diff --git a/.buildkite/ftr_configs.yml b/.buildkite/ftr_configs.yml index c10bf18e5e9177..eb7daad21b0f05 100644 --- a/.buildkite/ftr_configs.yml +++ b/.buildkite/ftr_configs.yml @@ -117,6 +117,7 @@ enabled: - x-pack/test/alerting_api_integration/basic/config.ts - x-pack/test/alerting_api_integration/security_and_spaces/group1/config.ts - x-pack/test/alerting_api_integration/security_and_spaces/group2/config.ts + - x-pack/test/alerting_api_integration/security_and_spaces/group2/config_non_dedicated_task_runner.ts - x-pack/test/alerting_api_integration/spaces_only/config.ts - x-pack/test/api_integration_basic/config.ts - x-pack/test/api_integration/config_security_basic.ts diff --git a/.buildkite/pipeline-utils/test-failures/annotate.ts b/.buildkite/pipeline-utils/test-failures/annotate.ts index 8ac896c99434b3..8397fa670af668 100644 --- a/.buildkite/pipeline-utils/test-failures/annotate.ts +++ b/.buildkite/pipeline-utils/test-failures/annotate.ts @@ -150,7 +150,7 @@ export const annotateTestFailures = async () => { } exec( - `buildkite-agent artifact download --include-retried-jobs "target/test_failures/*.json" "${failureDir}"` + `.buildkite/scripts/common/download_artifact.sh --include-retried-jobs "target/test_failures/*.json" "${failureDir}"` ); const failures: TestFailure[] = recursiveReadDir(failureDir) diff --git a/.buildkite/scripts/common/download_artifact.sh b/.buildkite/scripts/common/download_artifact.sh new file mode 100755 index 00000000000000..09f2d9e978a96a --- /dev/null +++ b/.buildkite/scripts/common/download_artifact.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash + +set -euo pipefail + +source "$(dirname "$0")/util.sh" +download_artifact "$@" diff --git a/.buildkite/scripts/common/util.sh b/.buildkite/scripts/common/util.sh index b25ba2c46213f1..1ce05856ec6b7b 100755 --- a/.buildkite/scripts/common/util.sh +++ b/.buildkite/scripts/common/util.sh @@ -168,3 +168,9 @@ npm_install_global() { npm install -g "$toInstall" && touch "$successFlag" fi } + +# Download an artifact using the buildkite-agent, takes the same arguments as https://buildkite.com/docs/agent/v3/cli-artifact#downloading-artifacts-usage +# times-out after 60 seconds and retries up to 3 times +download_artifact() { + retry 3 1 timeout 3m buildkite-agent artifact download "$@" +} diff --git a/.buildkite/scripts/download_build_artifacts.sh b/.buildkite/scripts/download_build_artifacts.sh index 1e7525fff25ea8..dd0ae660543a84 100755 --- a/.buildkite/scripts/download_build_artifacts.sh +++ b/.buildkite/scripts/download_build_artifacts.sh @@ -2,13 +2,15 @@ set -euo pipefail +source "$(dirname "$0")/common/util.sh" + if [[ ! -d "$KIBANA_BUILD_LOCATION/bin" ]]; then echo '--- Downloading Distribution and Plugin artifacts' cd "$WORKSPACE" - buildkite-agent artifact download kibana-default.tar.gz . --build "${KIBANA_BUILD_ID:-$BUILDKITE_BUILD_ID}" - buildkite-agent artifact download kibana-default-plugins.tar.gz . --build "${KIBANA_BUILD_ID:-$BUILDKITE_BUILD_ID}" + download_artifact kibana-default.tar.gz . --build "${KIBANA_BUILD_ID:-$BUILDKITE_BUILD_ID}" + download_artifact kibana-default-plugins.tar.gz . --build "${KIBANA_BUILD_ID:-$BUILDKITE_BUILD_ID}" mkdir -p "$KIBANA_BUILD_LOCATION" tar -xzf kibana-default.tar.gz -C "$KIBANA_BUILD_LOCATION" --strip=1 diff --git a/.buildkite/scripts/steps/artifacts/cloud.sh b/.buildkite/scripts/steps/artifacts/cloud.sh index d2d5785093f1ee..5bf2285ab162ad 100644 --- a/.buildkite/scripts/steps/artifacts/cloud.sh +++ b/.buildkite/scripts/steps/artifacts/cloud.sh @@ -4,12 +4,13 @@ set -euo pipefail .buildkite/scripts/bootstrap.sh +source "$(dirname "$0")/../../common/util.sh" source .buildkite/scripts/steps/artifacts/env.sh echo "--- Build and publish Cloud image" mkdir -p target -buildkite-agent artifact download "kibana-$FULL_VERSION-linux-x86_64.tar.gz" ./target --build "${KIBANA_BUILD_ID:-$BUILDKITE_BUILD_ID}" +download_artifact "kibana-$FULL_VERSION-linux-x86_64.tar.gz" ./target --build "${KIBANA_BUILD_ID:-$BUILDKITE_BUILD_ID}" node scripts/build \ --skip-initialize \ diff --git a/.buildkite/scripts/steps/artifacts/docker_context.sh b/.buildkite/scripts/steps/artifacts/docker_context.sh index 86c4361173a080..c50fb3e0524fd9 100755 --- a/.buildkite/scripts/steps/artifacts/docker_context.sh +++ b/.buildkite/scripts/steps/artifacts/docker_context.sh @@ -4,6 +4,7 @@ set -euo pipefail .buildkite/scripts/bootstrap.sh +source "$(dirname "$0")/../../common/util.sh" source .buildkite/scripts/steps/artifacts/env.sh KIBANA_DOCKER_CONTEXT="${KIBANA_DOCKER_CONTEXT:="default"}" @@ -28,7 +29,7 @@ fi tar -xf "target/$DOCKER_CONTEXT_FILE" -C "$DOCKER_BUILD_FOLDER" cd $DOCKER_BUILD_FOLDER -buildkite-agent artifact download "kibana-$FULL_VERSION-linux-x86_64.tar.gz" . --build "${KIBANA_BUILD_ID:-$BUILDKITE_BUILD_ID}" +download_artifact "kibana-$FULL_VERSION-linux-x86_64.tar.gz" . --build "${KIBANA_BUILD_ID:-$BUILDKITE_BUILD_ID}" echo "--- Build context" docker build . diff --git a/.buildkite/scripts/steps/artifacts/publish.sh b/.buildkite/scripts/steps/artifacts/publish.sh index ed4cb5ca1d4b99..1caee4a0eb025e 100644 --- a/.buildkite/scripts/steps/artifacts/publish.sh +++ b/.buildkite/scripts/steps/artifacts/publish.sh @@ -7,8 +7,8 @@ source .buildkite/scripts/steps/artifacts/env.sh echo "--- Download and verify artifacts" function download { - buildkite-agent artifact download "$1" . --build "${KIBANA_BUILD_ID:-$BUILDKITE_BUILD_ID}" - buildkite-agent artifact download "$1.sha512.txt" . --build "${KIBANA_BUILD_ID:-$BUILDKITE_BUILD_ID}" + download_artifact "$1" . --build "${KIBANA_BUILD_ID:-$BUILDKITE_BUILD_ID}" + download_artifact "$1.sha512.txt" . --build "${KIBANA_BUILD_ID:-$BUILDKITE_BUILD_ID}" sha512sum -c "$1.sha512.txt" rm "$1.sha512.txt" } @@ -40,7 +40,7 @@ download "kibana-$FULL_VERSION-windows-x86_64.zip" download "dependencies-$FULL_VERSION.csv" -cd - +cd - echo "--- Set artifact permissions" chmod -R a+r target/* diff --git a/.buildkite/scripts/steps/cloud/build_and_deploy.sh b/.buildkite/scripts/steps/cloud/build_and_deploy.sh index 05427de0582251..6488eca2c9cd83 100755 --- a/.buildkite/scripts/steps/cloud/build_and_deploy.sh +++ b/.buildkite/scripts/steps/cloud/build_and_deploy.sh @@ -14,7 +14,7 @@ ECCTL_LOGS=$(mktemp --suffix ".json") echo "--- Download Kibana Distribution" mkdir -p ./target -buildkite-agent artifact download "kibana-$VERSION-linux-x86_64.tar.gz" ./target --build "${KIBANA_BUILD_ID:-$BUILDKITE_BUILD_ID}" +download_artifact "kibana-$VERSION-linux-x86_64.tar.gz" ./target --build "${KIBANA_BUILD_ID:-$BUILDKITE_BUILD_ID}" echo "--- Build Cloud Distribution" ELASTICSEARCH_MANIFEST_URL="https://storage.googleapis.com/kibana-ci-es-snapshots-daily/$(jq -r '.version' package.json)/manifest-latest-verified.json" diff --git a/.buildkite/scripts/steps/code_coverage/ftr_configs.sh b/.buildkite/scripts/steps/code_coverage/ftr_configs.sh index 1a5eafd2e901fa..8aa619651e71ea 100755 --- a/.buildkite/scripts/steps/code_coverage/ftr_configs.sh +++ b/.buildkite/scripts/steps/code_coverage/ftr_configs.sh @@ -28,7 +28,7 @@ configs="${FTR_CONFIG:-}" if [[ "$configs" == "" ]]; then echo "--- Downloading ftr test run order" - buildkite-agent artifact download ftr_run_order.json . + download_artifact ftr_run_order.json . configs=$(jq -r '.[env.FTR_CONFIG_GROUP_KEY].names[]' ftr_run_order.json) fi diff --git a/.buildkite/scripts/steps/code_coverage/ingest.sh b/.buildkite/scripts/steps/code_coverage/ingest.sh index 6632009346481d..31a24981ce2001 100755 --- a/.buildkite/scripts/steps/code_coverage/ingest.sh +++ b/.buildkite/scripts/steps/code_coverage/ingest.sh @@ -29,7 +29,7 @@ revolveBuildHashes() { } collectRan() { - buildkite-agent artifact download target/ran_files/* . + download_artifact target/ran_files/* . while read -r x; do ran=("${ran[@]}" "$(cat "$x")") @@ -51,7 +51,7 @@ fetchArtifacts() { local xs=("$@") for x in "${xs[@]}"; do - buildkite-agent artifact download "target/kibana-coverage/${x}/*" . + download_artifact "target/kibana-coverage/${x}/*" . done } diff --git a/.buildkite/scripts/steps/code_coverage/jest_parallel.sh b/.buildkite/scripts/steps/code_coverage/jest_parallel.sh index fd8ea61f2d220e..ec2095b88963cf 100755 --- a/.buildkite/scripts/steps/code_coverage/jest_parallel.sh +++ b/.buildkite/scripts/steps/code_coverage/jest_parallel.sh @@ -2,6 +2,7 @@ set -euo pipefail +source "$(dirname "$0")/../../common/util.sh" source .buildkite/scripts/steps/code_coverage/util.sh export JOB=$BUILDKITE_PARALLEL_JOB @@ -18,7 +19,7 @@ fi export TEST_TYPE echo "--- downloading jest test run order" -buildkite-agent artifact download jest_run_order.json . +download_artifact jest_run_order.json . configs=$(jq -r 'getpath([env.TEST_TYPE]) | .groups[env.JOB | tonumber].names | .[]' jest_run_order.json) echo "--- KIBANA_DIR: $KIBANA_DIR" diff --git a/.buildkite/scripts/steps/functional/scalability_dataset_extraction.sh b/.buildkite/scripts/steps/functional/scalability_dataset_extraction.sh index cb17393f5f4231..86d067174ba8b7 100755 --- a/.buildkite/scripts/steps/functional/scalability_dataset_extraction.sh +++ b/.buildkite/scripts/steps/functional/scalability_dataset_extraction.sh @@ -34,8 +34,8 @@ mkdir "${BUILD_ID}" tar -czf "${BUILD_ID}/scalability_traces.tar.gz" -C target scalability_traces buildkite-agent artifact upload "${BUILD_ID}/scalability_traces.tar.gz" # Upload Kibana build, plugins, commit sha and traces to the bucket -buildkite-agent artifact download kibana-default.tar.gz ./"${BUILD_ID}" -buildkite-agent artifact download kibana-default-plugins.tar.gz ./"${BUILD_ID}" +download_artifact kibana-default.tar.gz ./"${BUILD_ID}" +download_artifact kibana-default-plugins.tar.gz ./"${BUILD_ID}" echo "${BUILDKITE_COMMIT}" > "${BUILD_ID}/KIBANA_COMMIT_HASH" gsutil -m cp -r "${BUILD_ID}" "${GCS_BUCKET}" echo "--- Update reference to the latest CI build" diff --git a/.buildkite/scripts/steps/package_testing/test.sh b/.buildkite/scripts/steps/package_testing/test.sh index 5831f0d938b265..4a2b8a52525d60 100755 --- a/.buildkite/scripts/steps/package_testing/test.sh +++ b/.buildkite/scripts/steps/package_testing/test.sh @@ -2,6 +2,7 @@ set -euo pipefail +source "$(dirname "$0")/../../common/util.sh" .buildkite/scripts/bootstrap.sh echo "--- Package Testing for $TEST_PACKAGE" @@ -9,13 +10,13 @@ echo "--- Package Testing for $TEST_PACKAGE" mkdir -p target cd target if [[ "$TEST_PACKAGE" == "deb" ]]; then - buildkite-agent artifact download 'kibana-*-amd64.deb' . --build "${KIBANA_BUILD_ID:-$BUILDKITE_BUILD_ID}" + download_artifact 'kibana-*-amd64.deb' . --build "${KIBANA_BUILD_ID:-$BUILDKITE_BUILD_ID}" KIBANA_IP_ADDRESS="192.168.56.5" elif [[ "$TEST_PACKAGE" == "rpm" ]]; then - buildkite-agent artifact download 'kibana-*-x86_64.rpm' . --build "${KIBANA_BUILD_ID:-$BUILDKITE_BUILD_ID}" + download_artifact 'kibana-*-x86_64.rpm' . --build "${KIBANA_BUILD_ID:-$BUILDKITE_BUILD_ID}" KIBANA_IP_ADDRESS="192.168.56.6" elif [[ "$TEST_PACKAGE" == "docker" ]]; then - buildkite-agent artifact download "kibana-$KIBANA_PKG_VERSION*-docker-image.tar.gz" . --build "${KIBANA_BUILD_ID:-$BUILDKITE_BUILD_ID}" + download_artifact "kibana-$KIBANA_PKG_VERSION*-docker-image.tar.gz" . --build "${KIBANA_BUILD_ID:-$BUILDKITE_BUILD_ID}" KIBANA_IP_ADDRESS="192.168.56.7" fi cd .. diff --git a/.buildkite/scripts/steps/test/ftr_configs.sh b/.buildkite/scripts/steps/test/ftr_configs.sh index 52450b30f995ce..fca1f784692566 100755 --- a/.buildkite/scripts/steps/test/ftr_configs.sh +++ b/.buildkite/scripts/steps/test/ftr_configs.sh @@ -32,7 +32,7 @@ fi if [ "$configs" == "" ] && [ "$FTR_CONFIG_GROUP_KEY" != "" ]; then echo "--- downloading ftr test run order" - buildkite-agent artifact download ftr_run_order.json . + download_artifact ftr_run_order.json . configs=$(jq -r '.[env.FTR_CONFIG_GROUP_KEY].names[]' ftr_run_order.json) fi diff --git a/.buildkite/scripts/steps/test/jest_parallel.sh b/.buildkite/scripts/steps/test/jest_parallel.sh index 8ca025a3e65167..2c4474abe0b055 100755 --- a/.buildkite/scripts/steps/test/jest_parallel.sh +++ b/.buildkite/scripts/steps/test/jest_parallel.sh @@ -2,6 +2,7 @@ set -euo pipefail +source "$(dirname "$0")/../../common/util.sh" export JOB=${BUILDKITE_PARALLEL_JOB:-0} # a jest failure will result in the script returning an exit code of 10 @@ -20,7 +21,7 @@ fi export TEST_TYPE echo "--- downloading jest test run order" -buildkite-agent artifact download jest_run_order.json . +download_artifact jest_run_order.json . configs=$(jq -r 'getpath([env.TEST_TYPE]) | .groups[env.JOB | tonumber].names | .[]' jest_run_order.json) while read -r config; do diff --git a/.eslintrc.js b/.eslintrc.js index eb3488aa5caff8..caa408887c4992 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -72,7 +72,7 @@ const ELASTIC_LICENSE_HEADER = ` const SAFER_LODASH_SET_HEADER = ` /* * Elasticsearch B.V licenses this file to you under the MIT License. - * See \`packages/elastic-safer-lodash-set/LICENSE\` for more information. + * See \`packages/kbn-safer-lodash-set/LICENSE\` for more information. */ `; @@ -81,7 +81,7 @@ const SAFER_LODASH_SET_LODASH_HEADER = ` * This file is forked from the lodash project (https://lodash.com/), * and may include modifications made by Elasticsearch B.V. * Elasticsearch B.V. licenses this file to you under the MIT License. - * See \`packages/elastic-safer-lodash-set/LICENSE\` for more information. + * See \`packages/kbn-safer-lodash-set/LICENSE\` for more information. */ `; @@ -90,7 +90,7 @@ const SAFER_LODASH_SET_DEFINITELYTYPED_HEADER = ` * This file is forked from the DefinitelyTyped project (https://github.com/DefinitelyTyped/DefinitelyTyped), * and may include modifications made by Elasticsearch B.V. * Elasticsearch B.V. licenses this file to you under the MIT License. - * See \`packages/elastic-safer-lodash-set/LICENSE\` for more information. + * See \`packages/kbn-safer-lodash-set/LICENSE\` for more information. */ `; @@ -186,44 +186,44 @@ const RESTRICTED_IMPORTS = [ { name: 'lodash', importNames: ['set', 'setWith'], - message: 'Please use @elastic/safer-lodash-set instead', + message: 'Please use @kbn/safer-lodash-set instead', }, { name: 'lodash.set', - message: 'Please use @elastic/safer-lodash-set instead', + message: 'Please use @kbn/safer-lodash-set instead', }, { name: 'lodash.setwith', - message: 'Please use @elastic/safer-lodash-set instead', + message: 'Please use @kbn/safer-lodash-set instead', }, { name: 'lodash/set', - message: 'Please use @elastic/safer-lodash-set instead', + message: 'Please use @kbn/safer-lodash-set instead', }, { name: 'lodash/setWith', - message: 'Please use @elastic/safer-lodash-set instead', + message: 'Please use @kbn/safer-lodash-set instead', }, { name: 'lodash/fp', importNames: ['set', 'setWith', 'assoc', 'assocPath'], - message: 'Please use @elastic/safer-lodash-set instead', + message: 'Please use @kbn/safer-lodash-set instead', }, { name: 'lodash/fp/set', - message: 'Please use @elastic/safer-lodash-set instead', + message: 'Please use @kbn/safer-lodash-set instead', }, { name: 'lodash/fp/setWith', - message: 'Please use @elastic/safer-lodash-set instead', + message: 'Please use @kbn/safer-lodash-set instead', }, { name: 'lodash/fp/assoc', - message: 'Please use @elastic/safer-lodash-set instead', + message: 'Please use @kbn/safer-lodash-set instead', }, { name: 'lodash/fp/assocPath', - message: 'Please use @elastic/safer-lodash-set instead', + message: 'Please use @kbn/safer-lodash-set instead', }, { name: 'lodash', @@ -409,7 +409,7 @@ module.exports = { * safer-lodash-set package requires special license headers */ { - files: ['packages/elastic-safer-lodash-set/**/*.{js,mjs,ts,tsx}'], + files: ['packages/kbn-safer-lodash-set/**/*.{js,mjs,ts,tsx}'], rules: { '@kbn/eslint/require-license-header': [ 'error', @@ -438,7 +438,7 @@ module.exports = { }, { - files: ['packages/elastic-safer-lodash-set/test/*.{js,mjs,ts,tsx}'], + files: ['packages/kbn-safer-lodash-set/test/*.{js,mjs,ts,tsx}'], rules: { '@kbn/eslint/require-license-header': [ 'error', @@ -466,7 +466,7 @@ module.exports = { }, }, { - files: ['packages/elastic-safer-lodash-set/**/*.d.ts'], + files: ['packages/kbn-safer-lodash-set/**/*.d.ts'], rules: { '@kbn/eslint/require-license-header': [ 'error', @@ -734,7 +734,7 @@ module.exports = { * Harden specific rules */ { - files: ['test/harden/*.js', 'packages/elastic-safer-lodash-set/test/*.js'], + files: ['test/harden/*.js', 'packages/kbn-safer-lodash-set/test/*.js'], rules: { 'mocha/handle-done-callback': 'off', }, @@ -754,11 +754,11 @@ module.exports = { paths: [ { name: 'lodash.set', - message: 'Please use @elastic/safer-lodash-set instead', + message: 'Please use @kbn/safer-lodash-set instead', }, { name: 'lodash.setwith', - message: 'Please use @elastic/safer-lodash-set instead', + message: 'Please use @kbn/safer-lodash-set instead', }, { name: 'lodash.template', @@ -767,11 +767,11 @@ module.exports = { }, { name: 'lodash/set', - message: 'Please use @elastic/safer-lodash-set instead', + message: 'Please use @kbn/safer-lodash-set instead', }, { name: 'lodash/setWith', - message: 'Please use @elastic/safer-lodash-set instead', + message: 'Please use @kbn/safer-lodash-set instead', }, { name: 'lodash/template', @@ -786,12 +786,12 @@ module.exports = { { object: 'lodash', property: 'set', - message: 'Please use @elastic/safer-lodash-set instead', + message: 'Please use @kbn/safer-lodash-set instead', }, { object: '_', property: 'set', - message: 'Please use @elastic/safer-lodash-set instead', + message: 'Please use @kbn/safer-lodash-set instead', }, { object: 'lodash', @@ -808,32 +808,32 @@ module.exports = { { object: 'lodash', property: 'setWith', - message: 'Please use @elastic/safer-lodash-set instead', + message: 'Please use @kbn/safer-lodash-set instead', }, { object: '_', property: 'setWith', - message: 'Please use @elastic/safer-lodash-set instead', + message: 'Please use @kbn/safer-lodash-set instead', }, { object: 'lodash', property: 'assoc', - message: 'Please use @elastic/safer-lodash-set instead', + message: 'Please use @kbn/safer-lodash-set instead', }, { object: '_', property: 'assoc', - message: 'Please use @elastic/safer-lodash-set instead', + message: 'Please use @kbn/safer-lodash-set instead', }, { object: 'lodash', property: 'assocPath', - message: 'Please use @elastic/safer-lodash-set instead', + message: 'Please use @kbn/safer-lodash-set instead', }, { object: '_', property: 'assocPath', - message: 'Please use @elastic/safer-lodash-set instead', + message: 'Please use @kbn/safer-lodash-set instead', }, ], }, diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 09484706c05e0d..d4bf323f938a70 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -13,8 +13,10 @@ /src/plugins/saved_search/ @elastic/kibana-data-discovery /x-pack/plugins/discover_enhanced/ @elastic/kibana-data-discovery /test/functional/apps/discover/ @elastic/kibana-data-discovery +/test/api_integration/apis/unified_field_list/ @elastic/kibana-data-discovery /x-pack/plugins/graph/ @elastic/kibana-data-discovery /x-pack/test/functional/apps/graph @elastic/kibana-data-discovery +/src/plugins/unified_field_list/ @elastic/kibana-data-discovery # Vis Editors /x-pack/plugins/lens/ @elastic/kibana-vis-editors @@ -41,7 +43,10 @@ /src/plugins/url_forwarding/ @elastic/kibana-vis-editors /packages/kbn-tinymath/ @elastic/kibana-vis-editors /x-pack/test/functional/apps/lens @elastic/kibana-vis-editors +/x-pack/test/api_integration/apis/lens/ @elastic/kibana-vis-editors /test/functional/apps/visualize/ @elastic/kibana-vis-editors +/src/plugins/unified_field_list/ @elastic/kibana-vis-editors +/test/api_integration/apis/unified_field_list/ @elastic/kibana-vis-editors # Application Services /examples/bfetch_explorer/ @elastic/kibana-app-services @@ -87,6 +92,7 @@ /x-pack/test/search_sessions_integration/ @elastic/kibana-app-services /src/plugins/dashboard/public/application/embeddable/viewport/print_media @elastic/kibana-app-services x-pack/plugins/files @elastic/kibana-app-services +x-pack/examples/files_example @elastic/kibana-app-services ### Observability Plugins @@ -136,7 +142,7 @@ x-pack/plugins/files @elastic/kibana-app-services /src/apm.js @elastic/kibana-core @vigneshshanmugam /packages/kbn-apm-config-loader/ @elastic/kibana-core @vigneshshanmugam /src/core/types/elasticsearch @elastic/apm-ui -/packages/elastic-apm-synthtrace/ @elastic/apm-ui +/packages/kbn-apm-synthtrace/ @elastic/apm-ui /packages/kbn-shared-svg @elastic/apm-ui #CC# /src/plugins/apm_oss/ @elastic/apm-ui #CC# /x-pack/plugins/observability/ @elastic/apm-ui @@ -177,6 +183,7 @@ x-pack/plugins/files @elastic/kibana-app-services /src/plugins/controls/ @elastic/kibana-presentation /test/functional/apps/dashboard/ @elastic/kibana-presentation /test/functional/apps/dashboard_elements/ @elastic/kibana-presentation +/test/functional/services/dashboard/ @elastic/kibana-presentation /x-pack/plugins/canvas/ @elastic/kibana-presentation /x-pack/plugins/dashboard_enhanced/ @elastic/kibana-presentation /x-pack/test/functional/apps/canvas/ @elastic/kibana-presentation @@ -597,10 +604,10 @@ x-pack/plugins/security_solution/cypress/README.md @elastic/security-engineering x-pack/test/security_solution_cypress @elastic/security-engineering-productivity ## Security Solution sub teams - adaptive-workload-protection -x-pack/plugins/kubernetes_security @elastic/awp-platform -x-pack/plugins/session_view @elastic/awp-platform -x-pack/plugins/security_solution/public/common/components/sessions_viewer @elastic/awp-platform -x-pack/plugins/security_solution/public/kubernetes @elastic/awp-platform +x-pack/plugins/kubernetes_security @elastic/awp-viz +x-pack/plugins/session_view @elastic/awp-viz +x-pack/plugins/security_solution/public/common/components/sessions_viewer @elastic/awp-viz +x-pack/plugins/security_solution/public/kubernetes @elastic/awp-viz ## Security Solution sub teams - Protections Experience x-pack/plugins/threat_intelligence @elastic/protections-experience @@ -618,6 +625,7 @@ x-pack/test/threat_intelligence_cypress @elastic/protections-experience # Cloud Security Posture /x-pack/plugins/cloud_security_posture/ @elastic/kibana-cloud-security-posture /x-pack/plugins/security_solution/public/cloud_security_posture @elastic/kibana-cloud-security-posture +/x-pack/test/api_integration/apis/cloud_security_posture/ @elastic/kibana-cloud-security-posture # Security Solution onboarding tour /x-pack/plugins/security_solution/public/common/components/guided_onboarding @elastic/platform-onboarding @@ -669,7 +677,6 @@ x-pack/test/threat_intelligence_cypress @elastic/protections-experience # Application Experience ## Shared UX Team -/src/plugins/shared_ux/ @elastic/shared-ux /packages/shared-ux/ @elastic/shared-ux /packages/shared-ux-*/ @elastic/shared-ux diff --git a/.i18nrc.json b/.i18nrc.json index cee83a60c1fd2c..2a301de5e7edfe 100644 --- a/.i18nrc.json +++ b/.i18nrc.json @@ -67,8 +67,6 @@ "savedObjectsManagement": "src/plugins/saved_objects_management", "server": "src/legacy/server", "share": "src/plugins/share", - "sharedUX": "src/plugins/shared_ux", - "sharedUXComponents": "packages/kbn-shared-ux-components/src", "sharedUXPackages": "packages/shared-ux", "coloring": "packages/kbn-coloring/src", "statusPage": "src/legacy/core_plugins/status_page", @@ -93,7 +91,8 @@ "visTypeVislib": "src/plugins/vis_types/vislib", "visTypeXy": "src/plugins/vis_types/xy", "visualizations": "src/plugins/visualizations", - "unifiedSearch": "src/plugins/unified_search" + "unifiedSearch": "src/plugins/unified_search", + "unifiedFieldList": "src/plugins/unified_field_list" }, "translations": [] } diff --git a/api_docs/actions.devdocs.json b/api_docs/actions.devdocs.json index cd26846b4f4992..615835f7b85a4e 100644 --- a/api_docs/actions.devdocs.json +++ b/api_docs/actions.devdocs.json @@ -1594,7 +1594,7 @@ "label": "ActionParamsType", "description": [], "signature": [ - "{ readonly to: string[]; readonly message: string; readonly subject: string; readonly cc: string[]; readonly bcc: string[]; readonly kibanaFooterLink: Readonly<{} & { path: string; text: string; }>; }" + "{ readonly message: string; readonly to: string[]; readonly subject: string; readonly cc: string[]; readonly bcc: string[]; readonly kibanaFooterLink: Readonly<{} & { path: string; text: string; }>; }" ], "path": "x-pack/plugins/actions/server/builtin_action_types/email.ts", "deprecated": false, @@ -1622,7 +1622,7 @@ "label": "ActionParamsType", "description": [], "signature": [ - "{ readonly group?: string | undefined; readonly source?: string | undefined; readonly summary?: string | undefined; readonly component?: string | undefined; readonly timestamp?: string | undefined; readonly eventAction?: \"resolve\" | \"trigger\" | \"acknowledge\" | undefined; readonly dedupKey?: string | undefined; readonly severity?: \"error\" | \"warning\" | \"info\" | \"critical\" | undefined; readonly class?: string | undefined; }" + "{ readonly source?: string | undefined; readonly summary?: string | undefined; readonly group?: string | undefined; readonly component?: string | undefined; readonly timestamp?: string | undefined; readonly eventAction?: \"resolve\" | \"trigger\" | \"acknowledge\" | undefined; readonly dedupKey?: string | undefined; readonly severity?: \"error\" | \"warning\" | \"info\" | \"critical\" | undefined; readonly class?: string | undefined; }" ], "path": "x-pack/plugins/actions/server/builtin_action_types/pagerduty.ts", "deprecated": false, @@ -1706,7 +1706,7 @@ "label": "ActionParamsType", "description": [], "signature": [ - "Readonly<{} & { subAction: \"getFields\"; subActionParams: Readonly<{} & {}>; }> | Readonly<{} & { subAction: \"getIncident\"; subActionParams: Readonly<{} & { externalId: string; }>; }> | Readonly<{} & { subAction: \"handshake\"; subActionParams: Readonly<{} & {}>; }> | Readonly<{} & { subAction: \"pushToService\"; subActionParams: Readonly<{} & { incident: Readonly<{} & { name: string; description: string | null; externalId: string | null; incidentTypes: number[] | null; severityCode: number | null; }>; comments: Readonly<{} & { comment: string; commentId: string; }>[] | null; }>; }> | Readonly<{} & { subAction: \"incidentTypes\"; subActionParams: Readonly<{} & {}>; }> | Readonly<{} & { subAction: \"severity\"; subActionParams: Readonly<{} & {}>; }>" + "Readonly<{} & { subAction: \"getFields\"; subActionParams: Readonly<{} & {}>; }> | Readonly<{} & { subAction: \"getIncident\"; subActionParams: Readonly<{} & { externalId: string; }>; }> | Readonly<{} & { subAction: \"handshake\"; subActionParams: Readonly<{} & {}>; }> | Readonly<{} & { subAction: \"pushToService\"; subActionParams: Readonly<{} & { incident: Readonly<{} & { description: string | null; name: string; externalId: string | null; incidentTypes: number[] | null; severityCode: number | null; }>; comments: Readonly<{} & { comment: string; commentId: string; }>[] | null; }>; }> | Readonly<{} & { subAction: \"incidentTypes\"; subActionParams: Readonly<{} & {}>; }> | Readonly<{} & { subAction: \"severity\"; subActionParams: Readonly<{} & {}>; }>" ], "path": "x-pack/plugins/actions/server/builtin_action_types/resilient/index.ts", "deprecated": false, @@ -1758,17 +1758,7 @@ }, "<", "ActionTypeConfig", - ">>; delete: ({ id }: { id: string; }) => Promise<{}>; execute: ({ actionId, params, source, relatedSavedObjects, }: Omit<", - "ExecuteOptions", - ", \"request\">) => Promise<", - { - "pluginId": "actions", - "scope": "common", - "docId": "kibActionsPluginApi", - "section": "def-common.ActionTypeExecutorResult", - "text": "ActionTypeExecutorResult" - }, - ">; create: ({ action: { actionTypeId, name, config, secrets }, }: ", + ">>; delete: ({ id }: { id: string; }) => Promise<{}>; create: ({ action: { actionTypeId, name, config, secrets }, }: ", "CreateOptions", ") => Promise<", { @@ -1792,7 +1782,17 @@ }, "<", "ActionTypeConfig", - ">>; getAll: () => Promise<", + ">>; execute: ({ actionId, params, source, relatedSavedObjects, }: Omit<", + "ExecuteOptions", + ", \"request\">) => Promise<", + { + "pluginId": "actions", + "scope": "common", + "docId": "kibActionsPluginApi", + "section": "def-common.ActionTypeExecutorResult", + "text": "ActionTypeExecutorResult" + }, + ">; getAll: () => Promise<", { "pluginId": "actions", "scope": "server", diff --git a/api_docs/actions.mdx b/api_docs/actions.mdx index cea9920a1bda66..cba32fb9a1f956 100644 --- a/api_docs/actions.mdx +++ b/api_docs/actions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/actions title: "actions" image: https://source.unsplash.com/400x175/?github description: API docs for the actions plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'actions'] --- import actionsObj from './actions.devdocs.json'; diff --git a/api_docs/advanced_settings.mdx b/api_docs/advanced_settings.mdx index a17c6767ecf6a2..f90263b170f0ae 100644 --- a/api_docs/advanced_settings.mdx +++ b/api_docs/advanced_settings.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/advancedSettings title: "advancedSettings" image: https://source.unsplash.com/400x175/?github description: API docs for the advancedSettings plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'advancedSettings'] --- import advancedSettingsObj from './advanced_settings.devdocs.json'; diff --git a/api_docs/aiops.mdx b/api_docs/aiops.mdx index 7c272b064bef99..8a8262169aec61 100644 --- a/api_docs/aiops.mdx +++ b/api_docs/aiops.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/aiops title: "aiops" image: https://source.unsplash.com/400x175/?github description: API docs for the aiops plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'aiops'] --- import aiopsObj from './aiops.devdocs.json'; diff --git a/api_docs/alerting.devdocs.json b/api_docs/alerting.devdocs.json index 87de0e14043124..a71cca2e3d278c 100644 --- a/api_docs/alerting.devdocs.json +++ b/api_docs/alerting.devdocs.json @@ -43,7 +43,7 @@ "The rule to view" ], "signature": [ - "{ params: never; tags: string[]; id: string; name: string; monitoring?: ", + "{ params: never; tags: string[]; id: string; monitoring?: ", { "pluginId": "alerting", "scope": "common", @@ -51,7 +51,7 @@ "section": "def-common.RuleMonitoring", "text": "RuleMonitoring" }, - " | undefined; enabled: boolean; actions: ", + " | undefined; name: string; enabled: boolean; actions: ", { "pluginId": "alerting", "scope": "common", @@ -5817,7 +5817,7 @@ "label": "SanitizedRule", "description": [], "signature": [ - "{ params: Params; tags: string[]; id: string; name: string; monitoring?: ", + "{ params: Params; tags: string[]; id: string; monitoring?: ", { "pluginId": "alerting", "scope": "common", @@ -5825,7 +5825,7 @@ "section": "def-common.RuleMonitoring", "text": "RuleMonitoring" }, - " | undefined; enabled: boolean; actions: ", + " | undefined; name: string; enabled: boolean; actions: ", { "pluginId": "alerting", "scope": "common", diff --git a/api_docs/alerting.mdx b/api_docs/alerting.mdx index 86cba3e94c5eed..f040d14a1bf84a 100644 --- a/api_docs/alerting.mdx +++ b/api_docs/alerting.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/alerting title: "alerting" image: https://source.unsplash.com/400x175/?github description: API docs for the alerting plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'alerting'] --- import alertingObj from './alerting.devdocs.json'; diff --git a/api_docs/apm.mdx b/api_docs/apm.mdx index d2018bd0165acb..82e4a751cf705b 100644 --- a/api_docs/apm.mdx +++ b/api_docs/apm.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/apm title: "apm" image: https://source.unsplash.com/400x175/?github description: API docs for the apm plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'apm'] --- import apmObj from './apm.devdocs.json'; diff --git a/api_docs/banners.mdx b/api_docs/banners.mdx index 84b1bad15fe1b0..7e70fbb1b439a4 100644 --- a/api_docs/banners.mdx +++ b/api_docs/banners.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/banners title: "banners" image: https://source.unsplash.com/400x175/?github description: API docs for the banners plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'banners'] --- import bannersObj from './banners.devdocs.json'; diff --git a/api_docs/bfetch.mdx b/api_docs/bfetch.mdx index abd6c1c3fdd9fc..6b902bbc818622 100644 --- a/api_docs/bfetch.mdx +++ b/api_docs/bfetch.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/bfetch title: "bfetch" image: https://source.unsplash.com/400x175/?github description: API docs for the bfetch plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'bfetch'] --- import bfetchObj from './bfetch.devdocs.json'; diff --git a/api_docs/canvas.mdx b/api_docs/canvas.mdx index e38e19c9ba9a23..e2240e3ecce050 100644 --- a/api_docs/canvas.mdx +++ b/api_docs/canvas.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/canvas title: "canvas" image: https://source.unsplash.com/400x175/?github description: API docs for the canvas plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'canvas'] --- import canvasObj from './canvas.devdocs.json'; diff --git a/api_docs/cases.mdx b/api_docs/cases.mdx index 4d1b413add3c62..e5e90629bc57e5 100644 --- a/api_docs/cases.mdx +++ b/api_docs/cases.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cases title: "cases" image: https://source.unsplash.com/400x175/?github description: API docs for the cases plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cases'] --- import casesObj from './cases.devdocs.json'; diff --git a/api_docs/charts.devdocs.json b/api_docs/charts.devdocs.json index 96a9ad926a858a..6658d572dadd58 100644 --- a/api_docs/charts.devdocs.json +++ b/api_docs/charts.devdocs.json @@ -280,279 +280,6 @@ "returnComment": [], "initialIsOpen": false }, - { - "parentPluginId": "charts", - "id": "def-public.getBrushFromChartBrushEventFn", - "type": "Function", - "tags": [], - "label": "getBrushFromChartBrushEventFn", - "description": [ - "\nHelper function to transform `@elastic/charts` brush event into brush action event" - ], - "signature": [ - "(table: ", - { - "pluginId": "expressions", - "scope": "common", - "docId": "kibExpressionsPluginApi", - "section": "def-common.Datatable", - "text": "Datatable" - }, - ", xAccessor: ", - "Accessor", - " | ", - "AccessorFn", - ") => ({ x: selectedRange }: ", - "XYBrushEvent", - ") => ", - { - "pluginId": "charts", - "scope": "public", - "docId": "kibChartsPluginApi", - "section": "def-public.BrushTriggerEvent", - "text": "BrushTriggerEvent" - } - ], - "path": "src/plugins/charts/public/static/utils/transform_click_event.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "charts", - "id": "def-public.getBrushFromChartBrushEventFn.$1", - "type": "Object", - "tags": [], - "label": "table", - "description": [], - "signature": [ - { - "pluginId": "expressions", - "scope": "common", - "docId": "kibExpressionsPluginApi", - "section": "def-common.Datatable", - "text": "Datatable" - } - ], - "path": "src/plugins/charts/public/static/utils/transform_click_event.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "charts", - "id": "def-public.getBrushFromChartBrushEventFn.$2", - "type": "CompoundType", - "tags": [], - "label": "xAccessor", - "description": [], - "signature": [ - "Accessor", - " | ", - "AccessorFn", - "" - ], - "path": "src/plugins/charts/public/static/utils/transform_click_event.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [], - "initialIsOpen": false - }, - { - "parentPluginId": "charts", - "id": "def-public.getFilterFromChartClickEventFn", - "type": "Function", - "tags": [], - "label": "getFilterFromChartClickEventFn", - "description": [ - "\nHelper function to transform `@elastic/charts` click event into filter action event\n" - ], - "signature": [ - "(table: ", - { - "pluginId": "expressions", - "scope": "common", - "docId": "kibExpressionsPluginApi", - "section": "def-common.Datatable", - "text": "Datatable" - }, - ", xAccessor: ", - "Accessor", - " | ", - "AccessorFn", - ", splitSeriesAccessorFnMap?: Map> | undefined, splitChartAccessor?: ", - "Accessor", - " | ", - "AccessorFn", - " | undefined, negate?: boolean) => (points: [", - "GeometryValue", - ", ", - "XYChartSeriesIdentifier", - "][]) => ", - { - "pluginId": "charts", - "scope": "public", - "docId": "kibChartsPluginApi", - "section": "def-public.ClickTriggerEvent", - "text": "ClickTriggerEvent" - } - ], - "path": "src/plugins/charts/public/static/utils/transform_click_event.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "charts", - "id": "def-public.getFilterFromChartClickEventFn.$1", - "type": "Object", - "tags": [], - "label": "table", - "description": [], - "signature": [ - { - "pluginId": "expressions", - "scope": "common", - "docId": "kibExpressionsPluginApi", - "section": "def-common.Datatable", - "text": "Datatable" - } - ], - "path": "src/plugins/charts/public/static/utils/transform_click_event.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "charts", - "id": "def-public.getFilterFromChartClickEventFn.$2", - "type": "CompoundType", - "tags": [], - "label": "xAccessor", - "description": [], - "signature": [ - "Accessor", - " | ", - "AccessorFn", - "" - ], - "path": "src/plugins/charts/public/static/utils/transform_click_event.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "charts", - "id": "def-public.getFilterFromChartClickEventFn.$3", - "type": "Object", - "tags": [], - "label": "splitSeriesAccessorFnMap", - "description": [ - "needed when using `splitSeriesAccessors` as `AccessorFn`" - ], - "signature": [ - "Map> | undefined" - ], - "path": "src/plugins/charts/public/static/utils/transform_click_event.ts", - "deprecated": false, - "isRequired": false - }, - { - "parentPluginId": "charts", - "id": "def-public.getFilterFromChartClickEventFn.$4", - "type": "CompoundType", - "tags": [], - "label": "splitChartAccessor", - "description": [], - "signature": [ - "Accessor", - " | ", - "AccessorFn", - " | undefined" - ], - "path": "src/plugins/charts/public/static/utils/transform_click_event.ts", - "deprecated": false, - "isRequired": false - }, - { - "parentPluginId": "charts", - "id": "def-public.getFilterFromChartClickEventFn.$5", - "type": "boolean", - "tags": [], - "label": "negate", - "description": [], - "signature": [ - "boolean" - ], - "path": "src/plugins/charts/public/static/utils/transform_click_event.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [], - "initialIsOpen": false - }, - { - "parentPluginId": "charts", - "id": "def-public.getFilterFromSeriesFn", - "type": "Function", - "tags": [], - "label": "getFilterFromSeriesFn", - "description": [ - "\nHelper function to get filter action event from series" - ], - "signature": [ - "(table: ", - { - "pluginId": "expressions", - "scope": "common", - "docId": "kibExpressionsPluginApi", - "section": "def-common.Datatable", - "text": "Datatable" - }, - ") => ({ splitAccessors, ...rest }: ", - "XYChartSeriesIdentifier", - ", splitSeriesAccessorFnMap?: Map> | undefined, splitChartAccessor?: ", - "Accessor", - " | ", - "AccessorFn", - " | undefined, negate?: boolean) => ", - { - "pluginId": "charts", - "scope": "public", - "docId": "kibChartsPluginApi", - "section": "def-public.ClickTriggerEvent", - "text": "ClickTriggerEvent" - } - ], - "path": "src/plugins/charts/public/static/utils/transform_click_event.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "charts", - "id": "def-public.getFilterFromSeriesFn.$1", - "type": "Object", - "tags": [], - "label": "table", - "description": [], - "signature": [ - { - "pluginId": "expressions", - "scope": "common", - "docId": "kibExpressionsPluginApi", - "section": "def-common.Datatable", - "text": "Datatable" - } - ], - "path": "src/plugins/charts/public/static/utils/transform_click_event.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [], - "initialIsOpen": false - }, { "parentPluginId": "charts", "id": "def-public.getHeatmapColors", @@ -914,7 +641,7 @@ "tags": [], "label": "BrushTriggerEvent", "description": [], - "path": "src/plugins/charts/public/static/utils/transform_click_event.ts", + "path": "src/plugins/charts/public/index.ts", "deprecated": false, "children": [ { @@ -927,7 +654,7 @@ "signature": [ "\"brush\"" ], - "path": "src/plugins/charts/public/static/utils/transform_click_event.ts", + "path": "src/plugins/charts/public/index.ts", "deprecated": false }, { @@ -948,7 +675,7 @@ }, "; column: number; range: number[]; timeFieldName?: string | undefined; }" ], - "path": "src/plugins/charts/public/static/utils/transform_click_event.ts", + "path": "src/plugins/charts/public/index.ts", "deprecated": false } ], @@ -961,7 +688,7 @@ "tags": [], "label": "ClickTriggerEvent", "description": [], - "path": "src/plugins/charts/public/static/utils/transform_click_event.ts", + "path": "src/plugins/charts/public/index.ts", "deprecated": false, "children": [ { @@ -974,7 +701,7 @@ "signature": [ "\"filter\"" ], - "path": "src/plugins/charts/public/static/utils/transform_click_event.ts", + "path": "src/plugins/charts/public/index.ts", "deprecated": false }, { @@ -995,7 +722,7 @@ }, ", \"rows\" | \"columns\">; column: number; row: number; value: any; }[]; timeFieldName?: string | undefined; negate?: boolean | undefined; }" ], - "path": "src/plugins/charts/public/static/utils/transform_click_event.ts", + "path": "src/plugins/charts/public/index.ts", "deprecated": false } ], diff --git a/api_docs/charts.mdx b/api_docs/charts.mdx index a411f0a6642adf..dc8403d572cab5 100644 --- a/api_docs/charts.mdx +++ b/api_docs/charts.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/charts title: "charts" image: https://source.unsplash.com/400x175/?github description: API docs for the charts plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'charts'] --- import chartsObj from './charts.devdocs.json'; @@ -21,7 +21,7 @@ Contact [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 272 | 2 | 253 | 9 | +| 261 | 2 | 246 | 9 | ## Client diff --git a/api_docs/cloud.mdx b/api_docs/cloud.mdx index 5ed41f6940f9e3..8a2ddd22c483f8 100644 --- a/api_docs/cloud.mdx +++ b/api_docs/cloud.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloud title: "cloud" image: https://source.unsplash.com/400x175/?github description: API docs for the cloud plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloud'] --- import cloudObj from './cloud.devdocs.json'; diff --git a/api_docs/cloud_security_posture.mdx b/api_docs/cloud_security_posture.mdx index 216c1caed9a108..1f2f747e843c31 100644 --- a/api_docs/cloud_security_posture.mdx +++ b/api_docs/cloud_security_posture.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudSecurityPosture title: "cloudSecurityPosture" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudSecurityPosture plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudSecurityPosture'] --- import cloudSecurityPostureObj from './cloud_security_posture.devdocs.json'; diff --git a/api_docs/console.mdx b/api_docs/console.mdx index 1cb510e1d8603f..98b15cd0810069 100644 --- a/api_docs/console.mdx +++ b/api_docs/console.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/console title: "console" image: https://source.unsplash.com/400x175/?github description: API docs for the console plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'console'] --- import consoleObj from './console.devdocs.json'; diff --git a/api_docs/controls.devdocs.json b/api_docs/controls.devdocs.json index 6ebca7b46dd347..97e48e7ea99843 100644 --- a/api_docs/controls.devdocs.json +++ b/api_docs/controls.devdocs.json @@ -1906,7 +1906,7 @@ }, ">" ], - "path": "src/plugins/controls/public/control_types/range_slider/range_slider_embeddable.tsx", + "path": "src/plugins/controls/public/range_slider/embeddable/range_slider_embeddable.tsx", "deprecated": false, "children": [ { @@ -1919,7 +1919,7 @@ "signature": [ "\"rangeSliderControl\"" ], - "path": "src/plugins/controls/public/control_types/range_slider/range_slider_embeddable.tsx", + "path": "src/plugins/controls/public/range_slider/embeddable/range_slider_embeddable.tsx", "deprecated": false }, { @@ -1929,7 +1929,7 @@ "tags": [], "label": "deferEmbeddableLoad", "description": [], - "path": "src/plugins/controls/public/control_types/range_slider/range_slider_embeddable.tsx", + "path": "src/plugins/controls/public/range_slider/embeddable/range_slider_embeddable.tsx", "deprecated": false }, { @@ -1942,7 +1942,7 @@ "signature": [ "any" ], - "path": "src/plugins/controls/public/control_types/range_slider/range_slider_embeddable.tsx", + "path": "src/plugins/controls/public/range_slider/embeddable/range_slider_embeddable.tsx", "deprecated": false, "children": [ { @@ -1961,7 +1961,7 @@ "text": "ReduxEmbeddablePackage" } ], - "path": "src/plugins/controls/public/control_types/range_slider/range_slider_embeddable.tsx", + "path": "src/plugins/controls/public/range_slider/embeddable/range_slider_embeddable.tsx", "deprecated": false, "isRequired": true }, @@ -1981,7 +1981,7 @@ "text": "RangeSliderEmbeddableInput" } ], - "path": "src/plugins/controls/public/control_types/range_slider/range_slider_embeddable.tsx", + "path": "src/plugins/controls/public/range_slider/embeddable/range_slider_embeddable.tsx", "deprecated": false, "isRequired": true }, @@ -2001,7 +2001,7 @@ "text": "ControlOutput" } ], - "path": "src/plugins/controls/public/control_types/range_slider/range_slider_embeddable.tsx", + "path": "src/plugins/controls/public/range_slider/embeddable/range_slider_embeddable.tsx", "deprecated": false, "isRequired": true }, @@ -2038,7 +2038,7 @@ }, "> | undefined" ], - "path": "src/plugins/controls/public/control_types/range_slider/range_slider_embeddable.tsx", + "path": "src/plugins/controls/public/range_slider/embeddable/range_slider_embeddable.tsx", "deprecated": false, "isRequired": false } @@ -2055,7 +2055,7 @@ "signature": [ "() => void" ], - "path": "src/plugins/controls/public/control_types/range_slider/range_slider_embeddable.tsx", + "path": "src/plugins/controls/public/range_slider/embeddable/range_slider_embeddable.tsx", "deprecated": false, "children": [], "returnComment": [] @@ -2070,7 +2070,7 @@ "signature": [ "() => void" ], - "path": "src/plugins/controls/public/control_types/range_slider/range_slider_embeddable.tsx", + "path": "src/plugins/controls/public/range_slider/embeddable/range_slider_embeddable.tsx", "deprecated": false, "children": [], "returnComment": [] @@ -2085,7 +2085,7 @@ "signature": [ "(node: HTMLElement) => void" ], - "path": "src/plugins/controls/public/control_types/range_slider/range_slider_embeddable.tsx", + "path": "src/plugins/controls/public/range_slider/embeddable/range_slider_embeddable.tsx", "deprecated": false, "children": [ { @@ -2098,7 +2098,7 @@ "signature": [ "HTMLElement" ], - "path": "src/plugins/controls/public/control_types/range_slider/range_slider_embeddable.tsx", + "path": "src/plugins/controls/public/range_slider/embeddable/range_slider_embeddable.tsx", "deprecated": false, "isRequired": true } @@ -2191,7 +2191,7 @@ }, ">" ], - "path": "src/plugins/controls/public/control_types/range_slider/range_slider_embeddable_factory.tsx", + "path": "src/plugins/controls/public/range_slider/embeddable/range_slider_embeddable_factory.tsx", "deprecated": false, "children": [ { @@ -2201,9 +2201,54 @@ "tags": [], "label": "type", "description": [], - "path": "src/plugins/controls/public/control_types/range_slider/range_slider_embeddable_factory.tsx", + "path": "src/plugins/controls/public/range_slider/embeddable/range_slider_embeddable_factory.tsx", "deprecated": false }, + { + "parentPluginId": "controls", + "id": "def-public.RangeSliderEmbeddableFactory.getDisplayName", + "type": "Function", + "tags": [], + "label": "getDisplayName", + "description": [], + "signature": [ + "() => string" + ], + "path": "src/plugins/controls/public/range_slider/embeddable/range_slider_embeddable_factory.tsx", + "deprecated": false, + "children": [], + "returnComment": [] + }, + { + "parentPluginId": "controls", + "id": "def-public.RangeSliderEmbeddableFactory.getDescription", + "type": "Function", + "tags": [], + "label": "getDescription", + "description": [], + "signature": [ + "() => string" + ], + "path": "src/plugins/controls/public/range_slider/embeddable/range_slider_embeddable_factory.tsx", + "deprecated": false, + "children": [], + "returnComment": [] + }, + { + "parentPluginId": "controls", + "id": "def-public.RangeSliderEmbeddableFactory.getIconType", + "type": "Function", + "tags": [], + "label": "getIconType", + "description": [], + "signature": [ + "() => string" + ], + "path": "src/plugins/controls/public/range_slider/embeddable/range_slider_embeddable_factory.tsx", + "deprecated": false, + "children": [], + "returnComment": [] + }, { "parentPluginId": "controls", "id": "def-public.RangeSliderEmbeddableFactory.canCreateNew", @@ -2214,22 +2259,22 @@ "signature": [ "() => boolean" ], - "path": "src/plugins/controls/public/control_types/range_slider/range_slider_embeddable_factory.tsx", + "path": "src/plugins/controls/public/range_slider/embeddable/range_slider_embeddable_factory.tsx", "deprecated": false, "children": [], "returnComment": [] }, { "parentPluginId": "controls", - "id": "def-public.RangeSliderEmbeddableFactory.Unnamed", + "id": "def-public.RangeSliderEmbeddableFactory.isEditable", "type": "Function", "tags": [], - "label": "Constructor", + "label": "isEditable", "description": [], "signature": [ - "any" + "() => Promise" ], - "path": "src/plugins/controls/public/control_types/range_slider/range_slider_embeddable_factory.tsx", + "path": "src/plugins/controls/public/range_slider/embeddable/range_slider_embeddable_factory.tsx", "deprecated": false, "children": [], "returnComment": [] @@ -2284,7 +2329,7 @@ }, ">" ], - "path": "src/plugins/controls/public/control_types/range_slider/range_slider_embeddable_factory.tsx", + "path": "src/plugins/controls/public/range_slider/embeddable/range_slider_embeddable_factory.tsx", "deprecated": false, "children": [ { @@ -2303,7 +2348,7 @@ "text": "RangeSliderEmbeddableInput" } ], - "path": "src/plugins/controls/public/control_types/range_slider/range_slider_embeddable_factory.tsx", + "path": "src/plugins/controls/public/range_slider/embeddable/range_slider_embeddable_factory.tsx", "deprecated": false, "isRequired": true }, @@ -2340,7 +2385,7 @@ }, "> | undefined" ], - "path": "src/plugins/controls/public/control_types/range_slider/range_slider_embeddable_factory.tsx", + "path": "src/plugins/controls/public/range_slider/embeddable/range_slider_embeddable_factory.tsx", "deprecated": false, "isRequired": false } @@ -2397,7 +2442,7 @@ }, ">" ], - "path": "src/plugins/controls/public/control_types/range_slider/range_slider_embeddable_factory.tsx", + "path": "src/plugins/controls/public/range_slider/embeddable/range_slider_embeddable_factory.tsx", "deprecated": false, "children": [ { @@ -2418,7 +2463,7 @@ }, ">" ], - "path": "src/plugins/controls/public/control_types/range_slider/range_slider_embeddable_factory.tsx", + "path": "src/plugins/controls/public/range_slider/embeddable/range_slider_embeddable_factory.tsx", "deprecated": false, "isRequired": true }, @@ -2455,7 +2500,7 @@ }, "> | undefined" ], - "path": "src/plugins/controls/public/control_types/range_slider/range_slider_embeddable_factory.tsx", + "path": "src/plugins/controls/public/range_slider/embeddable/range_slider_embeddable_factory.tsx", "deprecated": false, "isRequired": false } @@ -2474,7 +2519,7 @@ "DataControlField", ") => void" ], - "path": "src/plugins/controls/public/control_types/range_slider/range_slider_embeddable_factory.tsx", + "path": "src/plugins/controls/public/range_slider/embeddable/range_slider_embeddable_factory.tsx", "deprecated": false, "children": [ { @@ -2487,73 +2532,13 @@ "signature": [ "DataControlField" ], - "path": "src/plugins/controls/public/control_types/range_slider/range_slider_embeddable_factory.tsx", + "path": "src/plugins/controls/public/range_slider/embeddable/range_slider_embeddable_factory.tsx", "deprecated": false, "isRequired": true } ], "returnComment": [] }, - { - "parentPluginId": "controls", - "id": "def-public.RangeSliderEmbeddableFactory.isEditable", - "type": "Function", - "tags": [], - "label": "isEditable", - "description": [], - "signature": [ - "() => Promise" - ], - "path": "src/plugins/controls/public/control_types/range_slider/range_slider_embeddable_factory.tsx", - "deprecated": false, - "children": [], - "returnComment": [] - }, - { - "parentPluginId": "controls", - "id": "def-public.RangeSliderEmbeddableFactory.getDisplayName", - "type": "Function", - "tags": [], - "label": "getDisplayName", - "description": [], - "signature": [ - "() => string" - ], - "path": "src/plugins/controls/public/control_types/range_slider/range_slider_embeddable_factory.tsx", - "deprecated": false, - "children": [], - "returnComment": [] - }, - { - "parentPluginId": "controls", - "id": "def-public.RangeSliderEmbeddableFactory.getIconType", - "type": "Function", - "tags": [], - "label": "getIconType", - "description": [], - "signature": [ - "() => string" - ], - "path": "src/plugins/controls/public/control_types/range_slider/range_slider_embeddable_factory.tsx", - "deprecated": false, - "children": [], - "returnComment": [] - }, - { - "parentPluginId": "controls", - "id": "def-public.RangeSliderEmbeddableFactory.getDescription", - "type": "Function", - "tags": [], - "label": "getDescription", - "description": [], - "signature": [ - "() => string" - ], - "path": "src/plugins/controls/public/control_types/range_slider/range_slider_embeddable_factory.tsx", - "deprecated": false, - "children": [], - "returnComment": [] - }, { "parentPluginId": "controls", "id": "def-public.RangeSliderEmbeddableFactory.inject", @@ -2581,7 +2566,7 @@ "text": "EmbeddableStateWithType" } ], - "path": "src/plugins/controls/public/control_types/range_slider/range_slider_embeddable_factory.tsx", + "path": "src/plugins/controls/public/range_slider/embeddable/range_slider_embeddable_factory.tsx", "deprecated": false, "returnComment": [], "children": [ @@ -2642,7 +2627,7 @@ "SavedObjectReference", "[]; }" ], - "path": "src/plugins/controls/public/control_types/range_slider/range_slider_embeddable_factory.tsx", + "path": "src/plugins/controls/public/range_slider/embeddable/range_slider_embeddable_factory.tsx", "deprecated": false, "returnComment": [], "children": [ @@ -3281,7 +3266,7 @@ " extends ", "DataControlInput" ], - "path": "src/plugins/controls/common/control_types/range_slider/types.ts", + "path": "src/plugins/controls/common/range_slider/types.ts", "deprecated": false, "children": [ { @@ -3294,7 +3279,7 @@ "signature": [ "[string, string]" ], - "path": "src/plugins/controls/common/control_types/range_slider/types.ts", + "path": "src/plugins/controls/common/range_slider/types.ts", "deprecated": false } ], @@ -3529,21 +3514,7 @@ "signature": [ "\"rangeSliderControl\"" ], - "path": "src/plugins/controls/common/control_types/range_slider/types.ts", - "deprecated": false, - "initialIsOpen": false - }, - { - "parentPluginId": "controls", - "id": "def-public.TIME_SLIDER_CONTROL", - "type": "string", - "tags": [], - "label": "TIME_SLIDER_CONTROL", - "description": [], - "signature": [ - "\"timeSlider\"" - ], - "path": "src/plugins/controls/common/control_types/time_slider/types.ts", + "path": "src/plugins/controls/common/range_slider/types.ts", "deprecated": false, "initialIsOpen": false } @@ -4263,7 +4234,7 @@ " extends ", "DataControlInput" ], - "path": "src/plugins/controls/common/control_types/range_slider/types.ts", + "path": "src/plugins/controls/common/range_slider/types.ts", "deprecated": false, "children": [ { @@ -4276,7 +4247,7 @@ "signature": [ "[string, string]" ], - "path": "src/plugins/controls/common/control_types/range_slider/types.ts", + "path": "src/plugins/controls/common/range_slider/types.ts", "deprecated": false } ], @@ -4395,7 +4366,7 @@ "signature": [ "\"rangeSliderControl\"" ], - "path": "src/plugins/controls/common/control_types/range_slider/types.ts", + "path": "src/plugins/controls/common/range_slider/types.ts", "deprecated": false, "initialIsOpen": false }, @@ -4458,20 +4429,6 @@ "path": "src/plugins/controls/common/control_group/types.ts", "deprecated": false, "initialIsOpen": false - }, - { - "parentPluginId": "controls", - "id": "def-common.TIME_SLIDER_CONTROL", - "type": "string", - "tags": [], - "label": "TIME_SLIDER_CONTROL", - "description": [], - "signature": [ - "\"timeSlider\"" - ], - "path": "src/plugins/controls/common/control_types/time_slider/types.ts", - "deprecated": false, - "initialIsOpen": false } ], "objects": [] diff --git a/api_docs/controls.mdx b/api_docs/controls.mdx index cb0fc4f1fdfcc1..77812e0ab75dd4 100644 --- a/api_docs/controls.mdx +++ b/api_docs/controls.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/controls title: "controls" image: https://source.unsplash.com/400x175/?github description: API docs for the controls plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'controls'] --- import controlsObj from './controls.devdocs.json'; @@ -21,7 +21,7 @@ Contact [Kibana Presentation](https://github.com/orgs/elastic/teams/kibana-prese | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 207 | 0 | 199 | 7 | +| 204 | 0 | 196 | 7 | ## Client diff --git a/api_docs/core.devdocs.json b/api_docs/core.devdocs.json index a6f22147e3c403..416752a227c673 100644 --- a/api_docs/core.devdocs.json +++ b/api_docs/core.devdocs.json @@ -5399,7 +5399,7 @@ "label": "size", "description": [], "signature": [ - "\"s\" | \"m\" | \"l\" | undefined" + "\"m\" | \"s\" | \"l\" | undefined" ], "path": "node_modules/@types/kbn__core-overlays-browser/index.d.ts", "deprecated": false @@ -9956,7 +9956,7 @@ "signature": [ "{ options?: string[] | number[] | undefined; type?: ", "UiSettingsType", - " | undefined; metric?: { type: string; name: string; } | undefined; name?: string | undefined; order?: number | undefined; value?: unknown; description?: string | undefined; category?: string[] | undefined; optionLabels?: Record | undefined; requiresPageReload?: boolean | undefined; readonly?: boolean | undefined; sensitive?: boolean | undefined; deprecation?: ", + " | undefined; metric?: { type: string; name: string; } | undefined; value?: unknown; description?: string | undefined; name?: string | undefined; order?: number | undefined; category?: string[] | undefined; optionLabels?: Record | undefined; requiresPageReload?: boolean | undefined; readonly?: boolean | undefined; sensitive?: boolean | undefined; deprecation?: ", "DeprecationSettings", " | undefined; }" ], @@ -10025,9 +10025,9 @@ "label": "SavedObjectsFindOptions", "description": [], "signature": [ - "{ type: string | string[]; filter?: any; search?: string | undefined; page?: number | undefined; aggs?: Record | undefined; fields?: string[] | undefined; perPage?: number | undefined; sortField?: string | undefined; searchFields?: string[] | undefined; hasReference?: ", + "> | undefined; fields?: string[] | undefined; page?: number | undefined; perPage?: number | undefined; sortField?: string | undefined; searchFields?: string[] | undefined; hasReference?: ", "SavedObjectsFindOptionsReference", " | ", "SavedObjectsFindOptionsReference", @@ -10123,7 +10123,7 @@ "signature": [ "Pick<", "Toast", - ", \"children\" | \"onError\" | \"color\" | \"className\" | \"lang\" | \"style\" | \"role\" | \"tabIndex\" | \"aria-activedescendant\" | \"aria-atomic\" | \"aria-autocomplete\" | \"aria-busy\" | \"aria-checked\" | \"aria-colcount\" | \"aria-colindex\" | \"aria-colspan\" | \"aria-controls\" | \"aria-current\" | \"aria-describedby\" | \"aria-details\" | \"aria-disabled\" | \"aria-dropeffect\" | \"aria-errormessage\" | \"aria-expanded\" | \"aria-flowto\" | \"aria-grabbed\" | \"aria-haspopup\" | \"aria-hidden\" | \"aria-invalid\" | \"aria-keyshortcuts\" | \"aria-label\" | \"aria-labelledby\" | \"aria-level\" | \"aria-live\" | \"aria-modal\" | \"aria-multiline\" | \"aria-multiselectable\" | \"aria-orientation\" | \"aria-owns\" | \"aria-placeholder\" | \"aria-posinset\" | \"aria-pressed\" | \"aria-readonly\" | \"aria-relevant\" | \"aria-required\" | \"aria-roledescription\" | \"aria-rowcount\" | \"aria-rowindex\" | \"aria-rowspan\" | \"aria-selected\" | \"aria-setsize\" | \"aria-sort\" | \"aria-valuemax\" | \"aria-valuemin\" | \"aria-valuenow\" | \"aria-valuetext\" | \"dangerouslySetInnerHTML\" | \"onCopy\" | \"onCopyCapture\" | \"onCut\" | \"onCutCapture\" | \"onPaste\" | \"onPasteCapture\" | \"onCompositionEnd\" | \"onCompositionEndCapture\" | \"onCompositionStart\" | \"onCompositionStartCapture\" | \"onCompositionUpdate\" | \"onCompositionUpdateCapture\" | \"onFocus\" | \"onFocusCapture\" | \"onBlur\" | \"onBlurCapture\" | \"onChange\" | \"onChangeCapture\" | \"onBeforeInput\" | \"onBeforeInputCapture\" | \"onInput\" | \"onInputCapture\" | \"onReset\" | \"onResetCapture\" | \"onSubmit\" | \"onSubmitCapture\" | \"onInvalid\" | \"onInvalidCapture\" | \"onLoad\" | \"onLoadCapture\" | \"onErrorCapture\" | \"onKeyDown\" | \"onKeyDownCapture\" | \"onKeyPress\" | \"onKeyPressCapture\" | \"onKeyUp\" | \"onKeyUpCapture\" | \"onAbort\" | \"onAbortCapture\" | \"onCanPlay\" | \"onCanPlayCapture\" | \"onCanPlayThrough\" | \"onCanPlayThroughCapture\" | \"onDurationChange\" | \"onDurationChangeCapture\" | \"onEmptied\" | \"onEmptiedCapture\" | \"onEncrypted\" | \"onEncryptedCapture\" | \"onEnded\" | \"onEndedCapture\" | \"onLoadedData\" | \"onLoadedDataCapture\" | \"onLoadedMetadata\" | \"onLoadedMetadataCapture\" | \"onLoadStart\" | \"onLoadStartCapture\" | \"onPause\" | \"onPauseCapture\" | \"onPlay\" | \"onPlayCapture\" | \"onPlaying\" | \"onPlayingCapture\" | \"onProgress\" | \"onProgressCapture\" | \"onRateChange\" | \"onRateChangeCapture\" | \"onSeeked\" | \"onSeekedCapture\" | \"onSeeking\" | \"onSeekingCapture\" | \"onStalled\" | \"onStalledCapture\" | \"onSuspend\" | \"onSuspendCapture\" | \"onTimeUpdate\" | \"onTimeUpdateCapture\" | \"onVolumeChange\" | \"onVolumeChangeCapture\" | \"onWaiting\" | \"onWaitingCapture\" | \"onAuxClick\" | \"onAuxClickCapture\" | \"onClick\" | \"onClickCapture\" | \"onContextMenu\" | \"onContextMenuCapture\" | \"onDoubleClick\" | \"onDoubleClickCapture\" | \"onDrag\" | \"onDragCapture\" | \"onDragEnd\" | \"onDragEndCapture\" | \"onDragEnter\" | \"onDragEnterCapture\" | \"onDragExit\" | \"onDragExitCapture\" | \"onDragLeave\" | \"onDragLeaveCapture\" | \"onDragOver\" | \"onDragOverCapture\" | \"onDragStart\" | \"onDragStartCapture\" | \"onDrop\" | \"onDropCapture\" | \"onMouseDown\" | \"onMouseDownCapture\" | \"onMouseEnter\" | \"onMouseLeave\" | \"onMouseMove\" | \"onMouseMoveCapture\" | \"onMouseOut\" | \"onMouseOutCapture\" | \"onMouseOver\" | \"onMouseOverCapture\" | \"onMouseUp\" | \"onMouseUpCapture\" | \"onSelect\" | \"onSelectCapture\" | \"onTouchCancel\" | \"onTouchCancelCapture\" | \"onTouchEnd\" | \"onTouchEndCapture\" | \"onTouchMove\" | \"onTouchMoveCapture\" | \"onTouchStart\" | \"onTouchStartCapture\" | \"onPointerDown\" | \"onPointerDownCapture\" | \"onPointerMove\" | \"onPointerMoveCapture\" | \"onPointerUp\" | \"onPointerUpCapture\" | \"onPointerCancel\" | \"onPointerCancelCapture\" | \"onPointerEnter\" | \"onPointerEnterCapture\" | \"onPointerLeave\" | \"onPointerLeaveCapture\" | \"onPointerOver\" | \"onPointerOverCapture\" | \"onPointerOut\" | \"onPointerOutCapture\" | \"onGotPointerCapture\" | \"onGotPointerCaptureCapture\" | \"onLostPointerCapture\" | \"onLostPointerCaptureCapture\" | \"onScroll\" | \"onScrollCapture\" | \"onWheel\" | \"onWheelCapture\" | \"onAnimationStart\" | \"onAnimationStartCapture\" | \"onAnimationEnd\" | \"onAnimationEndCapture\" | \"onAnimationIteration\" | \"onAnimationIterationCapture\" | \"onTransitionEnd\" | \"onTransitionEndCapture\" | \"data-test-subj\" | \"hidden\" | \"security\" | \"defaultValue\" | \"defaultChecked\" | \"suppressContentEditableWarning\" | \"suppressHydrationWarning\" | \"accessKey\" | \"contentEditable\" | \"contextMenu\" | \"dir\" | \"draggable\" | \"placeholder\" | \"slot\" | \"spellCheck\" | \"translate\" | \"radioGroup\" | \"about\" | \"datatype\" | \"inlist\" | \"prefix\" | \"property\" | \"resource\" | \"typeof\" | \"vocab\" | \"autoCapitalize\" | \"autoCorrect\" | \"autoSave\" | \"itemProp\" | \"itemScope\" | \"itemType\" | \"itemID\" | \"itemRef\" | \"results\" | \"unselectable\" | \"inputMode\" | \"is\" | \"toastLifeTimeMs\" | \"iconType\" | \"onClose\"> & { title?: string | ", + ", \"children\" | \"onError\" | \"hidden\" | \"color\" | \"className\" | \"onChange\" | \"onKeyDown\" | \"onClick\" | \"security\" | \"defaultValue\" | \"lang\" | \"defaultChecked\" | \"suppressContentEditableWarning\" | \"suppressHydrationWarning\" | \"accessKey\" | \"contentEditable\" | \"contextMenu\" | \"dir\" | \"draggable\" | \"placeholder\" | \"slot\" | \"spellCheck\" | \"style\" | \"tabIndex\" | \"translate\" | \"radioGroup\" | \"role\" | \"about\" | \"datatype\" | \"inlist\" | \"prefix\" | \"property\" | \"resource\" | \"typeof\" | \"vocab\" | \"autoCapitalize\" | \"autoCorrect\" | \"autoSave\" | \"itemProp\" | \"itemScope\" | \"itemType\" | \"itemID\" | \"itemRef\" | \"results\" | \"unselectable\" | \"inputMode\" | \"is\" | \"aria-activedescendant\" | \"aria-atomic\" | \"aria-autocomplete\" | \"aria-busy\" | \"aria-checked\" | \"aria-colcount\" | \"aria-colindex\" | \"aria-colspan\" | \"aria-controls\" | \"aria-current\" | \"aria-describedby\" | \"aria-details\" | \"aria-disabled\" | \"aria-dropeffect\" | \"aria-errormessage\" | \"aria-expanded\" | \"aria-flowto\" | \"aria-grabbed\" | \"aria-haspopup\" | \"aria-hidden\" | \"aria-invalid\" | \"aria-keyshortcuts\" | \"aria-label\" | \"aria-labelledby\" | \"aria-level\" | \"aria-live\" | \"aria-modal\" | \"aria-multiline\" | \"aria-multiselectable\" | \"aria-orientation\" | \"aria-owns\" | \"aria-placeholder\" | \"aria-posinset\" | \"aria-pressed\" | \"aria-readonly\" | \"aria-relevant\" | \"aria-required\" | \"aria-roledescription\" | \"aria-rowcount\" | \"aria-rowindex\" | \"aria-rowspan\" | \"aria-selected\" | \"aria-setsize\" | \"aria-sort\" | \"aria-valuemax\" | \"aria-valuemin\" | \"aria-valuenow\" | \"aria-valuetext\" | \"dangerouslySetInnerHTML\" | \"onCopy\" | \"onCopyCapture\" | \"onCut\" | \"onCutCapture\" | \"onPaste\" | \"onPasteCapture\" | \"onCompositionEnd\" | \"onCompositionEndCapture\" | \"onCompositionStart\" | \"onCompositionStartCapture\" | \"onCompositionUpdate\" | \"onCompositionUpdateCapture\" | \"onFocus\" | \"onFocusCapture\" | \"onBlur\" | \"onBlurCapture\" | \"onChangeCapture\" | \"onBeforeInput\" | \"onBeforeInputCapture\" | \"onInput\" | \"onInputCapture\" | \"onReset\" | \"onResetCapture\" | \"onSubmit\" | \"onSubmitCapture\" | \"onInvalid\" | \"onInvalidCapture\" | \"onLoad\" | \"onLoadCapture\" | \"onErrorCapture\" | \"onKeyDownCapture\" | \"onKeyPress\" | \"onKeyPressCapture\" | \"onKeyUp\" | \"onKeyUpCapture\" | \"onAbort\" | \"onAbortCapture\" | \"onCanPlay\" | \"onCanPlayCapture\" | \"onCanPlayThrough\" | \"onCanPlayThroughCapture\" | \"onDurationChange\" | \"onDurationChangeCapture\" | \"onEmptied\" | \"onEmptiedCapture\" | \"onEncrypted\" | \"onEncryptedCapture\" | \"onEnded\" | \"onEndedCapture\" | \"onLoadedData\" | \"onLoadedDataCapture\" | \"onLoadedMetadata\" | \"onLoadedMetadataCapture\" | \"onLoadStart\" | \"onLoadStartCapture\" | \"onPause\" | \"onPauseCapture\" | \"onPlay\" | \"onPlayCapture\" | \"onPlaying\" | \"onPlayingCapture\" | \"onProgress\" | \"onProgressCapture\" | \"onRateChange\" | \"onRateChangeCapture\" | \"onSeeked\" | \"onSeekedCapture\" | \"onSeeking\" | \"onSeekingCapture\" | \"onStalled\" | \"onStalledCapture\" | \"onSuspend\" | \"onSuspendCapture\" | \"onTimeUpdate\" | \"onTimeUpdateCapture\" | \"onVolumeChange\" | \"onVolumeChangeCapture\" | \"onWaiting\" | \"onWaitingCapture\" | \"onAuxClick\" | \"onAuxClickCapture\" | \"onClickCapture\" | \"onContextMenu\" | \"onContextMenuCapture\" | \"onDoubleClick\" | \"onDoubleClickCapture\" | \"onDrag\" | \"onDragCapture\" | \"onDragEnd\" | \"onDragEndCapture\" | \"onDragEnter\" | \"onDragEnterCapture\" | \"onDragExit\" | \"onDragExitCapture\" | \"onDragLeave\" | \"onDragLeaveCapture\" | \"onDragOver\" | \"onDragOverCapture\" | \"onDragStart\" | \"onDragStartCapture\" | \"onDrop\" | \"onDropCapture\" | \"onMouseDown\" | \"onMouseDownCapture\" | \"onMouseEnter\" | \"onMouseLeave\" | \"onMouseMove\" | \"onMouseMoveCapture\" | \"onMouseOut\" | \"onMouseOutCapture\" | \"onMouseOver\" | \"onMouseOverCapture\" | \"onMouseUp\" | \"onMouseUpCapture\" | \"onSelect\" | \"onSelectCapture\" | \"onTouchCancel\" | \"onTouchCancelCapture\" | \"onTouchEnd\" | \"onTouchEndCapture\" | \"onTouchMove\" | \"onTouchMoveCapture\" | \"onTouchStart\" | \"onTouchStartCapture\" | \"onPointerDown\" | \"onPointerDownCapture\" | \"onPointerMove\" | \"onPointerMoveCapture\" | \"onPointerUp\" | \"onPointerUpCapture\" | \"onPointerCancel\" | \"onPointerCancelCapture\" | \"onPointerEnter\" | \"onPointerEnterCapture\" | \"onPointerLeave\" | \"onPointerLeaveCapture\" | \"onPointerOver\" | \"onPointerOverCapture\" | \"onPointerOut\" | \"onPointerOutCapture\" | \"onGotPointerCapture\" | \"onGotPointerCaptureCapture\" | \"onLostPointerCapture\" | \"onLostPointerCaptureCapture\" | \"onScroll\" | \"onScrollCapture\" | \"onWheel\" | \"onWheelCapture\" | \"onAnimationStart\" | \"onAnimationStartCapture\" | \"onAnimationEnd\" | \"onAnimationEndCapture\" | \"onAnimationIteration\" | \"onAnimationIterationCapture\" | \"onTransitionEnd\" | \"onTransitionEndCapture\" | \"toastLifeTimeMs\" | \"iconType\" | \"onClose\" | \"data-test-subj\"> & { title?: string | ", "MountPoint", " | undefined; text?: string | ", "MountPoint", @@ -10162,7 +10162,7 @@ "signature": [ "Pick<", "Toast", - ", \"children\" | \"onError\" | \"color\" | \"className\" | \"lang\" | \"style\" | \"role\" | \"tabIndex\" | \"aria-activedescendant\" | \"aria-atomic\" | \"aria-autocomplete\" | \"aria-busy\" | \"aria-checked\" | \"aria-colcount\" | \"aria-colindex\" | \"aria-colspan\" | \"aria-controls\" | \"aria-current\" | \"aria-describedby\" | \"aria-details\" | \"aria-disabled\" | \"aria-dropeffect\" | \"aria-errormessage\" | \"aria-expanded\" | \"aria-flowto\" | \"aria-grabbed\" | \"aria-haspopup\" | \"aria-hidden\" | \"aria-invalid\" | \"aria-keyshortcuts\" | \"aria-label\" | \"aria-labelledby\" | \"aria-level\" | \"aria-live\" | \"aria-modal\" | \"aria-multiline\" | \"aria-multiselectable\" | \"aria-orientation\" | \"aria-owns\" | \"aria-placeholder\" | \"aria-posinset\" | \"aria-pressed\" | \"aria-readonly\" | \"aria-relevant\" | \"aria-required\" | \"aria-roledescription\" | \"aria-rowcount\" | \"aria-rowindex\" | \"aria-rowspan\" | \"aria-selected\" | \"aria-setsize\" | \"aria-sort\" | \"aria-valuemax\" | \"aria-valuemin\" | \"aria-valuenow\" | \"aria-valuetext\" | \"dangerouslySetInnerHTML\" | \"onCopy\" | \"onCopyCapture\" | \"onCut\" | \"onCutCapture\" | \"onPaste\" | \"onPasteCapture\" | \"onCompositionEnd\" | \"onCompositionEndCapture\" | \"onCompositionStart\" | \"onCompositionStartCapture\" | \"onCompositionUpdate\" | \"onCompositionUpdateCapture\" | \"onFocus\" | \"onFocusCapture\" | \"onBlur\" | \"onBlurCapture\" | \"onChange\" | \"onChangeCapture\" | \"onBeforeInput\" | \"onBeforeInputCapture\" | \"onInput\" | \"onInputCapture\" | \"onReset\" | \"onResetCapture\" | \"onSubmit\" | \"onSubmitCapture\" | \"onInvalid\" | \"onInvalidCapture\" | \"onLoad\" | \"onLoadCapture\" | \"onErrorCapture\" | \"onKeyDown\" | \"onKeyDownCapture\" | \"onKeyPress\" | \"onKeyPressCapture\" | \"onKeyUp\" | \"onKeyUpCapture\" | \"onAbort\" | \"onAbortCapture\" | \"onCanPlay\" | \"onCanPlayCapture\" | \"onCanPlayThrough\" | \"onCanPlayThroughCapture\" | \"onDurationChange\" | \"onDurationChangeCapture\" | \"onEmptied\" | \"onEmptiedCapture\" | \"onEncrypted\" | \"onEncryptedCapture\" | \"onEnded\" | \"onEndedCapture\" | \"onLoadedData\" | \"onLoadedDataCapture\" | \"onLoadedMetadata\" | \"onLoadedMetadataCapture\" | \"onLoadStart\" | \"onLoadStartCapture\" | \"onPause\" | \"onPauseCapture\" | \"onPlay\" | \"onPlayCapture\" | \"onPlaying\" | \"onPlayingCapture\" | \"onProgress\" | \"onProgressCapture\" | \"onRateChange\" | \"onRateChangeCapture\" | \"onSeeked\" | \"onSeekedCapture\" | \"onSeeking\" | \"onSeekingCapture\" | \"onStalled\" | \"onStalledCapture\" | \"onSuspend\" | \"onSuspendCapture\" | \"onTimeUpdate\" | \"onTimeUpdateCapture\" | \"onVolumeChange\" | \"onVolumeChangeCapture\" | \"onWaiting\" | \"onWaitingCapture\" | \"onAuxClick\" | \"onAuxClickCapture\" | \"onClick\" | \"onClickCapture\" | \"onContextMenu\" | \"onContextMenuCapture\" | \"onDoubleClick\" | \"onDoubleClickCapture\" | \"onDrag\" | \"onDragCapture\" | \"onDragEnd\" | \"onDragEndCapture\" | \"onDragEnter\" | \"onDragEnterCapture\" | \"onDragExit\" | \"onDragExitCapture\" | \"onDragLeave\" | \"onDragLeaveCapture\" | \"onDragOver\" | \"onDragOverCapture\" | \"onDragStart\" | \"onDragStartCapture\" | \"onDrop\" | \"onDropCapture\" | \"onMouseDown\" | \"onMouseDownCapture\" | \"onMouseEnter\" | \"onMouseLeave\" | \"onMouseMove\" | \"onMouseMoveCapture\" | \"onMouseOut\" | \"onMouseOutCapture\" | \"onMouseOver\" | \"onMouseOverCapture\" | \"onMouseUp\" | \"onMouseUpCapture\" | \"onSelect\" | \"onSelectCapture\" | \"onTouchCancel\" | \"onTouchCancelCapture\" | \"onTouchEnd\" | \"onTouchEndCapture\" | \"onTouchMove\" | \"onTouchMoveCapture\" | \"onTouchStart\" | \"onTouchStartCapture\" | \"onPointerDown\" | \"onPointerDownCapture\" | \"onPointerMove\" | \"onPointerMoveCapture\" | \"onPointerUp\" | \"onPointerUpCapture\" | \"onPointerCancel\" | \"onPointerCancelCapture\" | \"onPointerEnter\" | \"onPointerEnterCapture\" | \"onPointerLeave\" | \"onPointerLeaveCapture\" | \"onPointerOver\" | \"onPointerOverCapture\" | \"onPointerOut\" | \"onPointerOutCapture\" | \"onGotPointerCapture\" | \"onGotPointerCaptureCapture\" | \"onLostPointerCapture\" | \"onLostPointerCaptureCapture\" | \"onScroll\" | \"onScrollCapture\" | \"onWheel\" | \"onWheelCapture\" | \"onAnimationStart\" | \"onAnimationStartCapture\" | \"onAnimationEnd\" | \"onAnimationEndCapture\" | \"onAnimationIteration\" | \"onAnimationIterationCapture\" | \"onTransitionEnd\" | \"onTransitionEndCapture\" | \"data-test-subj\" | \"hidden\" | \"security\" | \"defaultValue\" | \"defaultChecked\" | \"suppressContentEditableWarning\" | \"suppressHydrationWarning\" | \"accessKey\" | \"contentEditable\" | \"contextMenu\" | \"dir\" | \"draggable\" | \"placeholder\" | \"slot\" | \"spellCheck\" | \"translate\" | \"radioGroup\" | \"about\" | \"datatype\" | \"inlist\" | \"prefix\" | \"property\" | \"resource\" | \"typeof\" | \"vocab\" | \"autoCapitalize\" | \"autoCorrect\" | \"autoSave\" | \"itemProp\" | \"itemScope\" | \"itemType\" | \"itemID\" | \"itemRef\" | \"results\" | \"unselectable\" | \"inputMode\" | \"is\" | \"toastLifeTimeMs\" | \"iconType\" | \"onClose\"> & { title?: string | ", + ", \"children\" | \"onError\" | \"hidden\" | \"color\" | \"className\" | \"onChange\" | \"onKeyDown\" | \"onClick\" | \"security\" | \"defaultValue\" | \"lang\" | \"defaultChecked\" | \"suppressContentEditableWarning\" | \"suppressHydrationWarning\" | \"accessKey\" | \"contentEditable\" | \"contextMenu\" | \"dir\" | \"draggable\" | \"placeholder\" | \"slot\" | \"spellCheck\" | \"style\" | \"tabIndex\" | \"translate\" | \"radioGroup\" | \"role\" | \"about\" | \"datatype\" | \"inlist\" | \"prefix\" | \"property\" | \"resource\" | \"typeof\" | \"vocab\" | \"autoCapitalize\" | \"autoCorrect\" | \"autoSave\" | \"itemProp\" | \"itemScope\" | \"itemType\" | \"itemID\" | \"itemRef\" | \"results\" | \"unselectable\" | \"inputMode\" | \"is\" | \"aria-activedescendant\" | \"aria-atomic\" | \"aria-autocomplete\" | \"aria-busy\" | \"aria-checked\" | \"aria-colcount\" | \"aria-colindex\" | \"aria-colspan\" | \"aria-controls\" | \"aria-current\" | \"aria-describedby\" | \"aria-details\" | \"aria-disabled\" | \"aria-dropeffect\" | \"aria-errormessage\" | \"aria-expanded\" | \"aria-flowto\" | \"aria-grabbed\" | \"aria-haspopup\" | \"aria-hidden\" | \"aria-invalid\" | \"aria-keyshortcuts\" | \"aria-label\" | \"aria-labelledby\" | \"aria-level\" | \"aria-live\" | \"aria-modal\" | \"aria-multiline\" | \"aria-multiselectable\" | \"aria-orientation\" | \"aria-owns\" | \"aria-placeholder\" | \"aria-posinset\" | \"aria-pressed\" | \"aria-readonly\" | \"aria-relevant\" | \"aria-required\" | \"aria-roledescription\" | \"aria-rowcount\" | \"aria-rowindex\" | \"aria-rowspan\" | \"aria-selected\" | \"aria-setsize\" | \"aria-sort\" | \"aria-valuemax\" | \"aria-valuemin\" | \"aria-valuenow\" | \"aria-valuetext\" | \"dangerouslySetInnerHTML\" | \"onCopy\" | \"onCopyCapture\" | \"onCut\" | \"onCutCapture\" | \"onPaste\" | \"onPasteCapture\" | \"onCompositionEnd\" | \"onCompositionEndCapture\" | \"onCompositionStart\" | \"onCompositionStartCapture\" | \"onCompositionUpdate\" | \"onCompositionUpdateCapture\" | \"onFocus\" | \"onFocusCapture\" | \"onBlur\" | \"onBlurCapture\" | \"onChangeCapture\" | \"onBeforeInput\" | \"onBeforeInputCapture\" | \"onInput\" | \"onInputCapture\" | \"onReset\" | \"onResetCapture\" | \"onSubmit\" | \"onSubmitCapture\" | \"onInvalid\" | \"onInvalidCapture\" | \"onLoad\" | \"onLoadCapture\" | \"onErrorCapture\" | \"onKeyDownCapture\" | \"onKeyPress\" | \"onKeyPressCapture\" | \"onKeyUp\" | \"onKeyUpCapture\" | \"onAbort\" | \"onAbortCapture\" | \"onCanPlay\" | \"onCanPlayCapture\" | \"onCanPlayThrough\" | \"onCanPlayThroughCapture\" | \"onDurationChange\" | \"onDurationChangeCapture\" | \"onEmptied\" | \"onEmptiedCapture\" | \"onEncrypted\" | \"onEncryptedCapture\" | \"onEnded\" | \"onEndedCapture\" | \"onLoadedData\" | \"onLoadedDataCapture\" | \"onLoadedMetadata\" | \"onLoadedMetadataCapture\" | \"onLoadStart\" | \"onLoadStartCapture\" | \"onPause\" | \"onPauseCapture\" | \"onPlay\" | \"onPlayCapture\" | \"onPlaying\" | \"onPlayingCapture\" | \"onProgress\" | \"onProgressCapture\" | \"onRateChange\" | \"onRateChangeCapture\" | \"onSeeked\" | \"onSeekedCapture\" | \"onSeeking\" | \"onSeekingCapture\" | \"onStalled\" | \"onStalledCapture\" | \"onSuspend\" | \"onSuspendCapture\" | \"onTimeUpdate\" | \"onTimeUpdateCapture\" | \"onVolumeChange\" | \"onVolumeChangeCapture\" | \"onWaiting\" | \"onWaitingCapture\" | \"onAuxClick\" | \"onAuxClickCapture\" | \"onClickCapture\" | \"onContextMenu\" | \"onContextMenuCapture\" | \"onDoubleClick\" | \"onDoubleClickCapture\" | \"onDrag\" | \"onDragCapture\" | \"onDragEnd\" | \"onDragEndCapture\" | \"onDragEnter\" | \"onDragEnterCapture\" | \"onDragExit\" | \"onDragExitCapture\" | \"onDragLeave\" | \"onDragLeaveCapture\" | \"onDragOver\" | \"onDragOverCapture\" | \"onDragStart\" | \"onDragStartCapture\" | \"onDrop\" | \"onDropCapture\" | \"onMouseDown\" | \"onMouseDownCapture\" | \"onMouseEnter\" | \"onMouseLeave\" | \"onMouseMove\" | \"onMouseMoveCapture\" | \"onMouseOut\" | \"onMouseOutCapture\" | \"onMouseOver\" | \"onMouseOverCapture\" | \"onMouseUp\" | \"onMouseUpCapture\" | \"onSelect\" | \"onSelectCapture\" | \"onTouchCancel\" | \"onTouchCancelCapture\" | \"onTouchEnd\" | \"onTouchEndCapture\" | \"onTouchMove\" | \"onTouchMoveCapture\" | \"onTouchStart\" | \"onTouchStartCapture\" | \"onPointerDown\" | \"onPointerDownCapture\" | \"onPointerMove\" | \"onPointerMoveCapture\" | \"onPointerUp\" | \"onPointerUpCapture\" | \"onPointerCancel\" | \"onPointerCancelCapture\" | \"onPointerEnter\" | \"onPointerEnterCapture\" | \"onPointerLeave\" | \"onPointerLeaveCapture\" | \"onPointerOver\" | \"onPointerOverCapture\" | \"onPointerOut\" | \"onPointerOutCapture\" | \"onGotPointerCapture\" | \"onGotPointerCaptureCapture\" | \"onLostPointerCapture\" | \"onLostPointerCaptureCapture\" | \"onScroll\" | \"onScrollCapture\" | \"onWheel\" | \"onWheelCapture\" | \"onAnimationStart\" | \"onAnimationStartCapture\" | \"onAnimationEnd\" | \"onAnimationEndCapture\" | \"onAnimationIteration\" | \"onAnimationIterationCapture\" | \"onTransitionEnd\" | \"onTransitionEndCapture\" | \"toastLifeTimeMs\" | \"iconType\" | \"onClose\" | \"data-test-subj\"> & { title?: string | ", "MountPoint", " | undefined; text?: string | ", "MountPoint", @@ -10278,229 +10278,1692 @@ "children": [ { "parentPluginId": "core", - "id": "def-server.CspConfig.private", - "type": "Any", + "id": "def-server.CspConfig.private", + "type": "Any", + "tags": [], + "label": "#private", + "description": [], + "signature": [ + "any" + ], + "path": "node_modules/@types/kbn__core-http-server-internal/index.d.ts", + "deprecated": false + }, + { + "parentPluginId": "core", + "id": "def-server.CspConfig.DEFAULT", + "type": "Object", + "tags": [], + "label": "DEFAULT", + "description": [], + "signature": [ + "CspConfig" + ], + "path": "node_modules/@types/kbn__core-http-server-internal/index.d.ts", + "deprecated": false + }, + { + "parentPluginId": "core", + "id": "def-server.CspConfig.strict", + "type": "boolean", + "tags": [], + "label": "strict", + "description": [], + "path": "node_modules/@types/kbn__core-http-server-internal/index.d.ts", + "deprecated": false + }, + { + "parentPluginId": "core", + "id": "def-server.CspConfig.warnLegacyBrowsers", + "type": "boolean", + "tags": [], + "label": "warnLegacyBrowsers", + "description": [], + "path": "node_modules/@types/kbn__core-http-server-internal/index.d.ts", + "deprecated": false + }, + { + "parentPluginId": "core", + "id": "def-server.CspConfig.disableEmbedding", + "type": "boolean", + "tags": [], + "label": "disableEmbedding", + "description": [], + "path": "node_modules/@types/kbn__core-http-server-internal/index.d.ts", + "deprecated": false + }, + { + "parentPluginId": "core", + "id": "def-server.CspConfig.header", + "type": "string", + "tags": [], + "label": "header", + "description": [], + "path": "node_modules/@types/kbn__core-http-server-internal/index.d.ts", + "deprecated": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "core", + "id": "def-server.EventLoopDelaysMonitor", + "type": "Class", + "tags": [], + "label": "EventLoopDelaysMonitor", + "description": [], + "signature": [ + "EventLoopDelaysMonitor", + " implements ", + "IEventLoopDelaysMonitor", + "<", + "IntervalHistogram", + ">" + ], + "path": "node_modules/@types/kbn__core-metrics-collectors-server-internal/index.d.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "core", + "id": "def-server.EventLoopDelaysMonitor.Unnamed", + "type": "Function", + "tags": [], + "label": "Constructor", + "description": [ + "\nCreating a new instance from EventLoopDelaysMonitor will\nautomatically start tracking event loop delays." + ], + "signature": [ + "any" + ], + "path": "node_modules/@types/kbn__core-metrics-collectors-server-internal/index.d.ts", + "deprecated": false, + "children": [], + "returnComment": [] + }, + { + "parentPluginId": "core", + "id": "def-server.EventLoopDelaysMonitor.collect", + "type": "Function", + "tags": [], + "label": "collect", + "description": [ + "\nCollect gathers event loop delays metrics from nodejs perf_hooks.monitorEventLoopDelay\nthe histogram calculations start from the last time `reset` was called or this\nEventLoopDelaysMonitor instance was created.\n\nReturns metrics in milliseconds.\n " + ], + "signature": [ + "() => ", + "IntervalHistogram" + ], + "path": "node_modules/@types/kbn__core-metrics-collectors-server-internal/index.d.ts", + "deprecated": false, + "children": [], + "returnComment": [] + }, + { + "parentPluginId": "core", + "id": "def-server.EventLoopDelaysMonitor.reset", + "type": "Function", + "tags": [], + "label": "reset", + "description": [ + "\nResets the collected histogram data." + ], + "signature": [ + "() => void" + ], + "path": "node_modules/@types/kbn__core-metrics-collectors-server-internal/index.d.ts", + "deprecated": false, + "children": [], + "returnComment": [] + }, + { + "parentPluginId": "core", + "id": "def-server.EventLoopDelaysMonitor.stop", + "type": "Function", + "tags": [], + "label": "stop", + "description": [ + "\nDisables updating the interval timer for collecting new data points." + ], + "signature": [ + "() => void" + ], + "path": "node_modules/@types/kbn__core-metrics-collectors-server-internal/index.d.ts", + "deprecated": false, + "children": [], + "returnComment": [] + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "core", + "id": "def-server.RouteValidationError", + "type": "Class", + "tags": [], + "label": "RouteValidationError", + "description": [ + "\nError to return when the validation is not successful." + ], + "signature": [ + "RouteValidationError", + " extends ", + "SchemaTypeError" + ], + "path": "node_modules/@types/kbn__core-http-server/index.d.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "core", + "id": "def-server.RouteValidationError.Unnamed", + "type": "Function", + "tags": [], + "label": "Constructor", + "description": [], + "signature": [ + "any" + ], + "path": "node_modules/@types/kbn__core-http-server/index.d.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "core", + "id": "def-server.RouteValidationError.Unnamed.$1", + "type": "CompoundType", + "tags": [], + "label": "error", + "description": [], + "signature": [ + "string | Error" + ], + "path": "node_modules/@types/kbn__core-http-server/index.d.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "core", + "id": "def-server.RouteValidationError.Unnamed.$2", + "type": "Array", + "tags": [], + "label": "path", + "description": [], + "signature": [ + "string[] | undefined" + ], + "path": "node_modules/@types/kbn__core-http-server/index.d.ts", + "deprecated": false, + "isRequired": false + } + ], + "returnComment": [] + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsErrorHelpers", + "type": "Class", + "tags": [], + "label": "SavedObjectsErrorHelpers", + "description": [], + "signature": [ + "SavedObjectsErrorHelpers" + ], + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsErrorHelpers.isSavedObjectsClientError", + "type": "Function", + "tags": [], + "label": "isSavedObjectsClientError", + "description": [], + "signature": [ + "(error: any) => error is ", + "DecoratedError" + ], + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsErrorHelpers.isSavedObjectsClientError.$1", + "type": "Any", + "tags": [], + "label": "error", + "description": [], + "signature": [ + "any" + ], + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsErrorHelpers.decorateBadRequestError", + "type": "Function", + "tags": [], + "label": "decorateBadRequestError", + "description": [], + "signature": [ + "(error: Error, reason?: string | undefined) => ", + "DecoratedError" + ], + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsErrorHelpers.decorateBadRequestError.$1", + "type": "Object", + "tags": [], + "label": "error", + "description": [], + "signature": [ + "Error" + ], + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsErrorHelpers.decorateBadRequestError.$2", + "type": "string", + "tags": [], + "label": "reason", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false, + "isRequired": false + } + ], + "returnComment": [] + }, + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsErrorHelpers.createBadRequestError", + "type": "Function", + "tags": [], + "label": "createBadRequestError", + "description": [], + "signature": [ + "(reason?: string | undefined) => ", + "DecoratedError" + ], + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsErrorHelpers.createBadRequestError.$1", + "type": "string", + "tags": [], + "label": "reason", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false, + "isRequired": false + } + ], + "returnComment": [] + }, + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsErrorHelpers.createUnsupportedTypeError", + "type": "Function", + "tags": [], + "label": "createUnsupportedTypeError", + "description": [], + "signature": [ + "(type: string) => ", + "DecoratedError" + ], + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsErrorHelpers.createUnsupportedTypeError.$1", + "type": "string", + "tags": [], + "label": "type", + "description": [], + "signature": [ + "string" + ], + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsErrorHelpers.isBadRequestError", + "type": "Function", + "tags": [], + "label": "isBadRequestError", + "description": [], + "signature": [ + "(error: Error | ", + "DecoratedError", + ") => boolean" + ], + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsErrorHelpers.isBadRequestError.$1", + "type": "CompoundType", + "tags": [], + "label": "error", + "description": [], + "signature": [ + "Error | ", + "DecoratedError" + ], + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsErrorHelpers.createInvalidVersionError", + "type": "Function", + "tags": [], + "label": "createInvalidVersionError", + "description": [], + "signature": [ + "(versionInput?: string | undefined) => ", + "DecoratedError" + ], + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsErrorHelpers.createInvalidVersionError.$1", + "type": "string", + "tags": [], + "label": "versionInput", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false, + "isRequired": false + } + ], + "returnComment": [] + }, + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsErrorHelpers.isInvalidVersionError", + "type": "Function", + "tags": [], + "label": "isInvalidVersionError", + "description": [], + "signature": [ + "(error: Error | ", + "DecoratedError", + ") => boolean" + ], + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsErrorHelpers.isInvalidVersionError.$1", + "type": "CompoundType", + "tags": [], + "label": "error", + "description": [], + "signature": [ + "Error | ", + "DecoratedError" + ], + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsErrorHelpers.decorateNotAuthorizedError", + "type": "Function", + "tags": [], + "label": "decorateNotAuthorizedError", + "description": [], + "signature": [ + "(error: Error, reason?: string | undefined) => ", + "DecoratedError" + ], + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsErrorHelpers.decorateNotAuthorizedError.$1", + "type": "Object", + "tags": [], + "label": "error", + "description": [], + "signature": [ + "Error" + ], + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsErrorHelpers.decorateNotAuthorizedError.$2", + "type": "string", + "tags": [], + "label": "reason", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false, + "isRequired": false + } + ], + "returnComment": [] + }, + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsErrorHelpers.isNotAuthorizedError", + "type": "Function", + "tags": [], + "label": "isNotAuthorizedError", + "description": [], + "signature": [ + "(error: Error | ", + "DecoratedError", + ") => boolean" + ], + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsErrorHelpers.isNotAuthorizedError.$1", + "type": "CompoundType", + "tags": [], + "label": "error", + "description": [], + "signature": [ + "Error | ", + "DecoratedError" + ], + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsErrorHelpers.decorateForbiddenError", + "type": "Function", + "tags": [], + "label": "decorateForbiddenError", + "description": [], + "signature": [ + "(error: Error, reason?: string | undefined) => ", + "DecoratedError" + ], + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsErrorHelpers.decorateForbiddenError.$1", + "type": "Object", + "tags": [], + "label": "error", + "description": [], + "signature": [ + "Error" + ], + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsErrorHelpers.decorateForbiddenError.$2", + "type": "string", + "tags": [], + "label": "reason", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false, + "isRequired": false + } + ], + "returnComment": [] + }, + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsErrorHelpers.isForbiddenError", + "type": "Function", + "tags": [], + "label": "isForbiddenError", + "description": [], + "signature": [ + "(error: Error | ", + "DecoratedError", + ") => boolean" + ], + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsErrorHelpers.isForbiddenError.$1", + "type": "CompoundType", + "tags": [], + "label": "error", + "description": [], + "signature": [ + "Error | ", + "DecoratedError" + ], + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsErrorHelpers.decorateRequestEntityTooLargeError", + "type": "Function", + "tags": [], + "label": "decorateRequestEntityTooLargeError", + "description": [], + "signature": [ + "(error: Error, reason?: string | undefined) => ", + "DecoratedError" + ], + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsErrorHelpers.decorateRequestEntityTooLargeError.$1", + "type": "Object", + "tags": [], + "label": "error", + "description": [], + "signature": [ + "Error" + ], + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsErrorHelpers.decorateRequestEntityTooLargeError.$2", + "type": "string", + "tags": [], + "label": "reason", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false, + "isRequired": false + } + ], + "returnComment": [] + }, + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsErrorHelpers.isRequestEntityTooLargeError", + "type": "Function", + "tags": [], + "label": "isRequestEntityTooLargeError", + "description": [], + "signature": [ + "(error: Error | ", + "DecoratedError", + ") => boolean" + ], + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsErrorHelpers.isRequestEntityTooLargeError.$1", + "type": "CompoundType", + "tags": [], + "label": "error", + "description": [], + "signature": [ + "Error | ", + "DecoratedError" + ], + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsErrorHelpers.createGenericNotFoundError", + "type": "Function", + "tags": [], + "label": "createGenericNotFoundError", + "description": [], + "signature": [ + "(type?: string | null | undefined, id?: string | null | undefined) => ", + "DecoratedError" + ], + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsErrorHelpers.createGenericNotFoundError.$1", + "type": "CompoundType", + "tags": [], + "label": "type", + "description": [], + "signature": [ + "string | null | undefined" + ], + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false, + "isRequired": false + }, + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsErrorHelpers.createGenericNotFoundError.$2", + "type": "CompoundType", + "tags": [], + "label": "id", + "description": [], + "signature": [ + "string | null | undefined" + ], + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false, + "isRequired": false + } + ], + "returnComment": [] + }, + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsErrorHelpers.createIndexAliasNotFoundError", + "type": "Function", + "tags": [], + "label": "createIndexAliasNotFoundError", + "description": [], + "signature": [ + "(alias: string) => ", + "DecoratedError" + ], + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsErrorHelpers.createIndexAliasNotFoundError.$1", + "type": "string", + "tags": [], + "label": "alias", + "description": [], + "signature": [ + "string" + ], + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsErrorHelpers.decorateIndexAliasNotFoundError", + "type": "Function", + "tags": [], + "label": "decorateIndexAliasNotFoundError", + "description": [], + "signature": [ + "(error: Error, alias: string) => ", + "DecoratedError" + ], + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsErrorHelpers.decorateIndexAliasNotFoundError.$1", + "type": "Object", + "tags": [], + "label": "error", + "description": [], + "signature": [ + "Error" + ], + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsErrorHelpers.decorateIndexAliasNotFoundError.$2", + "type": "string", + "tags": [], + "label": "alias", + "description": [], + "signature": [ + "string" + ], + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsErrorHelpers.isNotFoundError", + "type": "Function", + "tags": [], + "label": "isNotFoundError", + "description": [], + "signature": [ + "(error: Error | ", + "DecoratedError", + ") => boolean" + ], + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsErrorHelpers.isNotFoundError.$1", + "type": "CompoundType", + "tags": [], + "label": "error", + "description": [], + "signature": [ + "Error | ", + "DecoratedError" + ], + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsErrorHelpers.decorateConflictError", + "type": "Function", + "tags": [], + "label": "decorateConflictError", + "description": [], + "signature": [ + "(error: Error, reason?: string | undefined) => ", + "DecoratedError" + ], + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsErrorHelpers.decorateConflictError.$1", + "type": "Object", + "tags": [], + "label": "error", + "description": [], + "signature": [ + "Error" + ], + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsErrorHelpers.decorateConflictError.$2", + "type": "string", + "tags": [], + "label": "reason", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false, + "isRequired": false + } + ], + "returnComment": [] + }, + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsErrorHelpers.createConflictError", + "type": "Function", + "tags": [], + "label": "createConflictError", + "description": [], + "signature": [ + "(type: string, id: string, reason?: string | undefined) => ", + "DecoratedError" + ], + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsErrorHelpers.createConflictError.$1", + "type": "string", + "tags": [], + "label": "type", + "description": [], + "signature": [ + "string" + ], + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsErrorHelpers.createConflictError.$2", + "type": "string", + "tags": [], + "label": "id", + "description": [], + "signature": [ + "string" + ], + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsErrorHelpers.createConflictError.$3", + "type": "string", + "tags": [], + "label": "reason", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false, + "isRequired": false + } + ], + "returnComment": [] + }, + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsErrorHelpers.isConflictError", + "type": "Function", + "tags": [], + "label": "isConflictError", + "description": [], + "signature": [ + "(error: Error | ", + "DecoratedError", + ") => boolean" + ], + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsErrorHelpers.isConflictError.$1", + "type": "CompoundType", + "tags": [], + "label": "error", + "description": [], + "signature": [ + "Error | ", + "DecoratedError" + ], + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsErrorHelpers.decorateTooManyRequestsError", + "type": "Function", + "tags": [], + "label": "decorateTooManyRequestsError", + "description": [], + "signature": [ + "(error: Error, reason?: string | undefined) => ", + "DecoratedError" + ], + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsErrorHelpers.decorateTooManyRequestsError.$1", + "type": "Object", + "tags": [], + "label": "error", + "description": [], + "signature": [ + "Error" + ], + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsErrorHelpers.decorateTooManyRequestsError.$2", + "type": "string", + "tags": [], + "label": "reason", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false, + "isRequired": false + } + ], + "returnComment": [] + }, + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsErrorHelpers.createTooManyRequestsError", + "type": "Function", "tags": [], - "label": "#private", + "label": "createTooManyRequestsError", "description": [], "signature": [ - "any" + "(type: string, id: string) => ", + "DecoratedError" ], - "path": "node_modules/@types/kbn__core-http-server-internal/index.d.ts", - "deprecated": false + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsErrorHelpers.createTooManyRequestsError.$1", + "type": "string", + "tags": [], + "label": "type", + "description": [], + "signature": [ + "string" + ], + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsErrorHelpers.createTooManyRequestsError.$2", + "type": "string", + "tags": [], + "label": "id", + "description": [], + "signature": [ + "string" + ], + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] }, { "parentPluginId": "core", - "id": "def-server.CspConfig.DEFAULT", - "type": "Object", + "id": "def-server.SavedObjectsErrorHelpers.isTooManyRequestsError", + "type": "Function", "tags": [], - "label": "DEFAULT", + "label": "isTooManyRequestsError", "description": [], "signature": [ - "CspConfig" + "(error: Error | ", + "DecoratedError", + ") => boolean" ], - "path": "node_modules/@types/kbn__core-http-server-internal/index.d.ts", - "deprecated": false + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsErrorHelpers.isTooManyRequestsError.$1", + "type": "CompoundType", + "tags": [], + "label": "error", + "description": [], + "signature": [ + "Error | ", + "DecoratedError" + ], + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] }, { "parentPluginId": "core", - "id": "def-server.CspConfig.strict", - "type": "boolean", + "id": "def-server.SavedObjectsErrorHelpers.decorateEsCannotExecuteScriptError", + "type": "Function", "tags": [], - "label": "strict", + "label": "decorateEsCannotExecuteScriptError", "description": [], - "path": "node_modules/@types/kbn__core-http-server-internal/index.d.ts", - "deprecated": false + "signature": [ + "(error: Error, reason?: string | undefined) => ", + "DecoratedError" + ], + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsErrorHelpers.decorateEsCannotExecuteScriptError.$1", + "type": "Object", + "tags": [], + "label": "error", + "description": [], + "signature": [ + "Error" + ], + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsErrorHelpers.decorateEsCannotExecuteScriptError.$2", + "type": "string", + "tags": [], + "label": "reason", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false, + "isRequired": false + } + ], + "returnComment": [] }, { "parentPluginId": "core", - "id": "def-server.CspConfig.warnLegacyBrowsers", - "type": "boolean", + "id": "def-server.SavedObjectsErrorHelpers.isEsCannotExecuteScriptError", + "type": "Function", "tags": [], - "label": "warnLegacyBrowsers", + "label": "isEsCannotExecuteScriptError", "description": [], - "path": "node_modules/@types/kbn__core-http-server-internal/index.d.ts", - "deprecated": false + "signature": [ + "(error: Error | ", + "DecoratedError", + ") => boolean" + ], + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsErrorHelpers.isEsCannotExecuteScriptError.$1", + "type": "CompoundType", + "tags": [], + "label": "error", + "description": [], + "signature": [ + "Error | ", + "DecoratedError" + ], + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] }, { "parentPluginId": "core", - "id": "def-server.CspConfig.disableEmbedding", - "type": "boolean", + "id": "def-server.SavedObjectsErrorHelpers.decorateEsUnavailableError", + "type": "Function", "tags": [], - "label": "disableEmbedding", + "label": "decorateEsUnavailableError", "description": [], - "path": "node_modules/@types/kbn__core-http-server-internal/index.d.ts", - "deprecated": false + "signature": [ + "(error: Error, reason?: string | undefined) => ", + "DecoratedError" + ], + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsErrorHelpers.decorateEsUnavailableError.$1", + "type": "Object", + "tags": [], + "label": "error", + "description": [], + "signature": [ + "Error" + ], + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsErrorHelpers.decorateEsUnavailableError.$2", + "type": "string", + "tags": [], + "label": "reason", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false, + "isRequired": false + } + ], + "returnComment": [] }, { "parentPluginId": "core", - "id": "def-server.CspConfig.header", - "type": "string", + "id": "def-server.SavedObjectsErrorHelpers.isEsUnavailableError", + "type": "Function", "tags": [], - "label": "header", + "label": "isEsUnavailableError", "description": [], - "path": "node_modules/@types/kbn__core-http-server-internal/index.d.ts", - "deprecated": false + "signature": [ + "(error: Error | ", + "DecoratedError", + ") => boolean" + ], + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsErrorHelpers.isEsUnavailableError.$1", + "type": "CompoundType", + "tags": [], + "label": "error", + "description": [], + "signature": [ + "Error | ", + "DecoratedError" + ], + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsErrorHelpers.decorateGeneralError", + "type": "Function", + "tags": [], + "label": "decorateGeneralError", + "description": [], + "signature": [ + "(error: Error, reason?: string | undefined) => ", + "DecoratedError" + ], + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsErrorHelpers.decorateGeneralError.$1", + "type": "Object", + "tags": [], + "label": "error", + "description": [], + "signature": [ + "Error" + ], + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsErrorHelpers.decorateGeneralError.$2", + "type": "string", + "tags": [], + "label": "reason", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false, + "isRequired": false + } + ], + "returnComment": [] + }, + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsErrorHelpers.isGeneralError", + "type": "Function", + "tags": [], + "label": "isGeneralError", + "description": [], + "signature": [ + "(error: Error | ", + "DecoratedError", + ") => boolean" + ], + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsErrorHelpers.isGeneralError.$1", + "type": "CompoundType", + "tags": [], + "label": "error", + "description": [], + "signature": [ + "Error | ", + "DecoratedError" + ], + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsErrorHelpers.createGenericNotFoundEsUnavailableError", + "type": "Function", + "tags": [], + "label": "createGenericNotFoundEsUnavailableError", + "description": [], + "signature": [ + "(type?: string | null | undefined, id?: string | null | undefined) => ", + "DecoratedError" + ], + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsErrorHelpers.createGenericNotFoundEsUnavailableError.$1", + "type": "CompoundType", + "tags": [], + "label": "type", + "description": [], + "signature": [ + "string | null | undefined" + ], + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false, + "isRequired": false + }, + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsErrorHelpers.createGenericNotFoundEsUnavailableError.$2", + "type": "CompoundType", + "tags": [], + "label": "id", + "description": [], + "signature": [ + "string | null | undefined" + ], + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false, + "isRequired": false + } + ], + "returnComment": [] } ], "initialIsOpen": false }, { "parentPluginId": "core", - "id": "def-server.EventLoopDelaysMonitor", + "id": "def-server.SavedObjectsUtils", "type": "Class", "tags": [], - "label": "EventLoopDelaysMonitor", + "label": "SavedObjectsUtils", "description": [], "signature": [ - "EventLoopDelaysMonitor", - " implements ", - "IEventLoopDelaysMonitor", - "<", - "IntervalHistogram", - ">" + "SavedObjectsUtils" ], - "path": "node_modules/@types/kbn__core-metrics-collectors-server-internal/index.d.ts", + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", "deprecated": false, "children": [ { "parentPluginId": "core", - "id": "def-server.EventLoopDelaysMonitor.Unnamed", + "id": "def-server.SavedObjectsUtils.namespaceIdToString", "type": "Function", "tags": [], - "label": "Constructor", + "label": "namespaceIdToString", "description": [ - "\nCreating a new instance from EventLoopDelaysMonitor will\nautomatically start tracking event loop delays." + "\nConverts a given saved object namespace ID to its string representation. All namespace IDs have an identical string representation, with\nthe exception of the `undefined` namespace ID (which has a namespace string of `'default'`).\n" ], "signature": [ - "any" + "(namespace?: string | undefined) => string" ], - "path": "node_modules/@types/kbn__core-metrics-collectors-server-internal/index.d.ts", + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", "deprecated": false, - "children": [], - "returnComment": [] + "returnComment": [], + "children": [ + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsUtils.namespaceIdToString.$1", + "type": "string", + "tags": [], + "label": "namespace", + "description": [ + "The namespace ID, which must be either a non-empty string or `undefined`." + ], + "signature": [ + "string | undefined" + ], + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false + } + ] }, { "parentPluginId": "core", - "id": "def-server.EventLoopDelaysMonitor.collect", + "id": "def-server.SavedObjectsUtils.namespaceStringToId", "type": "Function", "tags": [], - "label": "collect", + "label": "namespaceStringToId", "description": [ - "\nCollect gathers event loop delays metrics from nodejs perf_hooks.monitorEventLoopDelay\nthe histogram calculations start from the last time `reset` was called or this\nEventLoopDelaysMonitor instance was created.\n\nReturns metrics in milliseconds.\n " + "\nConverts a given saved object namespace string to its ID representation. All namespace strings have an identical ID representation, with\nthe exception of the `'default'` namespace string (which has a namespace ID of `undefined`).\n" ], "signature": [ - "() => ", - "IntervalHistogram" + "(namespace: string) => string | undefined" ], - "path": "node_modules/@types/kbn__core-metrics-collectors-server-internal/index.d.ts", + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", "deprecated": false, - "children": [], - "returnComment": [] + "returnComment": [], + "children": [ + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsUtils.namespaceStringToId.$1", + "type": "string", + "tags": [], + "label": "namespace", + "description": [ + "The namespace string, which must be non-empty." + ], + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false + } + ] }, { "parentPluginId": "core", - "id": "def-server.EventLoopDelaysMonitor.reset", + "id": "def-server.SavedObjectsUtils.createEmptyFindResponse", "type": "Function", "tags": [], - "label": "reset", + "label": "createEmptyFindResponse", "description": [ - "\nResets the collected histogram data." + "\nCreates an empty response for a find operation. This is only intended to be used by saved objects client wrappers." ], "signature": [ - "() => void" + "({ page, perPage, }: ", + "SavedObjectsFindOptions", + ") => ", + "SavedObjectsFindResponse", + "" ], - "path": "node_modules/@types/kbn__core-metrics-collectors-server-internal/index.d.ts", + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", "deprecated": false, - "children": [], - "returnComment": [] + "returnComment": [], + "children": [ + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsUtils.createEmptyFindResponse.$1", + "type": "Object", + "tags": [], + "label": "__0", + "description": [], + "signature": [ + "SavedObjectsFindOptions" + ], + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false + } + ] }, { "parentPluginId": "core", - "id": "def-server.EventLoopDelaysMonitor.stop", + "id": "def-server.SavedObjectsUtils.generateId", "type": "Function", "tags": [], - "label": "stop", + "label": "generateId", "description": [ - "\nDisables updating the interval timer for collecting new data points." + "\nGenerates a random ID for a saved objects." ], "signature": [ - "() => void" + "() => string" ], - "path": "node_modules/@types/kbn__core-metrics-collectors-server-internal/index.d.ts", + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", "deprecated": false, "children": [], "returnComment": [] - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "core", - "id": "def-server.RouteValidationError", - "type": "Class", - "tags": [], - "label": "RouteValidationError", - "description": [ - "\nError to return when the validation is not successful." - ], - "signature": [ - "RouteValidationError", - " extends ", - "SchemaTypeError" - ], - "path": "node_modules/@types/kbn__core-http-server/index.d.ts", - "deprecated": false, - "children": [ + }, { "parentPluginId": "core", - "id": "def-server.RouteValidationError.Unnamed", + "id": "def-server.SavedObjectsUtils.isRandomId", + "type": "Function", + "tags": [ + "todo" + ], + "label": "isRandomId", + "description": [ + "\nValidates that a saved object ID has been randomly generated.\n" + ], + "signature": [ + "(id: string | undefined) => boolean" + ], + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsUtils.isRandomId.$1", + "type": "string", + "tags": [], + "label": "id", + "description": [ + "The ID of a saved object." + ], + "signature": [ + "string | undefined" + ], + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false, + "isRequired": false + } + ], + "returnComment": [] + }, + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsUtils.getConvertedObjectId", "type": "Function", "tags": [], - "label": "Constructor", - "description": [], + "label": "getConvertedObjectId", + "description": [ + "\nUses a single-namespace object's \"legacy ID\" to determine what its new ID will be after it is converted to a multi-namespace type.\n" + ], "signature": [ - "any" + "(namespace: string | undefined, type: string, id: string) => string" ], - "path": "node_modules/@types/kbn__core-http-server/index.d.ts", + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", "deprecated": false, "children": [ { "parentPluginId": "core", - "id": "def-server.RouteValidationError.Unnamed.$1", - "type": "CompoundType", + "id": "def-server.SavedObjectsUtils.getConvertedObjectId.$1", + "type": "string", "tags": [], - "label": "error", - "description": [], + "label": "namespace", + "description": [ + "The namespace of the saved object before it is converted." + ], "signature": [ - "string | Error" + "string | undefined" ], - "path": "node_modules/@types/kbn__core-http-server/index.d.ts", + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false, + "isRequired": false + }, + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsUtils.getConvertedObjectId.$2", + "type": "string", + "tags": [], + "label": "type", + "description": [ + "The type of the saved object before it is converted." + ], + "signature": [ + "string" + ], + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", "deprecated": false, "isRequired": true }, { "parentPluginId": "core", - "id": "def-server.RouteValidationError.Unnamed.$2", - "type": "Array", + "id": "def-server.SavedObjectsUtils.getConvertedObjectId.$3", + "type": "string", "tags": [], - "label": "path", - "description": [], + "label": "id", + "description": [ + "The ID of the saved object before it is converted." + ], "signature": [ - "string[] | undefined" + "string" ], - "path": "node_modules/@types/kbn__core-http-server/index.d.ts", + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", "deprecated": false, - "isRequired": false + "isRequired": true } ], - "returnComment": [] + "returnComment": [ + "The ID of the saved object after it is converted." + ] } ], "initialIsOpen": false } ], "functions": [ + { + "parentPluginId": "core", + "id": "def-server.mergeSavedObjectMigrationMaps", + "type": "Function", + "tags": [], + "label": "mergeSavedObjectMigrationMaps", + "description": [ + "\nMerges two saved object migration maps.\n\nIf there is a migration for a given version on only one of the maps,\nthat migration function will be used:\n\nmergeSavedObjectMigrationMaps({ '1.2.3': f }, { '4.5.6': g }) -> { '1.2.3': f, '4.5.6': g }\n\nIf there is a migration for a given version on both maps, the migrations will be composed:\n\nmergeSavedObjectMigrationMaps({ '1.2.3': f }, { '1.2.3': g }) -> { '1.2.3': (doc, context) => f(g(doc, context), context) }\n" + ], + "signature": [ + "(map1: ", + "SavedObjectMigrationMap", + ", map2: ", + "SavedObjectMigrationMap", + ") => ", + "SavedObjectMigrationMap" + ], + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false, + "returnComment": [], + "children": [ + { + "parentPluginId": "core", + "id": "def-server.mergeSavedObjectMigrationMaps.$1", + "type": "Object", + "tags": [], + "label": "map1", + "description": [], + "signature": [ + "SavedObjectMigrationMap" + ], + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false + }, + { + "parentPluginId": "core", + "id": "def-server.mergeSavedObjectMigrationMaps.$2", + "type": "Object", + "tags": [], + "label": "map2", + "description": [], + "signature": [ + "SavedObjectMigrationMap" + ], + "path": "node_modules/@types/kbn__core-saved-objects-utils-server/index.d.ts", + "deprecated": false + } + ], + "initialIsOpen": false + }, { "parentPluginId": "core", "id": "def-server.pollEsNodesVersion", @@ -15798,7 +17261,9 @@ "TransportRequestOptions", " | undefined): Promise<", "WriteResponseBase", - ">; }; name: string | symbol; transform: ", + ">; }; cluster: ", + "default", + "; eql: ", "default", "; search: { >; }; cluster: ", - "default", - "; eql: ", - "default", - "; create: { (this: That, params: ", + ">; }; create: { (this: That, params: ", "CreateRequest", " | ", "CreateRequest", @@ -15866,7 +17327,7 @@ "default", "; security: ", "default", - "; index: { (this: That, params: ", + "; name: string | symbol; index: { (this: That, params: ", "IndexRequest", " | ", "IndexRequest", @@ -16878,6 +18339,8 @@ "TermvectorsResponse", ">; }; textStructure: ", "default", + "; transform: ", + "default", "; updateByQuery: { (this: That, params: ", "UpdateByQueryRequest", " | ", @@ -20724,7 +22187,9 @@ "TransportRequestOptions", " | undefined): Promise<", "WriteResponseBase", - ">; }; name: string | symbol; transform: ", + ">; }; cluster: ", + "default", + "; eql: ", "default", "; search: { >; }; cluster: ", - "default", - "; eql: ", - "default", - "; create: { (this: That, params: ", + ">; }; create: { (this: That, params: ", "CreateRequest", " | ", "CreateRequest", @@ -20792,7 +22253,7 @@ "default", "; security: ", "default", - "; index: { (this: That, params: ", + "; name: string | symbol; index: { (this: That, params: ", "IndexRequest", " | ", "IndexRequest", @@ -21804,6 +23265,8 @@ "TermvectorsResponse", ">; }; textStructure: ", "default", + "; transform: ", + "default", "; updateByQuery: { (this: That, params: ", "UpdateByQueryRequest", " | ", @@ -21927,7 +23390,9 @@ "TransportRequestOptions", " | undefined): Promise<", "WriteResponseBase", - ">; }; name: string | symbol; transform: ", + ">; }; cluster: ", + "default", + "; eql: ", "default", "; search: { >; }; cluster: ", - "default", - "; eql: ", - "default", - "; create: { (this: That, params: ", + ">; }; create: { (this: That, params: ", "CreateRequest", " | ", "CreateRequest", @@ -21995,7 +23456,7 @@ "default", "; security: ", "default", - "; index: { (this: That, params: ", + "; name: string | symbol; index: { (this: That, params: ", "IndexRequest", " | ", "IndexRequest", @@ -23007,6 +24468,8 @@ "TermvectorsResponse", ">; }; textStructure: ", "default", + "; transform: ", + "default", "; updateByQuery: { (this: That, params: ", "UpdateByQueryRequest", " | ", @@ -24281,7 +25744,7 @@ "label": "level", "description": [], "signature": [ - "\"error\" | \"all\" | \"off\" | \"info\" | \"debug\" | \"trace\" | \"warn\" | \"fatal\"" + "\"error\" | \"all\" | \"info\" | \"debug\" | \"off\" | \"trace\" | \"warn\" | \"fatal\"" ], "path": "node_modules/@types/kbn__core-logging-server/index.d.ts", "deprecated": false @@ -26222,7 +27685,9 @@ "TransportRequestOptions", " | undefined): Promise<", "WriteResponseBase", - ">; }; name: string | symbol; transform: ", + ">; }; cluster: ", + "default", + "; eql: ", "default", "; search: { >; }; cluster: ", - "default", - "; eql: ", - "default", - "; create: { (this: That, params: ", + ">; }; create: { (this: That, params: ", "CreateRequest", " | ", "CreateRequest", @@ -26290,7 +27751,7 @@ "default", "; security: ", "default", - "; index: { (this: That, params: ", + "; name: string | symbol; index: { (this: That, params: ", "IndexRequest", " | ", "IndexRequest", @@ -27302,6 +28763,8 @@ "TermvectorsResponse", ">; }; textStructure: ", "default", + "; transform: ", + "default", "; updateByQuery: { (this: That, params: ", "UpdateByQueryRequest", " | ", @@ -36951,7 +38414,7 @@ "label": "EcsEventType", "description": [], "signature": [ - "\"start\" | \"error\" | \"connection\" | \"end\" | \"group\" | \"user\" | \"info\" | \"admin\" | \"protocol\" | \"access\" | \"allowed\" | \"change\" | \"creation\" | \"deletion\" | \"denied\" | \"installation\"" + "\"start\" | \"error\" | \"connection\" | \"user\" | \"info\" | \"group\" | \"end\" | \"admin\" | \"protocol\" | \"access\" | \"allowed\" | \"change\" | \"creation\" | \"deletion\" | \"denied\" | \"installation\"" ], "path": "node_modules/@types/kbn__logging/index.d.ts", "deprecated": false, @@ -37019,7 +38482,9 @@ "TransportRequestOptions", " | undefined): Promise<", "WriteResponseBase", - ">; }; name: string | symbol; transform: ", + ">; }; cluster: ", + "default", + "; eql: ", "default", "; search: { >; }; cluster: ", - "default", - "; eql: ", - "default", - "; create: { (this: That, params: ", + ">; }; create: { (this: That, params: ", "CreateRequest", " | ", "CreateRequest", @@ -37087,7 +38548,7 @@ "default", "; security: ", "default", - "; index: { (this: That, params: ", + "; name: string | symbol; index: { (this: That, params: ", "IndexRequest", " | ", "IndexRequest", @@ -38099,6 +39560,8 @@ "TermvectorsResponse", ">; }; textStructure: ", "default", + "; transform: ", + "default", "; updateByQuery: { (this: That, params: ", "UpdateByQueryRequest", " | ", @@ -39404,7 +40867,7 @@ "signature": [ "{ options?: string[] | number[] | undefined; type?: ", "UiSettingsType", - " | undefined; metric?: { type: string; name: string; } | undefined; name?: string | undefined; order?: number | undefined; value?: unknown; description?: string | undefined; category?: string[] | undefined; optionLabels?: Record | undefined; requiresPageReload?: boolean | undefined; readonly?: boolean | undefined; sensitive?: boolean | undefined; deprecation?: ", + " | undefined; metric?: { type: string; name: string; } | undefined; value?: unknown; description?: string | undefined; name?: string | undefined; order?: number | undefined; category?: string[] | undefined; optionLabels?: Record | undefined; requiresPageReload?: boolean | undefined; readonly?: boolean | undefined; sensitive?: boolean | undefined; deprecation?: ", "DeprecationSettings", " | undefined; }" ], diff --git a/api_docs/core.mdx b/api_docs/core.mdx index d2617beda341df..64ec51aebbae78 100644 --- a/api_docs/core.mdx +++ b/api_docs/core.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/core title: "core" image: https://source.unsplash.com/400x175/?github description: API docs for the core plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'core'] --- import coreObj from './core.devdocs.json'; @@ -21,7 +21,7 @@ Contact [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) for que | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 2524 | 2 | 296 | 6 | +| 2524 | 1 | 216 | 5 | ## Client diff --git a/api_docs/core_application.devdocs.json b/api_docs/core_application.devdocs.json index 00b0c241fac11c..30eaa3462a34aa 100644 --- a/api_docs/core_application.devdocs.json +++ b/api_docs/core_application.devdocs.json @@ -2168,7 +2168,7 @@ "section": "def-public.AppStatus", "text": "AppStatus" }, - " | undefined; tooltip?: string | undefined; searchable?: boolean | undefined; deepLinks?: ", + " | undefined; searchable?: boolean | undefined; deepLinks?: ", { "pluginId": "core", "scope": "public", @@ -2184,7 +2184,7 @@ "section": "def-public.AppNavLinkStatus", "text": "AppNavLinkStatus" }, - " | undefined; defaultPath?: string | undefined; }" + " | undefined; defaultPath?: string | undefined; tooltip?: string | undefined; }" ], "path": "src/core/public/application/types.ts", "deprecated": false, diff --git a/api_docs/core_application.mdx b/api_docs/core_application.mdx index d4e1c7abfaa554..b226c180814ebe 100644 --- a/api_docs/core_application.mdx +++ b/api_docs/core_application.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/core-application title: "core.application" image: https://source.unsplash.com/400x175/?github description: API docs for the core.application plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'core.application'] --- import coreApplicationObj from './core_application.devdocs.json'; @@ -21,7 +21,7 @@ Contact [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) for que | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 2524 | 2 | 296 | 6 | +| 2524 | 1 | 216 | 5 | ## Client diff --git a/api_docs/core_chrome.devdocs.json b/api_docs/core_chrome.devdocs.json index ddbd7175cd71a8..a1c6878eef0632 100644 --- a/api_docs/core_chrome.devdocs.json +++ b/api_docs/core_chrome.devdocs.json @@ -1912,7 +1912,7 @@ "signature": [ "React.HTMLAttributes & ", "CommonProps", - " & { href?: string | undefined; onClick?: React.MouseEventHandler | undefined; text: React.ReactNode; truncate?: boolean | undefined; color?: \"warning\" | \"primary\" | \"success\" | \"accent\" | \"danger\" | \"text\" | \"subdued\" | \"ghost\" | undefined; 'aria-current'?: boolean | \"date\" | \"location\" | \"true\" | \"false\" | \"page\" | \"step\" | \"time\" | undefined; }" + " & { href?: string | undefined; onClick?: React.MouseEventHandler | undefined; text: React.ReactNode; truncate?: boolean | undefined; color?: \"warning\" | \"subdued\" | \"primary\" | \"accent\" | \"success\" | \"danger\" | \"text\" | \"ghost\" | undefined; 'aria-current'?: boolean | \"date\" | \"location\" | \"time\" | \"page\" | \"false\" | \"true\" | \"step\" | undefined; }" ], "path": "src/core/public/chrome/types.ts", "deprecated": false, @@ -1926,9 +1926,9 @@ "label": "ChromeHelpExtensionLinkBase", "description": [], "signature": [ - "{ target?: string | (string & {}) | undefined; 'data-test-subj'?: string | undefined; iconType?: ", + "{ iconType?: ", "IconType", - " | undefined; rel?: string | undefined; }" + " | undefined; 'data-test-subj'?: string | undefined; rel?: string | undefined; target?: string | (string & {}) | undefined; }" ], "path": "src/core/public/chrome/ui/header/header_help_menu.tsx", "deprecated": false, diff --git a/api_docs/core_chrome.mdx b/api_docs/core_chrome.mdx index 2488a4ea9b758b..abc55c34b289d6 100644 --- a/api_docs/core_chrome.mdx +++ b/api_docs/core_chrome.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/core-chrome title: "core.chrome" image: https://source.unsplash.com/400x175/?github description: API docs for the core.chrome plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'core.chrome'] --- import coreChromeObj from './core_chrome.devdocs.json'; @@ -21,7 +21,7 @@ Contact [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) for que | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 2524 | 2 | 296 | 6 | +| 2524 | 1 | 216 | 5 | ## Client diff --git a/api_docs/core_saved_objects.devdocs.json b/api_docs/core_saved_objects.devdocs.json index 7c494cf0fad8e4..86cf67bdb6a5cd 100644 --- a/api_docs/core_saved_objects.devdocs.json +++ b/api_docs/core_saved_objects.devdocs.json @@ -10,1181 +10,6 @@ }, "server": { "classes": [ - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsErrorHelpers", - "type": "Class", - "tags": [], - "label": "SavedObjectsErrorHelpers", - "description": [], - "path": "src/core/server/saved_objects/service/lib/errors.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsErrorHelpers.isSavedObjectsClientError", - "type": "Function", - "tags": [], - "label": "isSavedObjectsClientError", - "description": [], - "signature": [ - "(error: any) => error is ", - "DecoratedError" - ], - "path": "src/core/server/saved_objects/service/lib/errors.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsErrorHelpers.isSavedObjectsClientError.$1", - "type": "Any", - "tags": [], - "label": "error", - "description": [], - "signature": [ - "any" - ], - "path": "src/core/server/saved_objects/service/lib/errors.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [] - }, - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsErrorHelpers.decorateBadRequestError", - "type": "Function", - "tags": [], - "label": "decorateBadRequestError", - "description": [], - "signature": [ - "(error: Error, reason?: string | undefined) => ", - "DecoratedError" - ], - "path": "src/core/server/saved_objects/service/lib/errors.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsErrorHelpers.decorateBadRequestError.$1", - "type": "Object", - "tags": [], - "label": "error", - "description": [], - "signature": [ - "Error" - ], - "path": "src/core/server/saved_objects/service/lib/errors.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsErrorHelpers.decorateBadRequestError.$2", - "type": "string", - "tags": [], - "label": "reason", - "description": [], - "signature": [ - "string | undefined" - ], - "path": "src/core/server/saved_objects/service/lib/errors.ts", - "deprecated": false, - "isRequired": false - } - ], - "returnComment": [] - }, - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsErrorHelpers.createBadRequestError", - "type": "Function", - "tags": [], - "label": "createBadRequestError", - "description": [], - "signature": [ - "(reason?: string | undefined) => ", - "DecoratedError" - ], - "path": "src/core/server/saved_objects/service/lib/errors.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsErrorHelpers.createBadRequestError.$1", - "type": "string", - "tags": [], - "label": "reason", - "description": [], - "signature": [ - "string | undefined" - ], - "path": "src/core/server/saved_objects/service/lib/errors.ts", - "deprecated": false, - "isRequired": false - } - ], - "returnComment": [] - }, - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsErrorHelpers.createUnsupportedTypeError", - "type": "Function", - "tags": [], - "label": "createUnsupportedTypeError", - "description": [], - "signature": [ - "(type: string) => ", - "DecoratedError" - ], - "path": "src/core/server/saved_objects/service/lib/errors.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsErrorHelpers.createUnsupportedTypeError.$1", - "type": "string", - "tags": [], - "label": "type", - "description": [], - "signature": [ - "string" - ], - "path": "src/core/server/saved_objects/service/lib/errors.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [] - }, - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsErrorHelpers.isBadRequestError", - "type": "Function", - "tags": [], - "label": "isBadRequestError", - "description": [], - "signature": [ - "(error: Error | ", - "DecoratedError", - ") => boolean" - ], - "path": "src/core/server/saved_objects/service/lib/errors.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsErrorHelpers.isBadRequestError.$1", - "type": "CompoundType", - "tags": [], - "label": "error", - "description": [], - "signature": [ - "Error | ", - "DecoratedError" - ], - "path": "src/core/server/saved_objects/service/lib/errors.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [] - }, - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsErrorHelpers.createInvalidVersionError", - "type": "Function", - "tags": [], - "label": "createInvalidVersionError", - "description": [], - "signature": [ - "(versionInput?: string | undefined) => ", - "DecoratedError" - ], - "path": "src/core/server/saved_objects/service/lib/errors.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsErrorHelpers.createInvalidVersionError.$1", - "type": "string", - "tags": [], - "label": "versionInput", - "description": [], - "signature": [ - "string | undefined" - ], - "path": "src/core/server/saved_objects/service/lib/errors.ts", - "deprecated": false, - "isRequired": false - } - ], - "returnComment": [] - }, - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsErrorHelpers.isInvalidVersionError", - "type": "Function", - "tags": [], - "label": "isInvalidVersionError", - "description": [], - "signature": [ - "(error: Error | ", - "DecoratedError", - ") => boolean" - ], - "path": "src/core/server/saved_objects/service/lib/errors.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsErrorHelpers.isInvalidVersionError.$1", - "type": "CompoundType", - "tags": [], - "label": "error", - "description": [], - "signature": [ - "Error | ", - "DecoratedError" - ], - "path": "src/core/server/saved_objects/service/lib/errors.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [] - }, - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsErrorHelpers.decorateNotAuthorizedError", - "type": "Function", - "tags": [], - "label": "decorateNotAuthorizedError", - "description": [], - "signature": [ - "(error: Error, reason?: string | undefined) => ", - "DecoratedError" - ], - "path": "src/core/server/saved_objects/service/lib/errors.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsErrorHelpers.decorateNotAuthorizedError.$1", - "type": "Object", - "tags": [], - "label": "error", - "description": [], - "signature": [ - "Error" - ], - "path": "src/core/server/saved_objects/service/lib/errors.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsErrorHelpers.decorateNotAuthorizedError.$2", - "type": "string", - "tags": [], - "label": "reason", - "description": [], - "signature": [ - "string | undefined" - ], - "path": "src/core/server/saved_objects/service/lib/errors.ts", - "deprecated": false, - "isRequired": false - } - ], - "returnComment": [] - }, - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsErrorHelpers.isNotAuthorizedError", - "type": "Function", - "tags": [], - "label": "isNotAuthorizedError", - "description": [], - "signature": [ - "(error: Error | ", - "DecoratedError", - ") => boolean" - ], - "path": "src/core/server/saved_objects/service/lib/errors.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsErrorHelpers.isNotAuthorizedError.$1", - "type": "CompoundType", - "tags": [], - "label": "error", - "description": [], - "signature": [ - "Error | ", - "DecoratedError" - ], - "path": "src/core/server/saved_objects/service/lib/errors.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [] - }, - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsErrorHelpers.decorateForbiddenError", - "type": "Function", - "tags": [], - "label": "decorateForbiddenError", - "description": [], - "signature": [ - "(error: Error, reason?: string | undefined) => ", - "DecoratedError" - ], - "path": "src/core/server/saved_objects/service/lib/errors.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsErrorHelpers.decorateForbiddenError.$1", - "type": "Object", - "tags": [], - "label": "error", - "description": [], - "signature": [ - "Error" - ], - "path": "src/core/server/saved_objects/service/lib/errors.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsErrorHelpers.decorateForbiddenError.$2", - "type": "string", - "tags": [], - "label": "reason", - "description": [], - "signature": [ - "string | undefined" - ], - "path": "src/core/server/saved_objects/service/lib/errors.ts", - "deprecated": false, - "isRequired": false - } - ], - "returnComment": [] - }, - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsErrorHelpers.isForbiddenError", - "type": "Function", - "tags": [], - "label": "isForbiddenError", - "description": [], - "signature": [ - "(error: Error | ", - "DecoratedError", - ") => boolean" - ], - "path": "src/core/server/saved_objects/service/lib/errors.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsErrorHelpers.isForbiddenError.$1", - "type": "CompoundType", - "tags": [], - "label": "error", - "description": [], - "signature": [ - "Error | ", - "DecoratedError" - ], - "path": "src/core/server/saved_objects/service/lib/errors.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [] - }, - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsErrorHelpers.decorateRequestEntityTooLargeError", - "type": "Function", - "tags": [], - "label": "decorateRequestEntityTooLargeError", - "description": [], - "signature": [ - "(error: Error, reason?: string | undefined) => ", - "DecoratedError" - ], - "path": "src/core/server/saved_objects/service/lib/errors.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsErrorHelpers.decorateRequestEntityTooLargeError.$1", - "type": "Object", - "tags": [], - "label": "error", - "description": [], - "signature": [ - "Error" - ], - "path": "src/core/server/saved_objects/service/lib/errors.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsErrorHelpers.decorateRequestEntityTooLargeError.$2", - "type": "string", - "tags": [], - "label": "reason", - "description": [], - "signature": [ - "string | undefined" - ], - "path": "src/core/server/saved_objects/service/lib/errors.ts", - "deprecated": false, - "isRequired": false - } - ], - "returnComment": [] - }, - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsErrorHelpers.isRequestEntityTooLargeError", - "type": "Function", - "tags": [], - "label": "isRequestEntityTooLargeError", - "description": [], - "signature": [ - "(error: Error | ", - "DecoratedError", - ") => boolean" - ], - "path": "src/core/server/saved_objects/service/lib/errors.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsErrorHelpers.isRequestEntityTooLargeError.$1", - "type": "CompoundType", - "tags": [], - "label": "error", - "description": [], - "signature": [ - "Error | ", - "DecoratedError" - ], - "path": "src/core/server/saved_objects/service/lib/errors.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [] - }, - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsErrorHelpers.createGenericNotFoundError", - "type": "Function", - "tags": [], - "label": "createGenericNotFoundError", - "description": [], - "signature": [ - "(type?: string | null, id?: string | null) => ", - "DecoratedError" - ], - "path": "src/core/server/saved_objects/service/lib/errors.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsErrorHelpers.createGenericNotFoundError.$1", - "type": "CompoundType", - "tags": [], - "label": "type", - "description": [], - "signature": [ - "string | null" - ], - "path": "src/core/server/saved_objects/service/lib/errors.ts", - "deprecated": false, - "isRequired": false - }, - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsErrorHelpers.createGenericNotFoundError.$2", - "type": "CompoundType", - "tags": [], - "label": "id", - "description": [], - "signature": [ - "string | null" - ], - "path": "src/core/server/saved_objects/service/lib/errors.ts", - "deprecated": false, - "isRequired": false - } - ], - "returnComment": [] - }, - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsErrorHelpers.createIndexAliasNotFoundError", - "type": "Function", - "tags": [], - "label": "createIndexAliasNotFoundError", - "description": [], - "signature": [ - "(alias: string) => ", - "DecoratedError" - ], - "path": "src/core/server/saved_objects/service/lib/errors.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsErrorHelpers.createIndexAliasNotFoundError.$1", - "type": "string", - "tags": [], - "label": "alias", - "description": [], - "signature": [ - "string" - ], - "path": "src/core/server/saved_objects/service/lib/errors.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [] - }, - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsErrorHelpers.decorateIndexAliasNotFoundError", - "type": "Function", - "tags": [], - "label": "decorateIndexAliasNotFoundError", - "description": [], - "signature": [ - "(error: Error, alias: string) => ", - "DecoratedError" - ], - "path": "src/core/server/saved_objects/service/lib/errors.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsErrorHelpers.decorateIndexAliasNotFoundError.$1", - "type": "Object", - "tags": [], - "label": "error", - "description": [], - "signature": [ - "Error" - ], - "path": "src/core/server/saved_objects/service/lib/errors.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsErrorHelpers.decorateIndexAliasNotFoundError.$2", - "type": "string", - "tags": [], - "label": "alias", - "description": [], - "signature": [ - "string" - ], - "path": "src/core/server/saved_objects/service/lib/errors.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [] - }, - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsErrorHelpers.isNotFoundError", - "type": "Function", - "tags": [], - "label": "isNotFoundError", - "description": [], - "signature": [ - "(error: Error | ", - "DecoratedError", - ") => boolean" - ], - "path": "src/core/server/saved_objects/service/lib/errors.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsErrorHelpers.isNotFoundError.$1", - "type": "CompoundType", - "tags": [], - "label": "error", - "description": [], - "signature": [ - "Error | ", - "DecoratedError" - ], - "path": "src/core/server/saved_objects/service/lib/errors.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [] - }, - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsErrorHelpers.decorateConflictError", - "type": "Function", - "tags": [], - "label": "decorateConflictError", - "description": [], - "signature": [ - "(error: Error, reason?: string | undefined) => ", - "DecoratedError" - ], - "path": "src/core/server/saved_objects/service/lib/errors.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsErrorHelpers.decorateConflictError.$1", - "type": "Object", - "tags": [], - "label": "error", - "description": [], - "signature": [ - "Error" - ], - "path": "src/core/server/saved_objects/service/lib/errors.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsErrorHelpers.decorateConflictError.$2", - "type": "string", - "tags": [], - "label": "reason", - "description": [], - "signature": [ - "string | undefined" - ], - "path": "src/core/server/saved_objects/service/lib/errors.ts", - "deprecated": false, - "isRequired": false - } - ], - "returnComment": [] - }, - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsErrorHelpers.createConflictError", - "type": "Function", - "tags": [], - "label": "createConflictError", - "description": [], - "signature": [ - "(type: string, id: string, reason?: string | undefined) => ", - "DecoratedError" - ], - "path": "src/core/server/saved_objects/service/lib/errors.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsErrorHelpers.createConflictError.$1", - "type": "string", - "tags": [], - "label": "type", - "description": [], - "signature": [ - "string" - ], - "path": "src/core/server/saved_objects/service/lib/errors.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsErrorHelpers.createConflictError.$2", - "type": "string", - "tags": [], - "label": "id", - "description": [], - "signature": [ - "string" - ], - "path": "src/core/server/saved_objects/service/lib/errors.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsErrorHelpers.createConflictError.$3", - "type": "string", - "tags": [], - "label": "reason", - "description": [], - "signature": [ - "string | undefined" - ], - "path": "src/core/server/saved_objects/service/lib/errors.ts", - "deprecated": false, - "isRequired": false - } - ], - "returnComment": [] - }, - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsErrorHelpers.isConflictError", - "type": "Function", - "tags": [], - "label": "isConflictError", - "description": [], - "signature": [ - "(error: Error | ", - "DecoratedError", - ") => boolean" - ], - "path": "src/core/server/saved_objects/service/lib/errors.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsErrorHelpers.isConflictError.$1", - "type": "CompoundType", - "tags": [], - "label": "error", - "description": [], - "signature": [ - "Error | ", - "DecoratedError" - ], - "path": "src/core/server/saved_objects/service/lib/errors.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [] - }, - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsErrorHelpers.decorateTooManyRequestsError", - "type": "Function", - "tags": [], - "label": "decorateTooManyRequestsError", - "description": [], - "signature": [ - "(error: Error, reason?: string | undefined) => ", - "DecoratedError" - ], - "path": "src/core/server/saved_objects/service/lib/errors.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsErrorHelpers.decorateTooManyRequestsError.$1", - "type": "Object", - "tags": [], - "label": "error", - "description": [], - "signature": [ - "Error" - ], - "path": "src/core/server/saved_objects/service/lib/errors.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsErrorHelpers.decorateTooManyRequestsError.$2", - "type": "string", - "tags": [], - "label": "reason", - "description": [], - "signature": [ - "string | undefined" - ], - "path": "src/core/server/saved_objects/service/lib/errors.ts", - "deprecated": false, - "isRequired": false - } - ], - "returnComment": [] - }, - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsErrorHelpers.createTooManyRequestsError", - "type": "Function", - "tags": [], - "label": "createTooManyRequestsError", - "description": [], - "signature": [ - "(type: string, id: string) => ", - "DecoratedError" - ], - "path": "src/core/server/saved_objects/service/lib/errors.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsErrorHelpers.createTooManyRequestsError.$1", - "type": "string", - "tags": [], - "label": "type", - "description": [], - "signature": [ - "string" - ], - "path": "src/core/server/saved_objects/service/lib/errors.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsErrorHelpers.createTooManyRequestsError.$2", - "type": "string", - "tags": [], - "label": "id", - "description": [], - "signature": [ - "string" - ], - "path": "src/core/server/saved_objects/service/lib/errors.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [] - }, - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsErrorHelpers.isTooManyRequestsError", - "type": "Function", - "tags": [], - "label": "isTooManyRequestsError", - "description": [], - "signature": [ - "(error: Error | ", - "DecoratedError", - ") => boolean" - ], - "path": "src/core/server/saved_objects/service/lib/errors.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsErrorHelpers.isTooManyRequestsError.$1", - "type": "CompoundType", - "tags": [], - "label": "error", - "description": [], - "signature": [ - "Error | ", - "DecoratedError" - ], - "path": "src/core/server/saved_objects/service/lib/errors.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [] - }, - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsErrorHelpers.decorateEsCannotExecuteScriptError", - "type": "Function", - "tags": [], - "label": "decorateEsCannotExecuteScriptError", - "description": [], - "signature": [ - "(error: Error, reason?: string | undefined) => ", - "DecoratedError" - ], - "path": "src/core/server/saved_objects/service/lib/errors.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsErrorHelpers.decorateEsCannotExecuteScriptError.$1", - "type": "Object", - "tags": [], - "label": "error", - "description": [], - "signature": [ - "Error" - ], - "path": "src/core/server/saved_objects/service/lib/errors.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsErrorHelpers.decorateEsCannotExecuteScriptError.$2", - "type": "string", - "tags": [], - "label": "reason", - "description": [], - "signature": [ - "string | undefined" - ], - "path": "src/core/server/saved_objects/service/lib/errors.ts", - "deprecated": false, - "isRequired": false - } - ], - "returnComment": [] - }, - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsErrorHelpers.isEsCannotExecuteScriptError", - "type": "Function", - "tags": [], - "label": "isEsCannotExecuteScriptError", - "description": [], - "signature": [ - "(error: Error | ", - "DecoratedError", - ") => boolean" - ], - "path": "src/core/server/saved_objects/service/lib/errors.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsErrorHelpers.isEsCannotExecuteScriptError.$1", - "type": "CompoundType", - "tags": [], - "label": "error", - "description": [], - "signature": [ - "Error | ", - "DecoratedError" - ], - "path": "src/core/server/saved_objects/service/lib/errors.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [] - }, - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsErrorHelpers.decorateEsUnavailableError", - "type": "Function", - "tags": [], - "label": "decorateEsUnavailableError", - "description": [], - "signature": [ - "(error: Error, reason?: string | undefined) => ", - "DecoratedError" - ], - "path": "src/core/server/saved_objects/service/lib/errors.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsErrorHelpers.decorateEsUnavailableError.$1", - "type": "Object", - "tags": [], - "label": "error", - "description": [], - "signature": [ - "Error" - ], - "path": "src/core/server/saved_objects/service/lib/errors.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsErrorHelpers.decorateEsUnavailableError.$2", - "type": "string", - "tags": [], - "label": "reason", - "description": [], - "signature": [ - "string | undefined" - ], - "path": "src/core/server/saved_objects/service/lib/errors.ts", - "deprecated": false, - "isRequired": false - } - ], - "returnComment": [] - }, - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsErrorHelpers.isEsUnavailableError", - "type": "Function", - "tags": [], - "label": "isEsUnavailableError", - "description": [], - "signature": [ - "(error: Error | ", - "DecoratedError", - ") => boolean" - ], - "path": "src/core/server/saved_objects/service/lib/errors.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsErrorHelpers.isEsUnavailableError.$1", - "type": "CompoundType", - "tags": [], - "label": "error", - "description": [], - "signature": [ - "Error | ", - "DecoratedError" - ], - "path": "src/core/server/saved_objects/service/lib/errors.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [] - }, - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsErrorHelpers.decorateGeneralError", - "type": "Function", - "tags": [], - "label": "decorateGeneralError", - "description": [], - "signature": [ - "(error: Error, reason?: string | undefined) => ", - "DecoratedError" - ], - "path": "src/core/server/saved_objects/service/lib/errors.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsErrorHelpers.decorateGeneralError.$1", - "type": "Object", - "tags": [], - "label": "error", - "description": [], - "signature": [ - "Error" - ], - "path": "src/core/server/saved_objects/service/lib/errors.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsErrorHelpers.decorateGeneralError.$2", - "type": "string", - "tags": [], - "label": "reason", - "description": [], - "signature": [ - "string | undefined" - ], - "path": "src/core/server/saved_objects/service/lib/errors.ts", - "deprecated": false, - "isRequired": false - } - ], - "returnComment": [] - }, - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsErrorHelpers.isGeneralError", - "type": "Function", - "tags": [], - "label": "isGeneralError", - "description": [], - "signature": [ - "(error: Error | ", - "DecoratedError", - ") => boolean" - ], - "path": "src/core/server/saved_objects/service/lib/errors.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsErrorHelpers.isGeneralError.$1", - "type": "CompoundType", - "tags": [], - "label": "error", - "description": [], - "signature": [ - "Error | ", - "DecoratedError" - ], - "path": "src/core/server/saved_objects/service/lib/errors.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [] - }, - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsErrorHelpers.createGenericNotFoundEsUnavailableError", - "type": "Function", - "tags": [], - "label": "createGenericNotFoundEsUnavailableError", - "description": [], - "signature": [ - "(type?: string | null, id?: string | null) => ", - "DecoratedError" - ], - "path": "src/core/server/saved_objects/service/lib/errors.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsErrorHelpers.createGenericNotFoundEsUnavailableError.$1", - "type": "CompoundType", - "tags": [], - "label": "type", - "description": [], - "signature": [ - "string | null" - ], - "path": "src/core/server/saved_objects/service/lib/errors.ts", - "deprecated": false, - "isRequired": false - }, - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsErrorHelpers.createGenericNotFoundEsUnavailableError.$2", - "type": "CompoundType", - "tags": [], - "label": "id", - "description": [], - "signature": [ - "string | null" - ], - "path": "src/core/server/saved_objects/service/lib/errors.ts", - "deprecated": false, - "isRequired": false - } - ], - "returnComment": [] - } - ], - "initialIsOpen": false - }, { "parentPluginId": "core", "id": "def-server.SavedObjectsExportError", @@ -2791,300 +1616,9 @@ } ], "initialIsOpen": false - }, - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsUtils", - "type": "Class", - "tags": [], - "label": "SavedObjectsUtils", - "description": [], - "path": "src/core/server/saved_objects/service/lib/utils.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsUtils.namespaceIdToString", - "type": "Function", - "tags": [], - "label": "namespaceIdToString", - "description": [ - "\nConverts a given saved object namespace ID to its string representation. All namespace IDs have an identical string representation, with\nthe exception of the `undefined` namespace ID (which has a namespace string of `'default'`).\n" - ], - "signature": [ - "(namespace?: string | undefined) => string" - ], - "path": "src/core/server/saved_objects/service/lib/utils.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsUtils.namespaceIdToString.$1", - "type": "string", - "tags": [], - "label": "namespace", - "description": [ - "The namespace ID, which must be either a non-empty string or `undefined`." - ], - "signature": [ - "string | undefined" - ], - "path": "src/core/server/saved_objects/service/lib/utils.ts", - "deprecated": false, - "isRequired": false - } - ], - "returnComment": [] - }, - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsUtils.namespaceStringToId", - "type": "Function", - "tags": [], - "label": "namespaceStringToId", - "description": [ - "\nConverts a given saved object namespace string to its ID representation. All namespace strings have an identical ID representation, with\nthe exception of the `'default'` namespace string (which has a namespace ID of `undefined`).\n" - ], - "signature": [ - "(namespace: string) => string | undefined" - ], - "path": "src/core/server/saved_objects/service/lib/utils.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsUtils.namespaceStringToId.$1", - "type": "string", - "tags": [], - "label": "namespace", - "description": [ - "The namespace string, which must be non-empty." - ], - "signature": [ - "string" - ], - "path": "src/core/server/saved_objects/service/lib/utils.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [] - }, - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsUtils.createEmptyFindResponse", - "type": "Function", - "tags": [], - "label": "createEmptyFindResponse", - "description": [ - "\nCreates an empty response for a find operation. This is only intended to be used by saved objects client wrappers." - ], - "signature": [ - "({ page, perPage, }: ", - "SavedObjectsFindOptions", - ") => ", - "SavedObjectsFindResponse", - "" - ], - "path": "src/core/server/saved_objects/service/lib/utils.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsUtils.createEmptyFindResponse.$1", - "type": "Object", - "tags": [], - "label": "{\n page = FIND_DEFAULT_PAGE,\n perPage = FIND_DEFAULT_PER_PAGE,\n }", - "description": [], - "signature": [ - "SavedObjectsFindOptions" - ], - "path": "src/core/server/saved_objects/service/lib/utils.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [] - }, - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsUtils.generateId", - "type": "Function", - "tags": [], - "label": "generateId", - "description": [ - "\nGenerates a random ID for a saved objects." - ], - "signature": [ - "() => string" - ], - "path": "src/core/server/saved_objects/service/lib/utils.ts", - "deprecated": false, - "children": [], - "returnComment": [] - }, - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsUtils.isRandomId", - "type": "Function", - "tags": [ - "todo" - ], - "label": "isRandomId", - "description": [ - "\nValidates that a saved object ID has been randomly generated.\n" - ], - "signature": [ - "(id: string | undefined) => boolean" - ], - "path": "src/core/server/saved_objects/service/lib/utils.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsUtils.isRandomId.$1", - "type": "string", - "tags": [], - "label": "id", - "description": [ - "The ID of a saved object." - ], - "signature": [ - "string | undefined" - ], - "path": "src/core/server/saved_objects/service/lib/utils.ts", - "deprecated": false, - "isRequired": false - } - ], - "returnComment": [] - }, - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsUtils.getConvertedObjectId", - "type": "Function", - "tags": [], - "label": "getConvertedObjectId", - "description": [ - "\nUses a single-namespace object's \"legacy ID\" to determine what its new ID will be after it is converted to a multi-namespace type.\n" - ], - "signature": [ - "(namespace: string | undefined, type: string, id: string) => string" - ], - "path": "src/core/server/saved_objects/service/lib/utils.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsUtils.getConvertedObjectId.$1", - "type": "string", - "tags": [], - "label": "namespace", - "description": [ - "The namespace of the saved object before it is converted." - ], - "signature": [ - "string | undefined" - ], - "path": "src/core/server/saved_objects/service/lib/utils.ts", - "deprecated": false, - "isRequired": false - }, - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsUtils.getConvertedObjectId.$2", - "type": "string", - "tags": [], - "label": "type", - "description": [ - "The type of the saved object before it is converted." - ], - "signature": [ - "string" - ], - "path": "src/core/server/saved_objects/service/lib/utils.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "core", - "id": "def-server.SavedObjectsUtils.getConvertedObjectId.$3", - "type": "string", - "tags": [], - "label": "id", - "description": [ - "The ID of the saved object before it is converted." - ], - "signature": [ - "string" - ], - "path": "src/core/server/saved_objects/service/lib/utils.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [ - "The ID of the saved object after it is converted." - ] - } - ], - "initialIsOpen": false - } - ], - "functions": [ - { - "parentPluginId": "core", - "id": "def-server.mergeSavedObjectMigrationMaps", - "type": "Function", - "tags": [], - "label": "mergeSavedObjectMigrationMaps", - "description": [ - "\nMerges two saved object migration maps.\n\nIf there is a migration for a given version on only one of the maps,\nthat migration function will be used:\n\nmergeSavedObjectMigrationMaps({ '1.2.3': f }, { '4.5.6': g }) -> { '1.2.3': f, '4.5.6': g }\n\nIf there is a migration for a given version on both maps, the migrations will be composed:\n\nmergeSavedObjectMigrationMaps({ '1.2.3': f }, { '1.2.3': g }) -> { '1.2.3': (doc, context) => f(g(doc, context), context) }\n" - ], - "signature": [ - "(map1: ", - "SavedObjectMigrationMap", - ", map2: ", - "SavedObjectMigrationMap", - ") => ", - "SavedObjectMigrationMap" - ], - "path": "src/core/server/saved_objects/migrations/utils.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "core", - "id": "def-server.mergeSavedObjectMigrationMaps.$1", - "type": "Object", - "tags": [], - "label": "map1", - "description": [], - "signature": [ - "SavedObjectMigrationMap" - ], - "path": "src/core/server/saved_objects/migrations/utils.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "core", - "id": "def-server.mergeSavedObjectMigrationMaps.$2", - "type": "Object", - "tags": [], - "label": "map2", - "description": [], - "signature": [ - "SavedObjectMigrationMap" - ], - "path": "src/core/server/saved_objects/migrations/utils.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [], - "initialIsOpen": false } ], + "functions": [], "interfaces": [], "enums": [], "misc": [], diff --git a/api_docs/core_saved_objects.mdx b/api_docs/core_saved_objects.mdx index 4fdd33a0e9c16f..0e2f18cae3890c 100644 --- a/api_docs/core_saved_objects.mdx +++ b/api_docs/core_saved_objects.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/core-savedObjects title: "core.savedObjects" image: https://source.unsplash.com/400x175/?github description: API docs for the core.savedObjects plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'core.savedObjects'] --- import coreSavedObjectsObj from './core_saved_objects.devdocs.json'; @@ -21,13 +21,10 @@ Contact [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) for que | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 2524 | 2 | 296 | 6 | +| 2524 | 1 | 216 | 5 | ## Server -### Functions - - ### Classes diff --git a/api_docs/custom_integrations.devdocs.json b/api_docs/custom_integrations.devdocs.json index c6b9ecd132fea1..a56430796e3248 100644 --- a/api_docs/custom_integrations.devdocs.json +++ b/api_docs/custom_integrations.devdocs.json @@ -413,7 +413,7 @@ "label": "shipper", "description": [], "signature": [ - "\"other\" | \"beats\" | \"enterprise_search\" | \"language_clients\" | \"sample_data\" | \"tests\" | \"tutorial\" | \"placeholders\"" + "\"beats\" | \"enterprise_search\" | \"language_clients\" | \"other\" | \"sample_data\" | \"tests\" | \"tutorial\" | \"placeholders\"" ], "path": "src/plugins/custom_integrations/common/index.ts", "deprecated": false @@ -685,7 +685,7 @@ "label": "shipper", "description": [], "signature": [ - "\"other\" | \"beats\" | \"enterprise_search\" | \"language_clients\" | \"sample_data\" | \"tests\" | \"tutorial\" | \"placeholders\"" + "\"beats\" | \"enterprise_search\" | \"language_clients\" | \"other\" | \"sample_data\" | \"tests\" | \"tutorial\" | \"placeholders\"" ], "path": "src/plugins/custom_integrations/common/index.ts", "deprecated": false @@ -877,7 +877,7 @@ "\nThe list of all known shippers." ], "signature": [ - "(\"other\" | \"beats\" | \"enterprise_search\" | \"language_clients\" | \"sample_data\" | \"tests\" | \"tutorial\" | \"placeholders\")[]" + "(\"beats\" | \"enterprise_search\" | \"language_clients\" | \"other\" | \"sample_data\" | \"tests\" | \"tutorial\" | \"placeholders\")[]" ], "path": "src/plugins/custom_integrations/common/index.ts", "deprecated": false, @@ -893,7 +893,7 @@ "\nA shipper-- an internal or external system capable of storing data in ES/Kibana-- applicable to an Integration." ], "signature": [ - "\"other\" | \"beats\" | \"enterprise_search\" | \"language_clients\" | \"sample_data\" | \"tests\" | \"tutorial\" | \"placeholders\"" + "\"beats\" | \"enterprise_search\" | \"language_clients\" | \"other\" | \"sample_data\" | \"tests\" | \"tutorial\" | \"placeholders\"" ], "path": "src/plugins/custom_integrations/common/index.ts", "deprecated": false, diff --git a/api_docs/custom_integrations.mdx b/api_docs/custom_integrations.mdx index b2822593f7ce19..f0cddac0ac65fb 100644 --- a/api_docs/custom_integrations.mdx +++ b/api_docs/custom_integrations.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/customIntegrations title: "customIntegrations" image: https://source.unsplash.com/400x175/?github description: API docs for the customIntegrations plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'customIntegrations'] --- import customIntegrationsObj from './custom_integrations.devdocs.json'; diff --git a/api_docs/dashboard.devdocs.json b/api_docs/dashboard.devdocs.json index 01decee7cd29bb..32fc71a5d5c4c9 100644 --- a/api_docs/dashboard.devdocs.json +++ b/api_docs/dashboard.devdocs.json @@ -2190,7 +2190,7 @@ "section": "def-common.RawSavedDashboardPanel730ToLatest", "text": "RawSavedDashboardPanel730ToLatest" }, - ", \"type\" | \"version\" | \"title\" | \"panelIndex\" | \"gridData\" | \"embeddableConfig\" | \"panelRefName\"> & { readonly id?: string | undefined; readonly type: string; }" + ", \"type\" | \"title\" | \"panelIndex\" | \"gridData\" | \"version\" | \"embeddableConfig\" | \"panelRefName\"> & { readonly id?: string | undefined; readonly type: string; }" ], "path": "src/plugins/dashboard/common/types.ts", "deprecated": false, @@ -2849,7 +2849,7 @@ "signature": [ "Pick<", "RawSavedDashboardPanel640To720", - ", \"version\" | \"title\" | \"panelIndex\" | \"gridData\" | \"embeddableConfig\"> & { readonly type?: string | undefined; readonly name?: string | undefined; panelIndex: string; panelRefName?: string | undefined; }" + ", \"title\" | \"panelIndex\" | \"gridData\" | \"version\" | \"embeddableConfig\"> & { readonly type?: string | undefined; readonly name?: string | undefined; panelIndex: string; panelRefName?: string | undefined; }" ], "path": "src/plugins/dashboard/common/bwc/types.ts", "deprecated": false, @@ -2865,7 +2865,7 @@ "signature": [ "Pick<", "RawSavedDashboardPanel610", - ", \"version\" | \"title\" | \"columns\" | \"sort\" | \"panelIndex\" | \"gridData\"> & { readonly id: string; readonly type: string; }" + ", \"columns\" | \"title\" | \"sort\" | \"panelIndex\" | \"gridData\" | \"version\"> & { readonly id: string; readonly type: string; }" ], "path": "src/plugins/dashboard/common/types.ts", "deprecated": false, @@ -2881,7 +2881,7 @@ "signature": [ "Pick<", "RawSavedDashboardPanel620", - ", \"version\" | \"title\" | \"columns\" | \"sort\" | \"panelIndex\" | \"gridData\" | \"embeddableConfig\"> & { readonly id: string; readonly type: string; }" + ", \"columns\" | \"title\" | \"sort\" | \"panelIndex\" | \"gridData\" | \"version\" | \"embeddableConfig\"> & { readonly id: string; readonly type: string; }" ], "path": "src/plugins/dashboard/common/types.ts", "deprecated": false, @@ -2897,7 +2897,7 @@ "signature": [ "Pick<", "RawSavedDashboardPanel620", - ", \"version\" | \"title\" | \"columns\" | \"sort\" | \"panelIndex\" | \"gridData\" | \"embeddableConfig\"> & { readonly id: string; readonly type: string; }" + ", \"columns\" | \"title\" | \"sort\" | \"panelIndex\" | \"gridData\" | \"version\" | \"embeddableConfig\"> & { readonly id: string; readonly type: string; }" ], "path": "src/plugins/dashboard/common/types.ts", "deprecated": false, @@ -2913,7 +2913,7 @@ "signature": [ "Pick<", "RawSavedDashboardPanel640To720", - ", \"version\" | \"title\" | \"panelIndex\" | \"gridData\" | \"embeddableConfig\"> & { readonly id: string; readonly type: string; }" + ", \"title\" | \"panelIndex\" | \"gridData\" | \"version\" | \"embeddableConfig\"> & { readonly id: string; readonly type: string; }" ], "path": "src/plugins/dashboard/common/types.ts", "deprecated": false, @@ -2935,7 +2935,7 @@ "section": "def-common.RawSavedDashboardPanel730ToLatest", "text": "RawSavedDashboardPanel730ToLatest" }, - ", \"type\" | \"version\" | \"title\" | \"panelIndex\" | \"gridData\" | \"embeddableConfig\" | \"panelRefName\"> & { readonly id?: string | undefined; readonly type: string; }" + ", \"type\" | \"title\" | \"panelIndex\" | \"gridData\" | \"version\" | \"embeddableConfig\" | \"panelRefName\"> & { readonly id?: string | undefined; readonly type: string; }" ], "path": "src/plugins/dashboard/common/types.ts", "deprecated": false, @@ -2951,7 +2951,7 @@ "signature": [ "Pick<", "RawSavedDashboardPanelTo60", - ", \"title\" | \"row\" | \"columns\" | \"sort\" | \"size_x\" | \"size_y\" | \"col\" | \"panelIndex\"> & { readonly id: string; readonly type: string; }" + ", \"columns\" | \"title\" | \"sort\" | \"size_x\" | \"size_y\" | \"row\" | \"col\" | \"panelIndex\"> & { readonly id: string; readonly type: string; }" ], "path": "src/plugins/dashboard/common/types.ts", "deprecated": false, diff --git a/api_docs/dashboard.mdx b/api_docs/dashboard.mdx index 58bc34730efd42..4b2bf436b05d67 100644 --- a/api_docs/dashboard.mdx +++ b/api_docs/dashboard.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dashboard title: "dashboard" image: https://source.unsplash.com/400x175/?github description: API docs for the dashboard plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dashboard'] --- import dashboardObj from './dashboard.devdocs.json'; diff --git a/api_docs/dashboard_enhanced.mdx b/api_docs/dashboard_enhanced.mdx index 72d182930d118e..4e4d46e806b20f 100644 --- a/api_docs/dashboard_enhanced.mdx +++ b/api_docs/dashboard_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dashboardEnhanced title: "dashboardEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the dashboardEnhanced plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dashboardEnhanced'] --- import dashboardEnhancedObj from './dashboard_enhanced.devdocs.json'; diff --git a/api_docs/data.devdocs.json b/api_docs/data.devdocs.json index 80cc604dd10147..92bb53862bd102 100644 --- a/api_docs/data.devdocs.json +++ b/api_docs/data.devdocs.json @@ -10634,6 +10634,42 @@ ], "path": "src/plugins/data/public/index.ts", "deprecated": false + }, + { + "parentPluginId": "data", + "id": "def-public.search.aggs.calcAutoIntervalLessThan", + "type": "Function", + "tags": [], + "label": "calcAutoIntervalLessThan", + "description": [], + "signature": [ + "(maxBucketCount: number, duration: number) => moment.Duration" + ], + "path": "src/plugins/data/public/index.ts", + "deprecated": false, + "returnComment": [], + "children": [ + { + "parentPluginId": "data", + "id": "def-public.search.aggs.calcAutoIntervalLessThan.$1", + "type": "number", + "tags": [], + "label": "maxBucketCount", + "description": [], + "path": "src/plugins/data/common/search/aggs/buckets/lib/time_buckets/calc_auto_interval.ts", + "deprecated": false + }, + { + "parentPluginId": "data", + "id": "def-public.search.aggs.calcAutoIntervalLessThan.$2", + "type": "number", + "tags": [], + "label": "duration", + "description": [], + "path": "src/plugins/data/common/search/aggs/buckets/lib/time_buckets/calc_auto_interval.ts", + "deprecated": false + } + ] } ] }, @@ -14907,7 +14943,9 @@ "TransportRequestOptions", " | undefined): Promise<", "WriteResponseBase", - ">; }; name: string | symbol; transform: ", + ">; }; cluster: ", + "default", + "; eql: ", "default", "; search: { >; }; cluster: ", - "default", - "; eql: ", - "default", - "; create: { (this: That, params: ", + ">; }; create: { (this: That, params: ", "CreateRequest", " | ", "CreateRequest", @@ -14975,7 +15009,7 @@ "default", "; security: ", "default", - "; index: { (this: That, params: ", + "; name: string | symbol; index: { (this: That, params: ", "IndexRequest", " | ", "IndexRequest", @@ -15987,6 +16021,8 @@ "TermvectorsResponse", ">; }; textStructure: ", "default", + "; transform: ", + "default", "; updateByQuery: { (this: That, params: ", "UpdateByQueryRequest", " | ", diff --git a/api_docs/data.mdx b/api_docs/data.mdx index cfb72e2b9103ff..f266b7d279837e 100644 --- a/api_docs/data.mdx +++ b/api_docs/data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/data title: "data" image: https://source.unsplash.com/400x175/?github description: API docs for the data plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data'] --- import dataObj from './data.devdocs.json'; @@ -21,7 +21,7 @@ Contact [App Services](https://github.com/orgs/elastic/teams/kibana-app-services | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 3114 | 34 | 2428 | 22 | +| 3117 | 34 | 2431 | 22 | ## Client diff --git a/api_docs/data_query.mdx b/api_docs/data_query.mdx index 75626239d1244c..f3955f42792978 100644 --- a/api_docs/data_query.mdx +++ b/api_docs/data_query.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/data-query title: "data.query" image: https://source.unsplash.com/400x175/?github description: API docs for the data.query plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data.query'] --- import dataQueryObj from './data_query.devdocs.json'; @@ -21,7 +21,7 @@ Contact [App Services](https://github.com/orgs/elastic/teams/kibana-app-services | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 3114 | 34 | 2428 | 22 | +| 3117 | 34 | 2431 | 22 | ## Client diff --git a/api_docs/data_search.devdocs.json b/api_docs/data_search.devdocs.json index d7615605097df2..6d60b92265a0fe 100644 --- a/api_docs/data_search.devdocs.json +++ b/api_docs/data_search.devdocs.json @@ -2720,9 +2720,9 @@ "label": "options", "description": [], "signature": [ - "{ filter?: any; search?: string | undefined; page?: number | undefined; aggs?: Record | undefined; fields?: string[] | undefined; searchAfter?: string[] | undefined; perPage?: number | undefined; sortField?: string | undefined; sortOrder?: ", + "> | undefined; fields?: string[] | undefined; searchAfter?: string[] | undefined; page?: number | undefined; perPage?: number | undefined; sortField?: string | undefined; sortOrder?: ", "SortOrder", " | undefined; searchFields?: string[] | undefined; rootSearchFields?: string[] | undefined; hasReference?: ", "SavedObjectsFindOptionsReference", @@ -20481,7 +20481,7 @@ "label": "aggregate", "description": [], "signature": [ - "\"min\" | \"max\" | \"sum\" | \"concat\" | \"average\"" + "\"min\" | \"max\" | \"sum\" | \"average\" | \"concat\"" ], "path": "src/plugins/data/common/search/aggs/metrics/top_hit.ts", "deprecated": false @@ -28641,7 +28641,7 @@ "label": "GeoPoint", "description": [], "signature": [ - "string | [number, number] | Point" + "string | Point | [number, number]" ], "path": "src/plugins/data/common/search/expressions/geo_point.ts", "deprecated": false, diff --git a/api_docs/data_search.mdx b/api_docs/data_search.mdx index fd2354a07bc44d..deff066a8484f8 100644 --- a/api_docs/data_search.mdx +++ b/api_docs/data_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/data-search title: "data.search" image: https://source.unsplash.com/400x175/?github description: API docs for the data.search plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data.search'] --- import dataSearchObj from './data_search.devdocs.json'; @@ -21,7 +21,7 @@ Contact [App Services](https://github.com/orgs/elastic/teams/kibana-app-services | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 3114 | 34 | 2428 | 22 | +| 3117 | 34 | 2431 | 22 | ## Client diff --git a/api_docs/data_view_editor.mdx b/api_docs/data_view_editor.mdx index f38ea346a52bf0..a5a29825db2755 100644 --- a/api_docs/data_view_editor.mdx +++ b/api_docs/data_view_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViewEditor title: "dataViewEditor" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViewEditor plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViewEditor'] --- import dataViewEditorObj from './data_view_editor.devdocs.json'; diff --git a/api_docs/data_view_field_editor.mdx b/api_docs/data_view_field_editor.mdx index d4c712b6881718..fd560d635697ed 100644 --- a/api_docs/data_view_field_editor.mdx +++ b/api_docs/data_view_field_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViewFieldEditor title: "dataViewFieldEditor" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViewFieldEditor plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViewFieldEditor'] --- import dataViewFieldEditorObj from './data_view_field_editor.devdocs.json'; diff --git a/api_docs/data_view_management.mdx b/api_docs/data_view_management.mdx index 05ed050eca7831..064fa51e86e667 100644 --- a/api_docs/data_view_management.mdx +++ b/api_docs/data_view_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViewManagement title: "dataViewManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViewManagement plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViewManagement'] --- import dataViewManagementObj from './data_view_management.devdocs.json'; diff --git a/api_docs/data_views.devdocs.json b/api_docs/data_views.devdocs.json index 5f33a31588605b..8dd55e506010a0 100644 --- a/api_docs/data_views.devdocs.json +++ b/api_docs/data_views.devdocs.json @@ -10910,7 +10910,9 @@ "TransportRequestOptions", " | undefined): Promise<", "WriteResponseBase", - ">; }; name: string | symbol; transform: ", + ">; }; cluster: ", + "default", + "; eql: ", "default", "; search: { >; }; cluster: ", - "default", - "; eql: ", - "default", - "; create: { (this: That, params: ", + ">; }; create: { (this: That, params: ", "CreateRequest", " | ", "CreateRequest", @@ -10978,7 +10976,7 @@ "default", "; security: ", "default", - "; index: { (this: That, params: ", + "; name: string | symbol; index: { (this: That, params: ", "IndexRequest", " | ", "IndexRequest", @@ -11990,6 +11988,8 @@ "TermvectorsResponse", ">; }; textStructure: ", "default", + "; transform: ", + "default", "; updateByQuery: { (this: That, params: ", "UpdateByQueryRequest", " | ", @@ -16549,7 +16549,7 @@ "signature": [ "Pick<", "Toast", - ", \"children\" | \"onError\" | \"color\" | \"className\" | \"lang\" | \"style\" | \"role\" | \"tabIndex\" | \"aria-activedescendant\" | \"aria-atomic\" | \"aria-autocomplete\" | \"aria-busy\" | \"aria-checked\" | \"aria-colcount\" | \"aria-colindex\" | \"aria-colspan\" | \"aria-controls\" | \"aria-current\" | \"aria-describedby\" | \"aria-details\" | \"aria-disabled\" | \"aria-dropeffect\" | \"aria-errormessage\" | \"aria-expanded\" | \"aria-flowto\" | \"aria-grabbed\" | \"aria-haspopup\" | \"aria-hidden\" | \"aria-invalid\" | \"aria-keyshortcuts\" | \"aria-label\" | \"aria-labelledby\" | \"aria-level\" | \"aria-live\" | \"aria-modal\" | \"aria-multiline\" | \"aria-multiselectable\" | \"aria-orientation\" | \"aria-owns\" | \"aria-placeholder\" | \"aria-posinset\" | \"aria-pressed\" | \"aria-readonly\" | \"aria-relevant\" | \"aria-required\" | \"aria-roledescription\" | \"aria-rowcount\" | \"aria-rowindex\" | \"aria-rowspan\" | \"aria-selected\" | \"aria-setsize\" | \"aria-sort\" | \"aria-valuemax\" | \"aria-valuemin\" | \"aria-valuenow\" | \"aria-valuetext\" | \"dangerouslySetInnerHTML\" | \"onCopy\" | \"onCopyCapture\" | \"onCut\" | \"onCutCapture\" | \"onPaste\" | \"onPasteCapture\" | \"onCompositionEnd\" | \"onCompositionEndCapture\" | \"onCompositionStart\" | \"onCompositionStartCapture\" | \"onCompositionUpdate\" | \"onCompositionUpdateCapture\" | \"onFocus\" | \"onFocusCapture\" | \"onBlur\" | \"onBlurCapture\" | \"onChange\" | \"onChangeCapture\" | \"onBeforeInput\" | \"onBeforeInputCapture\" | \"onInput\" | \"onInputCapture\" | \"onReset\" | \"onResetCapture\" | \"onSubmit\" | \"onSubmitCapture\" | \"onInvalid\" | \"onInvalidCapture\" | \"onLoad\" | \"onLoadCapture\" | \"onErrorCapture\" | \"onKeyDown\" | \"onKeyDownCapture\" | \"onKeyPress\" | \"onKeyPressCapture\" | \"onKeyUp\" | \"onKeyUpCapture\" | \"onAbort\" | \"onAbortCapture\" | \"onCanPlay\" | \"onCanPlayCapture\" | \"onCanPlayThrough\" | \"onCanPlayThroughCapture\" | \"onDurationChange\" | \"onDurationChangeCapture\" | \"onEmptied\" | \"onEmptiedCapture\" | \"onEncrypted\" | \"onEncryptedCapture\" | \"onEnded\" | \"onEndedCapture\" | \"onLoadedData\" | \"onLoadedDataCapture\" | \"onLoadedMetadata\" | \"onLoadedMetadataCapture\" | \"onLoadStart\" | \"onLoadStartCapture\" | \"onPause\" | \"onPauseCapture\" | \"onPlay\" | \"onPlayCapture\" | \"onPlaying\" | \"onPlayingCapture\" | \"onProgress\" | \"onProgressCapture\" | \"onRateChange\" | \"onRateChangeCapture\" | \"onSeeked\" | \"onSeekedCapture\" | \"onSeeking\" | \"onSeekingCapture\" | \"onStalled\" | \"onStalledCapture\" | \"onSuspend\" | \"onSuspendCapture\" | \"onTimeUpdate\" | \"onTimeUpdateCapture\" | \"onVolumeChange\" | \"onVolumeChangeCapture\" | \"onWaiting\" | \"onWaitingCapture\" | \"onAuxClick\" | \"onAuxClickCapture\" | \"onClick\" | \"onClickCapture\" | \"onContextMenu\" | \"onContextMenuCapture\" | \"onDoubleClick\" | \"onDoubleClickCapture\" | \"onDrag\" | \"onDragCapture\" | \"onDragEnd\" | \"onDragEndCapture\" | \"onDragEnter\" | \"onDragEnterCapture\" | \"onDragExit\" | \"onDragExitCapture\" | \"onDragLeave\" | \"onDragLeaveCapture\" | \"onDragOver\" | \"onDragOverCapture\" | \"onDragStart\" | \"onDragStartCapture\" | \"onDrop\" | \"onDropCapture\" | \"onMouseDown\" | \"onMouseDownCapture\" | \"onMouseEnter\" | \"onMouseLeave\" | \"onMouseMove\" | \"onMouseMoveCapture\" | \"onMouseOut\" | \"onMouseOutCapture\" | \"onMouseOver\" | \"onMouseOverCapture\" | \"onMouseUp\" | \"onMouseUpCapture\" | \"onSelect\" | \"onSelectCapture\" | \"onTouchCancel\" | \"onTouchCancelCapture\" | \"onTouchEnd\" | \"onTouchEndCapture\" | \"onTouchMove\" | \"onTouchMoveCapture\" | \"onTouchStart\" | \"onTouchStartCapture\" | \"onPointerDown\" | \"onPointerDownCapture\" | \"onPointerMove\" | \"onPointerMoveCapture\" | \"onPointerUp\" | \"onPointerUpCapture\" | \"onPointerCancel\" | \"onPointerCancelCapture\" | \"onPointerEnter\" | \"onPointerEnterCapture\" | \"onPointerLeave\" | \"onPointerLeaveCapture\" | \"onPointerOver\" | \"onPointerOverCapture\" | \"onPointerOut\" | \"onPointerOutCapture\" | \"onGotPointerCapture\" | \"onGotPointerCaptureCapture\" | \"onLostPointerCapture\" | \"onLostPointerCaptureCapture\" | \"onScroll\" | \"onScrollCapture\" | \"onWheel\" | \"onWheelCapture\" | \"onAnimationStart\" | \"onAnimationStartCapture\" | \"onAnimationEnd\" | \"onAnimationEndCapture\" | \"onAnimationIteration\" | \"onAnimationIterationCapture\" | \"onTransitionEnd\" | \"onTransitionEndCapture\" | \"data-test-subj\" | \"hidden\" | \"security\" | \"defaultValue\" | \"defaultChecked\" | \"suppressContentEditableWarning\" | \"suppressHydrationWarning\" | \"accessKey\" | \"contentEditable\" | \"contextMenu\" | \"dir\" | \"draggable\" | \"placeholder\" | \"slot\" | \"spellCheck\" | \"translate\" | \"radioGroup\" | \"about\" | \"datatype\" | \"inlist\" | \"prefix\" | \"property\" | \"resource\" | \"typeof\" | \"vocab\" | \"autoCapitalize\" | \"autoCorrect\" | \"autoSave\" | \"itemProp\" | \"itemScope\" | \"itemType\" | \"itemID\" | \"itemRef\" | \"results\" | \"unselectable\" | \"inputMode\" | \"is\" | \"toastLifeTimeMs\" | \"iconType\" | \"onClose\"> & { title?: string | ", + ", \"children\" | \"onError\" | \"hidden\" | \"color\" | \"className\" | \"onChange\" | \"onKeyDown\" | \"onClick\" | \"security\" | \"defaultValue\" | \"lang\" | \"defaultChecked\" | \"suppressContentEditableWarning\" | \"suppressHydrationWarning\" | \"accessKey\" | \"contentEditable\" | \"contextMenu\" | \"dir\" | \"draggable\" | \"placeholder\" | \"slot\" | \"spellCheck\" | \"style\" | \"tabIndex\" | \"translate\" | \"radioGroup\" | \"role\" | \"about\" | \"datatype\" | \"inlist\" | \"prefix\" | \"property\" | \"resource\" | \"typeof\" | \"vocab\" | \"autoCapitalize\" | \"autoCorrect\" | \"autoSave\" | \"itemProp\" | \"itemScope\" | \"itemType\" | \"itemID\" | \"itemRef\" | \"results\" | \"unselectable\" | \"inputMode\" | \"is\" | \"aria-activedescendant\" | \"aria-atomic\" | \"aria-autocomplete\" | \"aria-busy\" | \"aria-checked\" | \"aria-colcount\" | \"aria-colindex\" | \"aria-colspan\" | \"aria-controls\" | \"aria-current\" | \"aria-describedby\" | \"aria-details\" | \"aria-disabled\" | \"aria-dropeffect\" | \"aria-errormessage\" | \"aria-expanded\" | \"aria-flowto\" | \"aria-grabbed\" | \"aria-haspopup\" | \"aria-hidden\" | \"aria-invalid\" | \"aria-keyshortcuts\" | \"aria-label\" | \"aria-labelledby\" | \"aria-level\" | \"aria-live\" | \"aria-modal\" | \"aria-multiline\" | \"aria-multiselectable\" | \"aria-orientation\" | \"aria-owns\" | \"aria-placeholder\" | \"aria-posinset\" | \"aria-pressed\" | \"aria-readonly\" | \"aria-relevant\" | \"aria-required\" | \"aria-roledescription\" | \"aria-rowcount\" | \"aria-rowindex\" | \"aria-rowspan\" | \"aria-selected\" | \"aria-setsize\" | \"aria-sort\" | \"aria-valuemax\" | \"aria-valuemin\" | \"aria-valuenow\" | \"aria-valuetext\" | \"dangerouslySetInnerHTML\" | \"onCopy\" | \"onCopyCapture\" | \"onCut\" | \"onCutCapture\" | \"onPaste\" | \"onPasteCapture\" | \"onCompositionEnd\" | \"onCompositionEndCapture\" | \"onCompositionStart\" | \"onCompositionStartCapture\" | \"onCompositionUpdate\" | \"onCompositionUpdateCapture\" | \"onFocus\" | \"onFocusCapture\" | \"onBlur\" | \"onBlurCapture\" | \"onChangeCapture\" | \"onBeforeInput\" | \"onBeforeInputCapture\" | \"onInput\" | \"onInputCapture\" | \"onReset\" | \"onResetCapture\" | \"onSubmit\" | \"onSubmitCapture\" | \"onInvalid\" | \"onInvalidCapture\" | \"onLoad\" | \"onLoadCapture\" | \"onErrorCapture\" | \"onKeyDownCapture\" | \"onKeyPress\" | \"onKeyPressCapture\" | \"onKeyUp\" | \"onKeyUpCapture\" | \"onAbort\" | \"onAbortCapture\" | \"onCanPlay\" | \"onCanPlayCapture\" | \"onCanPlayThrough\" | \"onCanPlayThroughCapture\" | \"onDurationChange\" | \"onDurationChangeCapture\" | \"onEmptied\" | \"onEmptiedCapture\" | \"onEncrypted\" | \"onEncryptedCapture\" | \"onEnded\" | \"onEndedCapture\" | \"onLoadedData\" | \"onLoadedDataCapture\" | \"onLoadedMetadata\" | \"onLoadedMetadataCapture\" | \"onLoadStart\" | \"onLoadStartCapture\" | \"onPause\" | \"onPauseCapture\" | \"onPlay\" | \"onPlayCapture\" | \"onPlaying\" | \"onPlayingCapture\" | \"onProgress\" | \"onProgressCapture\" | \"onRateChange\" | \"onRateChangeCapture\" | \"onSeeked\" | \"onSeekedCapture\" | \"onSeeking\" | \"onSeekingCapture\" | \"onStalled\" | \"onStalledCapture\" | \"onSuspend\" | \"onSuspendCapture\" | \"onTimeUpdate\" | \"onTimeUpdateCapture\" | \"onVolumeChange\" | \"onVolumeChangeCapture\" | \"onWaiting\" | \"onWaitingCapture\" | \"onAuxClick\" | \"onAuxClickCapture\" | \"onClickCapture\" | \"onContextMenu\" | \"onContextMenuCapture\" | \"onDoubleClick\" | \"onDoubleClickCapture\" | \"onDrag\" | \"onDragCapture\" | \"onDragEnd\" | \"onDragEndCapture\" | \"onDragEnter\" | \"onDragEnterCapture\" | \"onDragExit\" | \"onDragExitCapture\" | \"onDragLeave\" | \"onDragLeaveCapture\" | \"onDragOver\" | \"onDragOverCapture\" | \"onDragStart\" | \"onDragStartCapture\" | \"onDrop\" | \"onDropCapture\" | \"onMouseDown\" | \"onMouseDownCapture\" | \"onMouseEnter\" | \"onMouseLeave\" | \"onMouseMove\" | \"onMouseMoveCapture\" | \"onMouseOut\" | \"onMouseOutCapture\" | \"onMouseOver\" | \"onMouseOverCapture\" | \"onMouseUp\" | \"onMouseUpCapture\" | \"onSelect\" | \"onSelectCapture\" | \"onTouchCancel\" | \"onTouchCancelCapture\" | \"onTouchEnd\" | \"onTouchEndCapture\" | \"onTouchMove\" | \"onTouchMoveCapture\" | \"onTouchStart\" | \"onTouchStartCapture\" | \"onPointerDown\" | \"onPointerDownCapture\" | \"onPointerMove\" | \"onPointerMoveCapture\" | \"onPointerUp\" | \"onPointerUpCapture\" | \"onPointerCancel\" | \"onPointerCancelCapture\" | \"onPointerEnter\" | \"onPointerEnterCapture\" | \"onPointerLeave\" | \"onPointerLeaveCapture\" | \"onPointerOver\" | \"onPointerOverCapture\" | \"onPointerOut\" | \"onPointerOutCapture\" | \"onGotPointerCapture\" | \"onGotPointerCaptureCapture\" | \"onLostPointerCapture\" | \"onLostPointerCaptureCapture\" | \"onScroll\" | \"onScrollCapture\" | \"onWheel\" | \"onWheelCapture\" | \"onAnimationStart\" | \"onAnimationStartCapture\" | \"onAnimationEnd\" | \"onAnimationEndCapture\" | \"onAnimationIteration\" | \"onAnimationIterationCapture\" | \"onTransitionEnd\" | \"onTransitionEndCapture\" | \"toastLifeTimeMs\" | \"iconType\" | \"onClose\" | \"data-test-subj\"> & { title?: string | ", "MountPoint", " | undefined; text?: string | ", "MountPoint", @@ -19748,7 +19748,7 @@ "label": "DataViewSavedObjectAttrs", "description": [], "signature": [ - "{ type?: string | undefined; name?: string | undefined; title: string; typeMeta?: string | undefined; }" + "{ type?: string | undefined; title: string; name?: string | undefined; typeMeta?: string | undefined; }" ], "path": "src/plugins/data_views/common/data_views/data_views.ts", "deprecated": false, @@ -20309,7 +20309,7 @@ "signature": [ "Pick<", "Toast", - ", \"children\" | \"onError\" | \"color\" | \"className\" | \"lang\" | \"style\" | \"role\" | \"tabIndex\" | \"aria-activedescendant\" | \"aria-atomic\" | \"aria-autocomplete\" | \"aria-busy\" | \"aria-checked\" | \"aria-colcount\" | \"aria-colindex\" | \"aria-colspan\" | \"aria-controls\" | \"aria-current\" | \"aria-describedby\" | \"aria-details\" | \"aria-disabled\" | \"aria-dropeffect\" | \"aria-errormessage\" | \"aria-expanded\" | \"aria-flowto\" | \"aria-grabbed\" | \"aria-haspopup\" | \"aria-hidden\" | \"aria-invalid\" | \"aria-keyshortcuts\" | \"aria-label\" | \"aria-labelledby\" | \"aria-level\" | \"aria-live\" | \"aria-modal\" | \"aria-multiline\" | \"aria-multiselectable\" | \"aria-orientation\" | \"aria-owns\" | \"aria-placeholder\" | \"aria-posinset\" | \"aria-pressed\" | \"aria-readonly\" | \"aria-relevant\" | \"aria-required\" | \"aria-roledescription\" | \"aria-rowcount\" | \"aria-rowindex\" | \"aria-rowspan\" | \"aria-selected\" | \"aria-setsize\" | \"aria-sort\" | \"aria-valuemax\" | \"aria-valuemin\" | \"aria-valuenow\" | \"aria-valuetext\" | \"dangerouslySetInnerHTML\" | \"onCopy\" | \"onCopyCapture\" | \"onCut\" | \"onCutCapture\" | \"onPaste\" | \"onPasteCapture\" | \"onCompositionEnd\" | \"onCompositionEndCapture\" | \"onCompositionStart\" | \"onCompositionStartCapture\" | \"onCompositionUpdate\" | \"onCompositionUpdateCapture\" | \"onFocus\" | \"onFocusCapture\" | \"onBlur\" | \"onBlurCapture\" | \"onChange\" | \"onChangeCapture\" | \"onBeforeInput\" | \"onBeforeInputCapture\" | \"onInput\" | \"onInputCapture\" | \"onReset\" | \"onResetCapture\" | \"onSubmit\" | \"onSubmitCapture\" | \"onInvalid\" | \"onInvalidCapture\" | \"onLoad\" | \"onLoadCapture\" | \"onErrorCapture\" | \"onKeyDown\" | \"onKeyDownCapture\" | \"onKeyPress\" | \"onKeyPressCapture\" | \"onKeyUp\" | \"onKeyUpCapture\" | \"onAbort\" | \"onAbortCapture\" | \"onCanPlay\" | \"onCanPlayCapture\" | \"onCanPlayThrough\" | \"onCanPlayThroughCapture\" | \"onDurationChange\" | \"onDurationChangeCapture\" | \"onEmptied\" | \"onEmptiedCapture\" | \"onEncrypted\" | \"onEncryptedCapture\" | \"onEnded\" | \"onEndedCapture\" | \"onLoadedData\" | \"onLoadedDataCapture\" | \"onLoadedMetadata\" | \"onLoadedMetadataCapture\" | \"onLoadStart\" | \"onLoadStartCapture\" | \"onPause\" | \"onPauseCapture\" | \"onPlay\" | \"onPlayCapture\" | \"onPlaying\" | \"onPlayingCapture\" | \"onProgress\" | \"onProgressCapture\" | \"onRateChange\" | \"onRateChangeCapture\" | \"onSeeked\" | \"onSeekedCapture\" | \"onSeeking\" | \"onSeekingCapture\" | \"onStalled\" | \"onStalledCapture\" | \"onSuspend\" | \"onSuspendCapture\" | \"onTimeUpdate\" | \"onTimeUpdateCapture\" | \"onVolumeChange\" | \"onVolumeChangeCapture\" | \"onWaiting\" | \"onWaitingCapture\" | \"onAuxClick\" | \"onAuxClickCapture\" | \"onClick\" | \"onClickCapture\" | \"onContextMenu\" | \"onContextMenuCapture\" | \"onDoubleClick\" | \"onDoubleClickCapture\" | \"onDrag\" | \"onDragCapture\" | \"onDragEnd\" | \"onDragEndCapture\" | \"onDragEnter\" | \"onDragEnterCapture\" | \"onDragExit\" | \"onDragExitCapture\" | \"onDragLeave\" | \"onDragLeaveCapture\" | \"onDragOver\" | \"onDragOverCapture\" | \"onDragStart\" | \"onDragStartCapture\" | \"onDrop\" | \"onDropCapture\" | \"onMouseDown\" | \"onMouseDownCapture\" | \"onMouseEnter\" | \"onMouseLeave\" | \"onMouseMove\" | \"onMouseMoveCapture\" | \"onMouseOut\" | \"onMouseOutCapture\" | \"onMouseOver\" | \"onMouseOverCapture\" | \"onMouseUp\" | \"onMouseUpCapture\" | \"onSelect\" | \"onSelectCapture\" | \"onTouchCancel\" | \"onTouchCancelCapture\" | \"onTouchEnd\" | \"onTouchEndCapture\" | \"onTouchMove\" | \"onTouchMoveCapture\" | \"onTouchStart\" | \"onTouchStartCapture\" | \"onPointerDown\" | \"onPointerDownCapture\" | \"onPointerMove\" | \"onPointerMoveCapture\" | \"onPointerUp\" | \"onPointerUpCapture\" | \"onPointerCancel\" | \"onPointerCancelCapture\" | \"onPointerEnter\" | \"onPointerEnterCapture\" | \"onPointerLeave\" | \"onPointerLeaveCapture\" | \"onPointerOver\" | \"onPointerOverCapture\" | \"onPointerOut\" | \"onPointerOutCapture\" | \"onGotPointerCapture\" | \"onGotPointerCaptureCapture\" | \"onLostPointerCapture\" | \"onLostPointerCaptureCapture\" | \"onScroll\" | \"onScrollCapture\" | \"onWheel\" | \"onWheelCapture\" | \"onAnimationStart\" | \"onAnimationStartCapture\" | \"onAnimationEnd\" | \"onAnimationEndCapture\" | \"onAnimationIteration\" | \"onAnimationIterationCapture\" | \"onTransitionEnd\" | \"onTransitionEndCapture\" | \"data-test-subj\" | \"hidden\" | \"security\" | \"defaultValue\" | \"defaultChecked\" | \"suppressContentEditableWarning\" | \"suppressHydrationWarning\" | \"accessKey\" | \"contentEditable\" | \"contextMenu\" | \"dir\" | \"draggable\" | \"placeholder\" | \"slot\" | \"spellCheck\" | \"translate\" | \"radioGroup\" | \"about\" | \"datatype\" | \"inlist\" | \"prefix\" | \"property\" | \"resource\" | \"typeof\" | \"vocab\" | \"autoCapitalize\" | \"autoCorrect\" | \"autoSave\" | \"itemProp\" | \"itemScope\" | \"itemType\" | \"itemID\" | \"itemRef\" | \"results\" | \"unselectable\" | \"inputMode\" | \"is\" | \"toastLifeTimeMs\" | \"iconType\" | \"onClose\"> & { title?: string | ", + ", \"children\" | \"onError\" | \"hidden\" | \"color\" | \"className\" | \"onChange\" | \"onKeyDown\" | \"onClick\" | \"security\" | \"defaultValue\" | \"lang\" | \"defaultChecked\" | \"suppressContentEditableWarning\" | \"suppressHydrationWarning\" | \"accessKey\" | \"contentEditable\" | \"contextMenu\" | \"dir\" | \"draggable\" | \"placeholder\" | \"slot\" | \"spellCheck\" | \"style\" | \"tabIndex\" | \"translate\" | \"radioGroup\" | \"role\" | \"about\" | \"datatype\" | \"inlist\" | \"prefix\" | \"property\" | \"resource\" | \"typeof\" | \"vocab\" | \"autoCapitalize\" | \"autoCorrect\" | \"autoSave\" | \"itemProp\" | \"itemScope\" | \"itemType\" | \"itemID\" | \"itemRef\" | \"results\" | \"unselectable\" | \"inputMode\" | \"is\" | \"aria-activedescendant\" | \"aria-atomic\" | \"aria-autocomplete\" | \"aria-busy\" | \"aria-checked\" | \"aria-colcount\" | \"aria-colindex\" | \"aria-colspan\" | \"aria-controls\" | \"aria-current\" | \"aria-describedby\" | \"aria-details\" | \"aria-disabled\" | \"aria-dropeffect\" | \"aria-errormessage\" | \"aria-expanded\" | \"aria-flowto\" | \"aria-grabbed\" | \"aria-haspopup\" | \"aria-hidden\" | \"aria-invalid\" | \"aria-keyshortcuts\" | \"aria-label\" | \"aria-labelledby\" | \"aria-level\" | \"aria-live\" | \"aria-modal\" | \"aria-multiline\" | \"aria-multiselectable\" | \"aria-orientation\" | \"aria-owns\" | \"aria-placeholder\" | \"aria-posinset\" | \"aria-pressed\" | \"aria-readonly\" | \"aria-relevant\" | \"aria-required\" | \"aria-roledescription\" | \"aria-rowcount\" | \"aria-rowindex\" | \"aria-rowspan\" | \"aria-selected\" | \"aria-setsize\" | \"aria-sort\" | \"aria-valuemax\" | \"aria-valuemin\" | \"aria-valuenow\" | \"aria-valuetext\" | \"dangerouslySetInnerHTML\" | \"onCopy\" | \"onCopyCapture\" | \"onCut\" | \"onCutCapture\" | \"onPaste\" | \"onPasteCapture\" | \"onCompositionEnd\" | \"onCompositionEndCapture\" | \"onCompositionStart\" | \"onCompositionStartCapture\" | \"onCompositionUpdate\" | \"onCompositionUpdateCapture\" | \"onFocus\" | \"onFocusCapture\" | \"onBlur\" | \"onBlurCapture\" | \"onChangeCapture\" | \"onBeforeInput\" | \"onBeforeInputCapture\" | \"onInput\" | \"onInputCapture\" | \"onReset\" | \"onResetCapture\" | \"onSubmit\" | \"onSubmitCapture\" | \"onInvalid\" | \"onInvalidCapture\" | \"onLoad\" | \"onLoadCapture\" | \"onErrorCapture\" | \"onKeyDownCapture\" | \"onKeyPress\" | \"onKeyPressCapture\" | \"onKeyUp\" | \"onKeyUpCapture\" | \"onAbort\" | \"onAbortCapture\" | \"onCanPlay\" | \"onCanPlayCapture\" | \"onCanPlayThrough\" | \"onCanPlayThroughCapture\" | \"onDurationChange\" | \"onDurationChangeCapture\" | \"onEmptied\" | \"onEmptiedCapture\" | \"onEncrypted\" | \"onEncryptedCapture\" | \"onEnded\" | \"onEndedCapture\" | \"onLoadedData\" | \"onLoadedDataCapture\" | \"onLoadedMetadata\" | \"onLoadedMetadataCapture\" | \"onLoadStart\" | \"onLoadStartCapture\" | \"onPause\" | \"onPauseCapture\" | \"onPlay\" | \"onPlayCapture\" | \"onPlaying\" | \"onPlayingCapture\" | \"onProgress\" | \"onProgressCapture\" | \"onRateChange\" | \"onRateChangeCapture\" | \"onSeeked\" | \"onSeekedCapture\" | \"onSeeking\" | \"onSeekingCapture\" | \"onStalled\" | \"onStalledCapture\" | \"onSuspend\" | \"onSuspendCapture\" | \"onTimeUpdate\" | \"onTimeUpdateCapture\" | \"onVolumeChange\" | \"onVolumeChangeCapture\" | \"onWaiting\" | \"onWaitingCapture\" | \"onAuxClick\" | \"onAuxClickCapture\" | \"onClickCapture\" | \"onContextMenu\" | \"onContextMenuCapture\" | \"onDoubleClick\" | \"onDoubleClickCapture\" | \"onDrag\" | \"onDragCapture\" | \"onDragEnd\" | \"onDragEndCapture\" | \"onDragEnter\" | \"onDragEnterCapture\" | \"onDragExit\" | \"onDragExitCapture\" | \"onDragLeave\" | \"onDragLeaveCapture\" | \"onDragOver\" | \"onDragOverCapture\" | \"onDragStart\" | \"onDragStartCapture\" | \"onDrop\" | \"onDropCapture\" | \"onMouseDown\" | \"onMouseDownCapture\" | \"onMouseEnter\" | \"onMouseLeave\" | \"onMouseMove\" | \"onMouseMoveCapture\" | \"onMouseOut\" | \"onMouseOutCapture\" | \"onMouseOver\" | \"onMouseOverCapture\" | \"onMouseUp\" | \"onMouseUpCapture\" | \"onSelect\" | \"onSelectCapture\" | \"onTouchCancel\" | \"onTouchCancelCapture\" | \"onTouchEnd\" | \"onTouchEndCapture\" | \"onTouchMove\" | \"onTouchMoveCapture\" | \"onTouchStart\" | \"onTouchStartCapture\" | \"onPointerDown\" | \"onPointerDownCapture\" | \"onPointerMove\" | \"onPointerMoveCapture\" | \"onPointerUp\" | \"onPointerUpCapture\" | \"onPointerCancel\" | \"onPointerCancelCapture\" | \"onPointerEnter\" | \"onPointerEnterCapture\" | \"onPointerLeave\" | \"onPointerLeaveCapture\" | \"onPointerOver\" | \"onPointerOverCapture\" | \"onPointerOut\" | \"onPointerOutCapture\" | \"onGotPointerCapture\" | \"onGotPointerCaptureCapture\" | \"onLostPointerCapture\" | \"onLostPointerCaptureCapture\" | \"onScroll\" | \"onScrollCapture\" | \"onWheel\" | \"onWheelCapture\" | \"onAnimationStart\" | \"onAnimationStartCapture\" | \"onAnimationEnd\" | \"onAnimationEndCapture\" | \"onAnimationIteration\" | \"onAnimationIterationCapture\" | \"onTransitionEnd\" | \"onTransitionEndCapture\" | \"toastLifeTimeMs\" | \"iconType\" | \"onClose\" | \"data-test-subj\"> & { title?: string | ", "MountPoint", " | undefined; text?: string | ", "MountPoint", diff --git a/api_docs/data_views.mdx b/api_docs/data_views.mdx index 51b11e2a5c7806..4cba0db8b5fafc 100644 --- a/api_docs/data_views.mdx +++ b/api_docs/data_views.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViews title: "dataViews" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViews plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViews'] --- import dataViewsObj from './data_views.devdocs.json'; diff --git a/api_docs/data_visualizer.mdx b/api_docs/data_visualizer.mdx index bf0f8671c1c3c4..bba6a6642f12c6 100644 --- a/api_docs/data_visualizer.mdx +++ b/api_docs/data_visualizer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataVisualizer title: "dataVisualizer" image: https://source.unsplash.com/400x175/?github description: API docs for the dataVisualizer plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataVisualizer'] --- import dataVisualizerObj from './data_visualizer.devdocs.json'; diff --git a/api_docs/deprecations_by_api.mdx b/api_docs/deprecations_by_api.mdx index 1e31b6934409ac..694f178b66e5cd 100644 --- a/api_docs/deprecations_by_api.mdx +++ b/api_docs/deprecations_by_api.mdx @@ -7,7 +7,7 @@ id: kibDevDocsDeprecationsByApi slug: /kibana-dev-docs/api-meta/deprecated-api-list-by-api title: Deprecated API usage by API description: A list of deprecated APIs, which plugins are still referencing them, and when they need to be removed by. -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- @@ -49,16 +49,16 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | lens, observability, dataVisualizer, fleet, cloudSecurityPosture, discoverEnhanced, osquery, synthetics | - | | | esUiShared, home, data, spaces, fleet, observability, ml, apm, indexLifecycleManagement, synthetics, upgradeAssistant, ux, savedObjectsManagement, kibanaOverview | - | | | management, spaces, ml, canvas, enterpriseSearch, osquery, home | - | -| | canvas, visTypeXy | - | +| | canvas | - | | | canvas | - | | | canvas | - | | | canvas | - | -| | canvas, visTypeXy | - | -| | canvas, visTypeXy | - | +| | canvas | - | +| | canvas | - | | | canvas | - | | | canvas | - | | | canvas | - | -| | canvas, visTypeXy | - | +| | canvas | - | | | management, enterpriseSearch | - | | | enterpriseSearch | - | | | actions, ml, savedObjectsTagging, enterpriseSearch | - | @@ -72,7 +72,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | apm, security, securitySolution | 8.8.0 | | | visualizations, dashboard, lens, maps, ml, securitySolution, security | 8.8.0 | | | securitySolution | 8.8.0 | -| | savedObjectsTaggingOss, visualizations, dashboard, lens | 8.8.0 | +| | savedObjectsTaggingOss, dashboard | 8.8.0 | | | dashboard | 8.8.0 | | | maps, dashboard | 8.8.0 | | | monitoring, kibanaUsageCollection, @kbn/core-metrics-server-internal | 8.8.0 | diff --git a/api_docs/deprecations_by_plugin.mdx b/api_docs/deprecations_by_plugin.mdx index e295c99ec7a6ab..5e6024d7f52e78 100644 --- a/api_docs/deprecations_by_plugin.mdx +++ b/api_docs/deprecations_by_plugin.mdx @@ -7,7 +7,7 @@ id: kibDevDocsDeprecationsByPlugin slug: /kibana-dev-docs/api-meta/deprecated-api-list-by-plugin title: Deprecated API usage by plugin description: A list of deprecated APIs, which plugins are still referencing them, and when they need to be removed by. -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- @@ -355,7 +355,6 @@ so TS and code-reference navigation might not highlight them. | | Deprecated API | Reference location(s) | Remove By | | ---------------|-----------|-----------| | | [lens_top_nav.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/app_plugin/lens_top_nav.tsx#:~:text=indexPatternId) | - | -| | [display_duplicate_title_confirm_modal.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/persistence/saved_objects_utils/display_duplicate_title_confirm_modal.ts#:~:text=SavedObject), [display_duplicate_title_confirm_modal.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/persistence/saved_objects_utils/display_duplicate_title_confirm_modal.ts#:~:text=SavedObject), [check_for_duplicate_title.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/persistence/saved_objects_utils/check_for_duplicate_title.ts#:~:text=SavedObject), [check_for_duplicate_title.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/persistence/saved_objects_utils/check_for_duplicate_title.ts#:~:text=SavedObject) | 8.8.0 | | | [types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/app_plugin/types.ts#:~:text=onAppLeave), [types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/app_plugin/types.ts#:~:text=onAppLeave), [mounter.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/app_plugin/mounter.tsx#:~:text=onAppLeave) | 8.8.0 | @@ -677,22 +676,10 @@ migrates to using the Kibana Privilege model: https://github.com/elastic/kibana/ -## visTypeXy - -| Deprecated API | Reference location(s) | Remove By | -| ---------------|-----------|-----------| -| | [xy_vis_fn.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_types/xy/public/expression_functions/xy_vis_fn.ts#:~:text=context) | - | -| | [xy_vis_fn.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_types/xy/public/expression_functions/xy_vis_fn.ts#:~:text=Render), [xy_vis_fn.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_types/xy/public/expression_functions/xy_vis_fn.ts#:~:text=Render) | - | -| | [xy_vis_fn.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_types/xy/public/expression_functions/xy_vis_fn.ts#:~:text=context) | - | -| | [xy_vis_fn.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_types/xy/public/expression_functions/xy_vis_fn.ts#:~:text=context) | - | - - - ## visualizations | Deprecated API | Reference location(s) | Remove By | | ---------------|-----------|-----------| -| | [display_duplicate_title_confirm_modal.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/utils/saved_objects_utils/display_duplicate_title_confirm_modal.ts#:~:text=SavedObject), [display_duplicate_title_confirm_modal.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/utils/saved_objects_utils/display_duplicate_title_confirm_modal.ts#:~:text=SavedObject), [check_for_duplicate_title.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/utils/saved_objects_utils/check_for_duplicate_title.ts#:~:text=SavedObject), [check_for_duplicate_title.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/utils/saved_objects_utils/check_for_duplicate_title.ts#:~:text=SavedObject) | 8.8.0 | | | [visualize_top_nav.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/visualize_app/components/visualize_top_nav.tsx#:~:text=onAppLeave), [visualize_editor_common.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/visualize_app/components/visualize_editor_common.tsx#:~:text=onAppLeave), [app.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/visualize_app/app.tsx#:~:text=onAppLeave), [index.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/visualize_app/index.tsx#:~:text=onAppLeave) | 8.8.0 | diff --git a/api_docs/deprecations_by_team.mdx b/api_docs/deprecations_by_team.mdx index 74bb32bef5d557..f11da1bf1abfe3 100644 --- a/api_docs/deprecations_by_team.mdx +++ b/api_docs/deprecations_by_team.mdx @@ -7,7 +7,7 @@ id: kibDevDocsDeprecationsDueByTeam slug: /kibana-dev-docs/api-meta/deprecations-due-by-team title: Deprecated APIs due to be removed, by team description: Lists the teams that are referencing deprecated APIs with a remove by date. -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- @@ -190,6 +190,5 @@ migrates to using the Kibana Privilege model: https://github.com/elastic/kibana/ | Plugin | Deprecated API | Reference location(s) | Remove By | | --------|-------|-----------|-----------| -| lens | | [display_duplicate_title_confirm_modal.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/persistence/saved_objects_utils/display_duplicate_title_confirm_modal.ts#:~:text=SavedObject), [display_duplicate_title_confirm_modal.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/persistence/saved_objects_utils/display_duplicate_title_confirm_modal.ts#:~:text=SavedObject), [check_for_duplicate_title.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/persistence/saved_objects_utils/check_for_duplicate_title.ts#:~:text=SavedObject), [check_for_duplicate_title.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/persistence/saved_objects_utils/check_for_duplicate_title.ts#:~:text=SavedObject), [display_duplicate_title_confirm_modal.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/utils/saved_objects_utils/display_duplicate_title_confirm_modal.ts#:~:text=SavedObject), [display_duplicate_title_confirm_modal.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/utils/saved_objects_utils/display_duplicate_title_confirm_modal.ts#:~:text=SavedObject), [check_for_duplicate_title.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/utils/saved_objects_utils/check_for_duplicate_title.ts#:~:text=SavedObject), [check_for_duplicate_title.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/utils/saved_objects_utils/check_for_duplicate_title.ts#:~:text=SavedObject) | 8.8.0 | | lens | | [types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/app_plugin/types.ts#:~:text=onAppLeave), [types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/app_plugin/types.ts#:~:text=onAppLeave), [mounter.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/app_plugin/mounter.tsx#:~:text=onAppLeave), [visualize_top_nav.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/visualize_app/components/visualize_top_nav.tsx#:~:text=onAppLeave), [visualize_editor_common.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/visualize_app/components/visualize_editor_common.tsx#:~:text=onAppLeave), [app.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/visualize_app/app.tsx#:~:text=onAppLeave), [index.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/visualize_app/index.tsx#:~:text=onAppLeave) | 8.8.0 | | management | | [application.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/management/public/application.tsx#:~:text=appBasePath) | 8.8.0 | \ No newline at end of file diff --git a/api_docs/dev_tools.mdx b/api_docs/dev_tools.mdx index 63e2c447379dfe..a36e1303727ff1 100644 --- a/api_docs/dev_tools.mdx +++ b/api_docs/dev_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/devTools title: "devTools" image: https://source.unsplash.com/400x175/?github description: API docs for the devTools plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'devTools'] --- import devToolsObj from './dev_tools.devdocs.json'; diff --git a/api_docs/discover.devdocs.json b/api_docs/discover.devdocs.json index 481583bf2fe5c6..32a75941272160 100644 --- a/api_docs/discover.devdocs.json +++ b/api_docs/discover.devdocs.json @@ -1091,6 +1091,59 @@ "path": "src/plugins/saved_search/public/services/saved_searches/types.ts", "deprecated": false }, + { + "parentPluginId": "discover", + "id": "def-public.SavedSearch.timeRestore", + "type": "CompoundType", + "tags": [], + "label": "timeRestore", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "src/plugins/saved_search/public/services/saved_searches/types.ts", + "deprecated": false + }, + { + "parentPluginId": "discover", + "id": "def-public.SavedSearch.timeRange", + "type": "Object", + "tags": [], + "label": "timeRange", + "description": [], + "signature": [ + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataQueryPluginApi", + "section": "def-common.TimeRange", + "text": "TimeRange" + }, + " | undefined" + ], + "path": "src/plugins/saved_search/public/services/saved_searches/types.ts", + "deprecated": false + }, + { + "parentPluginId": "discover", + "id": "def-public.SavedSearch.refreshInterval", + "type": "Object", + "tags": [], + "label": "refreshInterval", + "description": [], + "signature": [ + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataQueryPluginApi", + "section": "def-common.RefreshInterval", + "text": "RefreshInterval" + }, + " | undefined" + ], + "path": "src/plugins/saved_search/public/services/saved_searches/types.ts", + "deprecated": false + }, { "parentPluginId": "discover", "id": "def-public.SavedSearch.rowsPerPage", diff --git a/api_docs/discover.mdx b/api_docs/discover.mdx index 76894fe6de5e27..f5b71d1897d36a 100644 --- a/api_docs/discover.mdx +++ b/api_docs/discover.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/discover title: "discover" image: https://source.unsplash.com/400x175/?github description: API docs for the discover plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'discover'] --- import discoverObj from './discover.devdocs.json'; @@ -21,7 +21,7 @@ Contact [Data Discovery](https://github.com/orgs/elastic/teams/kibana-data-disco | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 90 | 0 | 73 | 5 | +| 93 | 0 | 76 | 4 | ## Client diff --git a/api_docs/discover_enhanced.mdx b/api_docs/discover_enhanced.mdx index 858b4d3a3def98..a50eb159b8c487 100644 --- a/api_docs/discover_enhanced.mdx +++ b/api_docs/discover_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/discoverEnhanced title: "discoverEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the discoverEnhanced plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'discoverEnhanced'] --- import discoverEnhancedObj from './discover_enhanced.devdocs.json'; diff --git a/api_docs/elastic_apm_synthtrace.mdx b/api_docs/elastic_apm_synthtrace.mdx deleted file mode 100644 index 16529073124836..00000000000000 --- a/api_docs/elastic_apm_synthtrace.mdx +++ /dev/null @@ -1,45 +0,0 @@ ---- -#### -#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system. -#### Reach out in #docs-engineering for more info. -#### -id: kibElasticApmSynthtracePluginApi -slug: /kibana-dev-docs/api/elastic-apm-synthtrace -title: "@elastic/apm-synthtrace" -image: https://source.unsplash.com/400x175/?github -description: API docs for the @elastic/apm-synthtrace plugin -date: 2022-08-17 -tags: ['contributor', 'dev', 'apidocs', 'kibana', '@elastic/apm-synthtrace'] ---- -import elasticApmSynthtraceObj from './elastic_apm_synthtrace.devdocs.json'; - -Elastic APM trace data generator - -Contact [Owner missing] for questions regarding this plugin. - -**Code health stats** - -| Public API count | Any count | Items lacking comments | Missing exports | -|-------------------|-----------|------------------------|-----------------| -| 74 | 0 | 74 | 11 | - -## Server - -### Objects - - -### Functions - - -### Classes - - -### Interfaces - - -### Enums - - -### Consts, variables and types - - diff --git a/api_docs/embeddable.devdocs.json b/api_docs/embeddable.devdocs.json index 15b274a52b3c1d..fcc61f30bb223c 100644 --- a/api_docs/embeddable.devdocs.json +++ b/api_docs/embeddable.devdocs.json @@ -8422,6 +8422,38 @@ ], "returnComment": [] }, + { + "parentPluginId": "embeddable", + "id": "def-public.IEmbeddable.updateOutput", + "type": "Function", + "tags": [], + "label": "updateOutput", + "description": [ + "\nUpdates output state with the given changes." + ], + "signature": [ + "(changes: Partial) => void" + ], + "path": "src/plugins/embeddable/public/lib/embeddables/i_embeddable.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "embeddable", + "id": "def-public.IEmbeddable.updateOutput.$1", + "type": "Object", + "tags": [], + "label": "changes", + "description": [], + "signature": [ + "Partial" + ], + "path": "src/plugins/embeddable/public/lib/embeddables/i_embeddable.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, { "parentPluginId": "embeddable", "id": "def-public.IEmbeddable.getInput$", diff --git a/api_docs/embeddable.mdx b/api_docs/embeddable.mdx index 9df80aa44cd575..67c15158b42ff0 100644 --- a/api_docs/embeddable.mdx +++ b/api_docs/embeddable.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/embeddable title: "embeddable" image: https://source.unsplash.com/400x175/?github description: API docs for the embeddable plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'embeddable'] --- import embeddableObj from './embeddable.devdocs.json'; @@ -21,7 +21,7 @@ Contact [App Services](https://github.com/orgs/elastic/teams/kibana-app-services | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 512 | 0 | 413 | 4 | +| 514 | 0 | 414 | 4 | ## Client diff --git a/api_docs/embeddable_enhanced.mdx b/api_docs/embeddable_enhanced.mdx index 533d446572a937..db905e4189a331 100644 --- a/api_docs/embeddable_enhanced.mdx +++ b/api_docs/embeddable_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/embeddableEnhanced title: "embeddableEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the embeddableEnhanced plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'embeddableEnhanced'] --- import embeddableEnhancedObj from './embeddable_enhanced.devdocs.json'; diff --git a/api_docs/encrypted_saved_objects.mdx b/api_docs/encrypted_saved_objects.mdx index c05ef3a50f0504..393766cf99d9ec 100644 --- a/api_docs/encrypted_saved_objects.mdx +++ b/api_docs/encrypted_saved_objects.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/encryptedSavedObjects title: "encryptedSavedObjects" image: https://source.unsplash.com/400x175/?github description: API docs for the encryptedSavedObjects plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'encryptedSavedObjects'] --- import encryptedSavedObjectsObj from './encrypted_saved_objects.devdocs.json'; diff --git a/api_docs/enterprise_search.devdocs.json b/api_docs/enterprise_search.devdocs.json index 4518c1110b7b12..7cf19747bfb193 100644 --- a/api_docs/enterprise_search.devdocs.json +++ b/api_docs/enterprise_search.devdocs.json @@ -14,6 +14,34 @@ "interfaces": [], "enums": [], "misc": [ + { + "parentPluginId": "enterpriseSearch", + "id": "def-server.ANALYTICS_COLLECTIONS_INDEX", + "type": "string", + "tags": [], + "label": "ANALYTICS_COLLECTIONS_INDEX", + "description": [], + "signature": [ + "\".elastic-analytics-collections\"" + ], + "path": "x-pack/plugins/enterprise_search/server/index.ts", + "deprecated": false, + "initialIsOpen": false + }, + { + "parentPluginId": "enterpriseSearch", + "id": "def-server.ANALYTICS_VERSION", + "type": "string", + "tags": [], + "label": "ANALYTICS_VERSION", + "description": [], + "signature": [ + "\"1\"" + ], + "path": "x-pack/plugins/enterprise_search/server/index.ts", + "deprecated": false, + "initialIsOpen": false + }, { "parentPluginId": "enterpriseSearch", "id": "def-server.ConfigType", diff --git a/api_docs/enterprise_search.mdx b/api_docs/enterprise_search.mdx index ca109c7ceccaa8..f852e914e44d00 100644 --- a/api_docs/enterprise_search.mdx +++ b/api_docs/enterprise_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/enterpriseSearch title: "enterpriseSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the enterpriseSearch plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'enterpriseSearch'] --- import enterpriseSearchObj from './enterprise_search.devdocs.json'; @@ -21,7 +21,7 @@ Contact [Enterprise Search](https://github.com/orgs/elastic/teams/enterprise-sea | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 6 | 0 | 6 | 0 | +| 8 | 0 | 8 | 0 | ## Server diff --git a/api_docs/es_ui_shared.mdx b/api_docs/es_ui_shared.mdx index 050d2207816ed6..d8a11f3f34f147 100644 --- a/api_docs/es_ui_shared.mdx +++ b/api_docs/es_ui_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/esUiShared title: "esUiShared" image: https://source.unsplash.com/400x175/?github description: API docs for the esUiShared plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'esUiShared'] --- import esUiSharedObj from './es_ui_shared.devdocs.json'; diff --git a/api_docs/event_annotation.devdocs.json b/api_docs/event_annotation.devdocs.json index 44dbbcb93afdbd..45958ad9a1352b 100644 --- a/api_docs/event_annotation.devdocs.json +++ b/api_docs/event_annotation.devdocs.json @@ -373,7 +373,7 @@ "label": "AvailableAnnotationIcon", "description": [], "signature": [ - "\"alert\" | \"circle\" | \"asterisk\" | \"bell\" | \"bolt\" | \"bug\" | \"editorComment\" | \"flag\" | \"heart\" | \"mapMarker\" | \"pinFilled\" | \"starEmpty\" | \"tag\" | \"triangle\"" + "\"circle\" | \"asterisk\" | \"alert\" | \"bell\" | \"bolt\" | \"bug\" | \"editorComment\" | \"flag\" | \"heart\" | \"mapMarker\" | \"pinFilled\" | \"starEmpty\" | \"tag\" | \"triangle\"" ], "path": "src/plugins/event_annotation/common/types.ts", "deprecated": false, @@ -847,7 +847,7 @@ "label": "options", "description": [], "signature": [ - "(\"alert\" | \"circle\" | \"asterisk\" | \"bell\" | \"bolt\" | \"bug\" | \"editorComment\" | \"flag\" | \"heart\" | \"mapMarker\" | \"pinFilled\" | \"starEmpty\" | \"tag\" | \"triangle\")[]" + "(\"circle\" | \"asterisk\" | \"alert\" | \"bell\" | \"bolt\" | \"bug\" | \"editorComment\" | \"flag\" | \"heart\" | \"mapMarker\" | \"pinFilled\" | \"starEmpty\" | \"tag\" | \"triangle\")[]" ], "path": "src/plugins/event_annotation/common/manual_event_annotation/index.ts", "deprecated": false diff --git a/api_docs/event_annotation.mdx b/api_docs/event_annotation.mdx index 252f1b0e7517b8..f35d88bc558777 100644 --- a/api_docs/event_annotation.mdx +++ b/api_docs/event_annotation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/eventAnnotation title: "eventAnnotation" image: https://source.unsplash.com/400x175/?github description: API docs for the eventAnnotation plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'eventAnnotation'] --- import eventAnnotationObj from './event_annotation.devdocs.json'; diff --git a/api_docs/event_log.devdocs.json b/api_docs/event_log.devdocs.json index ba50be14ed8cb2..ec9ab9ec49812c 100644 --- a/api_docs/event_log.devdocs.json +++ b/api_docs/event_log.devdocs.json @@ -1123,7 +1123,7 @@ "label": "data", "description": [], "signature": [ - "(Readonly<{ error?: Readonly<{ type?: string | undefined; id?: string | undefined; message?: string | undefined; code?: string | undefined; stack_trace?: string | undefined; } & {}> | undefined; tags?: string[] | undefined; log?: Readonly<{ logger?: string | undefined; level?: string | undefined; } & {}> | undefined; user?: Readonly<{ name?: string | undefined; } & {}> | undefined; message?: string | undefined; kibana?: Readonly<{ version?: string | undefined; alert?: Readonly<{ rule?: Readonly<{ consumer?: string | undefined; execution?: Readonly<{ status?: string | undefined; metrics?: Readonly<{ number_of_triggered_actions?: string | number | undefined; number_of_generated_actions?: string | number | undefined; alert_counts?: Readonly<{ recovered?: string | number | undefined; active?: string | number | undefined; new?: string | number | undefined; } & {}> | undefined; number_of_searches?: string | number | undefined; total_indexing_duration_ms?: string | number | undefined; es_search_duration_ms?: string | number | undefined; total_search_duration_ms?: string | number | undefined; execution_gap_duration_s?: string | number | undefined; } & {}> | undefined; uuid?: string | undefined; status_order?: string | number | undefined; } & {}> | undefined; rule_type_id?: string | undefined; } & {}> | undefined; } & {}> | undefined; alerting?: Readonly<{ status?: string | undefined; instance_id?: string | undefined; action_group_id?: string | undefined; action_subgroup?: string | undefined; } & {}> | undefined; server_uuid?: string | undefined; task?: Readonly<{ id?: string | undefined; schedule_delay?: string | number | undefined; scheduled?: string | undefined; } & {}> | undefined; saved_objects?: Readonly<{ type?: string | undefined; id?: string | undefined; namespace?: string | undefined; rel?: string | undefined; type_id?: string | undefined; } & {}>[] | undefined; space_ids?: string[] | undefined; } & {}> | undefined; ecs?: Readonly<{ version?: string | undefined; } & {}> | undefined; rule?: Readonly<{ id?: string | undefined; name?: string | undefined; version?: string | undefined; description?: string | undefined; license?: string | undefined; category?: string | undefined; reference?: string | undefined; author?: string[] | undefined; ruleset?: string | undefined; uuid?: string | undefined; } & {}> | undefined; event?: Readonly<{ start?: string | undefined; type?: string[] | undefined; id?: string | undefined; end?: string | undefined; original?: string | undefined; outcome?: string | undefined; created?: string | undefined; category?: string[] | undefined; duration?: string | number | undefined; code?: string | undefined; url?: string | undefined; action?: string | undefined; kind?: string | undefined; hash?: string | undefined; severity?: string | number | undefined; dataset?: string | undefined; ingested?: string | undefined; module?: string | undefined; provider?: string | undefined; reason?: string | undefined; reference?: string | undefined; risk_score?: number | undefined; risk_score_norm?: number | undefined; sequence?: string | number | undefined; timezone?: string | undefined; } & {}> | undefined; '@timestamp'?: string | undefined; } & {}> | undefined)[]" + "(Readonly<{ error?: Readonly<{ type?: string | undefined; message?: string | undefined; id?: string | undefined; code?: string | undefined; stack_trace?: string | undefined; } & {}> | undefined; tags?: string[] | undefined; log?: Readonly<{ logger?: string | undefined; level?: string | undefined; } & {}> | undefined; user?: Readonly<{ name?: string | undefined; } & {}> | undefined; message?: string | undefined; kibana?: Readonly<{ alert?: Readonly<{ rule?: Readonly<{ consumer?: string | undefined; execution?: Readonly<{ status?: string | undefined; metrics?: Readonly<{ number_of_triggered_actions?: string | number | undefined; number_of_generated_actions?: string | number | undefined; alert_counts?: Readonly<{ recovered?: string | number | undefined; active?: string | number | undefined; new?: string | number | undefined; } & {}> | undefined; number_of_searches?: string | number | undefined; total_indexing_duration_ms?: string | number | undefined; es_search_duration_ms?: string | number | undefined; total_search_duration_ms?: string | number | undefined; execution_gap_duration_s?: string | number | undefined; } & {}> | undefined; uuid?: string | undefined; status_order?: string | number | undefined; } & {}> | undefined; rule_type_id?: string | undefined; } & {}> | undefined; } & {}> | undefined; version?: string | undefined; alerting?: Readonly<{ status?: string | undefined; instance_id?: string | undefined; action_group_id?: string | undefined; action_subgroup?: string | undefined; } & {}> | undefined; server_uuid?: string | undefined; task?: Readonly<{ id?: string | undefined; schedule_delay?: string | number | undefined; scheduled?: string | undefined; } & {}> | undefined; saved_objects?: Readonly<{ type?: string | undefined; namespace?: string | undefined; id?: string | undefined; rel?: string | undefined; type_id?: string | undefined; } & {}>[] | undefined; space_ids?: string[] | undefined; } & {}> | undefined; ecs?: Readonly<{ version?: string | undefined; } & {}> | undefined; rule?: Readonly<{ id?: string | undefined; description?: string | undefined; name?: string | undefined; version?: string | undefined; license?: string | undefined; category?: string | undefined; reference?: string | undefined; author?: string[] | undefined; ruleset?: string | undefined; uuid?: string | undefined; } & {}> | undefined; event?: Readonly<{ start?: string | undefined; type?: string[] | undefined; id?: string | undefined; outcome?: string | undefined; created?: string | undefined; category?: string[] | undefined; end?: string | undefined; original?: string | undefined; duration?: string | number | undefined; code?: string | undefined; url?: string | undefined; action?: string | undefined; kind?: string | undefined; hash?: string | undefined; severity?: string | number | undefined; dataset?: string | undefined; ingested?: string | undefined; module?: string | undefined; provider?: string | undefined; reason?: string | undefined; reference?: string | undefined; risk_score?: number | undefined; risk_score_norm?: number | undefined; sequence?: string | number | undefined; timezone?: string | undefined; } & {}> | undefined; '@timestamp'?: string | undefined; } & {}> | undefined)[]" ], "path": "x-pack/plugins/event_log/server/es/cluster_client_adapter.ts", "deprecated": false @@ -1142,7 +1142,7 @@ "label": "IEvent", "description": [], "signature": [ - "DeepPartial | undefined; tags?: string[] | undefined; log?: Readonly<{ logger?: string | undefined; level?: string | undefined; } & {}> | undefined; user?: Readonly<{ name?: string | undefined; } & {}> | undefined; message?: string | undefined; kibana?: Readonly<{ version?: string | undefined; alert?: Readonly<{ rule?: Readonly<{ consumer?: string | undefined; execution?: Readonly<{ status?: string | undefined; metrics?: Readonly<{ number_of_triggered_actions?: string | number | undefined; number_of_generated_actions?: string | number | undefined; alert_counts?: Readonly<{ recovered?: string | number | undefined; active?: string | number | undefined; new?: string | number | undefined; } & {}> | undefined; number_of_searches?: string | number | undefined; total_indexing_duration_ms?: string | number | undefined; es_search_duration_ms?: string | number | undefined; total_search_duration_ms?: string | number | undefined; execution_gap_duration_s?: string | number | undefined; } & {}> | undefined; uuid?: string | undefined; status_order?: string | number | undefined; } & {}> | undefined; rule_type_id?: string | undefined; } & {}> | undefined; } & {}> | undefined; alerting?: Readonly<{ status?: string | undefined; instance_id?: string | undefined; action_group_id?: string | undefined; action_subgroup?: string | undefined; } & {}> | undefined; server_uuid?: string | undefined; task?: Readonly<{ id?: string | undefined; schedule_delay?: string | number | undefined; scheduled?: string | undefined; } & {}> | undefined; saved_objects?: Readonly<{ type?: string | undefined; id?: string | undefined; namespace?: string | undefined; rel?: string | undefined; type_id?: string | undefined; } & {}>[] | undefined; space_ids?: string[] | undefined; } & {}> | undefined; ecs?: Readonly<{ version?: string | undefined; } & {}> | undefined; rule?: Readonly<{ id?: string | undefined; name?: string | undefined; version?: string | undefined; description?: string | undefined; license?: string | undefined; category?: string | undefined; reference?: string | undefined; author?: string[] | undefined; ruleset?: string | undefined; uuid?: string | undefined; } & {}> | undefined; event?: Readonly<{ start?: string | undefined; type?: string[] | undefined; id?: string | undefined; end?: string | undefined; original?: string | undefined; outcome?: string | undefined; created?: string | undefined; category?: string[] | undefined; duration?: string | number | undefined; code?: string | undefined; url?: string | undefined; action?: string | undefined; kind?: string | undefined; hash?: string | undefined; severity?: string | number | undefined; dataset?: string | undefined; ingested?: string | undefined; module?: string | undefined; provider?: string | undefined; reason?: string | undefined; reference?: string | undefined; risk_score?: number | undefined; risk_score_norm?: number | undefined; sequence?: string | number | undefined; timezone?: string | undefined; } & {}> | undefined; '@timestamp'?: string | undefined; } & {}>>> | undefined" + "DeepPartial | undefined; tags?: string[] | undefined; log?: Readonly<{ logger?: string | undefined; level?: string | undefined; } & {}> | undefined; user?: Readonly<{ name?: string | undefined; } & {}> | undefined; message?: string | undefined; kibana?: Readonly<{ alert?: Readonly<{ rule?: Readonly<{ consumer?: string | undefined; execution?: Readonly<{ status?: string | undefined; metrics?: Readonly<{ number_of_triggered_actions?: string | number | undefined; number_of_generated_actions?: string | number | undefined; alert_counts?: Readonly<{ recovered?: string | number | undefined; active?: string | number | undefined; new?: string | number | undefined; } & {}> | undefined; number_of_searches?: string | number | undefined; total_indexing_duration_ms?: string | number | undefined; es_search_duration_ms?: string | number | undefined; total_search_duration_ms?: string | number | undefined; execution_gap_duration_s?: string | number | undefined; } & {}> | undefined; uuid?: string | undefined; status_order?: string | number | undefined; } & {}> | undefined; rule_type_id?: string | undefined; } & {}> | undefined; } & {}> | undefined; version?: string | undefined; alerting?: Readonly<{ status?: string | undefined; instance_id?: string | undefined; action_group_id?: string | undefined; action_subgroup?: string | undefined; } & {}> | undefined; server_uuid?: string | undefined; task?: Readonly<{ id?: string | undefined; schedule_delay?: string | number | undefined; scheduled?: string | undefined; } & {}> | undefined; saved_objects?: Readonly<{ type?: string | undefined; namespace?: string | undefined; id?: string | undefined; rel?: string | undefined; type_id?: string | undefined; } & {}>[] | undefined; space_ids?: string[] | undefined; } & {}> | undefined; ecs?: Readonly<{ version?: string | undefined; } & {}> | undefined; rule?: Readonly<{ id?: string | undefined; description?: string | undefined; name?: string | undefined; version?: string | undefined; license?: string | undefined; category?: string | undefined; reference?: string | undefined; author?: string[] | undefined; ruleset?: string | undefined; uuid?: string | undefined; } & {}> | undefined; event?: Readonly<{ start?: string | undefined; type?: string[] | undefined; id?: string | undefined; outcome?: string | undefined; created?: string | undefined; category?: string[] | undefined; end?: string | undefined; original?: string | undefined; duration?: string | number | undefined; code?: string | undefined; url?: string | undefined; action?: string | undefined; kind?: string | undefined; hash?: string | undefined; severity?: string | number | undefined; dataset?: string | undefined; ingested?: string | undefined; module?: string | undefined; provider?: string | undefined; reason?: string | undefined; reference?: string | undefined; risk_score?: number | undefined; risk_score_norm?: number | undefined; sequence?: string | number | undefined; timezone?: string | undefined; } & {}> | undefined; '@timestamp'?: string | undefined; } & {}>>> | undefined" ], "path": "x-pack/plugins/event_log/generated/schemas.ts", "deprecated": false, @@ -1156,7 +1156,7 @@ "label": "IValidatedEvent", "description": [], "signature": [ - "Readonly<{ error?: Readonly<{ type?: string | undefined; id?: string | undefined; message?: string | undefined; code?: string | undefined; stack_trace?: string | undefined; } & {}> | undefined; tags?: string[] | undefined; log?: Readonly<{ logger?: string | undefined; level?: string | undefined; } & {}> | undefined; user?: Readonly<{ name?: string | undefined; } & {}> | undefined; message?: string | undefined; kibana?: Readonly<{ version?: string | undefined; alert?: Readonly<{ rule?: Readonly<{ consumer?: string | undefined; execution?: Readonly<{ status?: string | undefined; metrics?: Readonly<{ number_of_triggered_actions?: string | number | undefined; number_of_generated_actions?: string | number | undefined; alert_counts?: Readonly<{ recovered?: string | number | undefined; active?: string | number | undefined; new?: string | number | undefined; } & {}> | undefined; number_of_searches?: string | number | undefined; total_indexing_duration_ms?: string | number | undefined; es_search_duration_ms?: string | number | undefined; total_search_duration_ms?: string | number | undefined; execution_gap_duration_s?: string | number | undefined; } & {}> | undefined; uuid?: string | undefined; status_order?: string | number | undefined; } & {}> | undefined; rule_type_id?: string | undefined; } & {}> | undefined; } & {}> | undefined; alerting?: Readonly<{ status?: string | undefined; instance_id?: string | undefined; action_group_id?: string | undefined; action_subgroup?: string | undefined; } & {}> | undefined; server_uuid?: string | undefined; task?: Readonly<{ id?: string | undefined; schedule_delay?: string | number | undefined; scheduled?: string | undefined; } & {}> | undefined; saved_objects?: Readonly<{ type?: string | undefined; id?: string | undefined; namespace?: string | undefined; rel?: string | undefined; type_id?: string | undefined; } & {}>[] | undefined; space_ids?: string[] | undefined; } & {}> | undefined; ecs?: Readonly<{ version?: string | undefined; } & {}> | undefined; rule?: Readonly<{ id?: string | undefined; name?: string | undefined; version?: string | undefined; description?: string | undefined; license?: string | undefined; category?: string | undefined; reference?: string | undefined; author?: string[] | undefined; ruleset?: string | undefined; uuid?: string | undefined; } & {}> | undefined; event?: Readonly<{ start?: string | undefined; type?: string[] | undefined; id?: string | undefined; end?: string | undefined; original?: string | undefined; outcome?: string | undefined; created?: string | undefined; category?: string[] | undefined; duration?: string | number | undefined; code?: string | undefined; url?: string | undefined; action?: string | undefined; kind?: string | undefined; hash?: string | undefined; severity?: string | number | undefined; dataset?: string | undefined; ingested?: string | undefined; module?: string | undefined; provider?: string | undefined; reason?: string | undefined; reference?: string | undefined; risk_score?: number | undefined; risk_score_norm?: number | undefined; sequence?: string | number | undefined; timezone?: string | undefined; } & {}> | undefined; '@timestamp'?: string | undefined; } & {}> | undefined" + "Readonly<{ error?: Readonly<{ type?: string | undefined; message?: string | undefined; id?: string | undefined; code?: string | undefined; stack_trace?: string | undefined; } & {}> | undefined; tags?: string[] | undefined; log?: Readonly<{ logger?: string | undefined; level?: string | undefined; } & {}> | undefined; user?: Readonly<{ name?: string | undefined; } & {}> | undefined; message?: string | undefined; kibana?: Readonly<{ alert?: Readonly<{ rule?: Readonly<{ consumer?: string | undefined; execution?: Readonly<{ status?: string | undefined; metrics?: Readonly<{ number_of_triggered_actions?: string | number | undefined; number_of_generated_actions?: string | number | undefined; alert_counts?: Readonly<{ recovered?: string | number | undefined; active?: string | number | undefined; new?: string | number | undefined; } & {}> | undefined; number_of_searches?: string | number | undefined; total_indexing_duration_ms?: string | number | undefined; es_search_duration_ms?: string | number | undefined; total_search_duration_ms?: string | number | undefined; execution_gap_duration_s?: string | number | undefined; } & {}> | undefined; uuid?: string | undefined; status_order?: string | number | undefined; } & {}> | undefined; rule_type_id?: string | undefined; } & {}> | undefined; } & {}> | undefined; version?: string | undefined; alerting?: Readonly<{ status?: string | undefined; instance_id?: string | undefined; action_group_id?: string | undefined; action_subgroup?: string | undefined; } & {}> | undefined; server_uuid?: string | undefined; task?: Readonly<{ id?: string | undefined; schedule_delay?: string | number | undefined; scheduled?: string | undefined; } & {}> | undefined; saved_objects?: Readonly<{ type?: string | undefined; namespace?: string | undefined; id?: string | undefined; rel?: string | undefined; type_id?: string | undefined; } & {}>[] | undefined; space_ids?: string[] | undefined; } & {}> | undefined; ecs?: Readonly<{ version?: string | undefined; } & {}> | undefined; rule?: Readonly<{ id?: string | undefined; description?: string | undefined; name?: string | undefined; version?: string | undefined; license?: string | undefined; category?: string | undefined; reference?: string | undefined; author?: string[] | undefined; ruleset?: string | undefined; uuid?: string | undefined; } & {}> | undefined; event?: Readonly<{ start?: string | undefined; type?: string[] | undefined; id?: string | undefined; outcome?: string | undefined; created?: string | undefined; category?: string[] | undefined; end?: string | undefined; original?: string | undefined; duration?: string | number | undefined; code?: string | undefined; url?: string | undefined; action?: string | undefined; kind?: string | undefined; hash?: string | undefined; severity?: string | number | undefined; dataset?: string | undefined; ingested?: string | undefined; module?: string | undefined; provider?: string | undefined; reason?: string | undefined; reference?: string | undefined; risk_score?: number | undefined; risk_score_norm?: number | undefined; sequence?: string | number | undefined; timezone?: string | undefined; } & {}> | undefined; '@timestamp'?: string | undefined; } & {}> | undefined" ], "path": "x-pack/plugins/event_log/generated/schemas.ts", "deprecated": false, diff --git a/api_docs/event_log.mdx b/api_docs/event_log.mdx index 7cd1d904f878a2..b545014a88b1f8 100644 --- a/api_docs/event_log.mdx +++ b/api_docs/event_log.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/eventLog title: "eventLog" image: https://source.unsplash.com/400x175/?github description: API docs for the eventLog plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'eventLog'] --- import eventLogObj from './event_log.devdocs.json'; diff --git a/api_docs/expression_error.mdx b/api_docs/expression_error.mdx index 31c1dab85bc034..801af47600d085 100644 --- a/api_docs/expression_error.mdx +++ b/api_docs/expression_error.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionError title: "expressionError" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionError plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionError'] --- import expressionErrorObj from './expression_error.devdocs.json'; diff --git a/api_docs/expression_gauge.devdocs.json b/api_docs/expression_gauge.devdocs.json index f40fb1a95cd511..67065298ff9a66 100644 --- a/api_docs/expression_gauge.devdocs.json +++ b/api_docs/expression_gauge.devdocs.json @@ -349,76 +349,6 @@ ], "returnComment": [], "initialIsOpen": false - }, - { - "parentPluginId": "expressionGauge", - "id": "def-public.HorizontalBulletIcon", - "type": "Function", - "tags": [], - "label": "HorizontalBulletIcon", - "description": [], - "signature": [ - "({ title, titleId, ...props }: Omit<", - "EuiIconProps", - ", \"type\">) => JSX.Element" - ], - "path": "src/plugins/chart_expressions/expression_gauge/public/components/icons/horizontal_bullet_icon.tsx", - "deprecated": false, - "children": [ - { - "parentPluginId": "expressionGauge", - "id": "def-public.HorizontalBulletIcon.$1", - "type": "Object", - "tags": [], - "label": "{ title, titleId, ...props }", - "description": [], - "signature": [ - "Omit<", - "EuiIconProps", - ", \"type\">" - ], - "path": "src/plugins/chart_expressions/expression_gauge/public/components/icons/horizontal_bullet_icon.tsx", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [], - "initialIsOpen": false - }, - { - "parentPluginId": "expressionGauge", - "id": "def-public.VerticalBulletIcon", - "type": "Function", - "tags": [], - "label": "VerticalBulletIcon", - "description": [], - "signature": [ - "({ title, titleId, ...props }: Omit<", - "EuiIconProps", - ", \"type\">) => JSX.Element" - ], - "path": "src/plugins/chart_expressions/expression_gauge/public/components/icons/vertical_bullet_icon.tsx", - "deprecated": false, - "children": [ - { - "parentPluginId": "expressionGauge", - "id": "def-public.VerticalBulletIcon.$1", - "type": "Object", - "tags": [], - "label": "{ title, titleId, ...props }", - "description": [], - "signature": [ - "Omit<", - "EuiIconProps", - ", \"type\">" - ], - "path": "src/plugins/chart_expressions/expression_gauge/public/components/icons/vertical_bullet_icon.tsx", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [], - "initialIsOpen": false } ], "interfaces": [], diff --git a/api_docs/expression_gauge.mdx b/api_docs/expression_gauge.mdx index 640337bf70bf53..fd3592cc58ebb9 100644 --- a/api_docs/expression_gauge.mdx +++ b/api_docs/expression_gauge.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionGauge title: "expressionGauge" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionGauge plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionGauge'] --- import expressionGaugeObj from './expression_gauge.devdocs.json'; @@ -21,7 +21,7 @@ Contact [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 61 | 0 | 61 | 2 | +| 57 | 0 | 57 | 2 | ## Client diff --git a/api_docs/expression_heatmap.devdocs.json b/api_docs/expression_heatmap.devdocs.json index 6cc1961115e4ed..2838d206d03a25 100644 --- a/api_docs/expression_heatmap.devdocs.json +++ b/api_docs/expression_heatmap.devdocs.json @@ -2,43 +2,7 @@ "id": "expressionHeatmap", "client": { "classes": [], - "functions": [ - { - "parentPluginId": "expressionHeatmap", - "id": "def-public.HeatmapIcon", - "type": "Function", - "tags": [], - "label": "HeatmapIcon", - "description": [], - "signature": [ - "({ title, titleId, ...props }: Omit<", - "EuiIconProps", - ", \"type\">) => JSX.Element" - ], - "path": "src/plugins/chart_expressions/expression_heatmap/public/components/heatmap_icon.tsx", - "deprecated": false, - "children": [ - { - "parentPluginId": "expressionHeatmap", - "id": "def-public.HeatmapIcon.$1", - "type": "Object", - "tags": [], - "label": "{ title, titleId, ...props }", - "description": [], - "signature": [ - "Omit<", - "EuiIconProps", - ", \"type\">" - ], - "path": "src/plugins/chart_expressions/expression_heatmap/public/components/heatmap_icon.tsx", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [], - "initialIsOpen": false - } - ], + "functions": [], "interfaces": [], "enums": [], "misc": [], diff --git a/api_docs/expression_heatmap.mdx b/api_docs/expression_heatmap.mdx index cdc7cf867c5fbe..a9d51a9b5d6752 100644 --- a/api_docs/expression_heatmap.mdx +++ b/api_docs/expression_heatmap.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionHeatmap title: "expressionHeatmap" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionHeatmap plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionHeatmap'] --- import expressionHeatmapObj from './expression_heatmap.devdocs.json'; @@ -21,12 +21,7 @@ Contact [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 107 | 0 | 103 | 3 | - -## Client - -### Functions - +| 105 | 0 | 101 | 3 | ## Common diff --git a/api_docs/expression_image.mdx b/api_docs/expression_image.mdx index 70c96eb3be2be5..e21f2c99e2df75 100644 --- a/api_docs/expression_image.mdx +++ b/api_docs/expression_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionImage title: "expressionImage" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionImage plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionImage'] --- import expressionImageObj from './expression_image.devdocs.json'; diff --git a/api_docs/expression_legacy_metric_vis.mdx b/api_docs/expression_legacy_metric_vis.mdx index adb5b7a1bd54dc..e5d4d74940efa9 100644 --- a/api_docs/expression_legacy_metric_vis.mdx +++ b/api_docs/expression_legacy_metric_vis.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionLegacyMetricVis title: "expressionLegacyMetricVis" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionLegacyMetricVis plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionLegacyMetricVis'] --- import expressionLegacyMetricVisObj from './expression_legacy_metric_vis.devdocs.json'; diff --git a/api_docs/expression_metric.mdx b/api_docs/expression_metric.mdx index b77f915106d752..aec13b25b506be 100644 --- a/api_docs/expression_metric.mdx +++ b/api_docs/expression_metric.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionMetric title: "expressionMetric" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionMetric plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionMetric'] --- import expressionMetricObj from './expression_metric.devdocs.json'; diff --git a/api_docs/expression_metric_vis.mdx b/api_docs/expression_metric_vis.mdx index 2830948fb2134d..270780c64a2a6f 100644 --- a/api_docs/expression_metric_vis.mdx +++ b/api_docs/expression_metric_vis.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionMetricVis title: "expressionMetricVis" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionMetricVis plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionMetricVis'] --- import expressionMetricVisObj from './expression_metric_vis.devdocs.json'; diff --git a/api_docs/expression_partition_vis.mdx b/api_docs/expression_partition_vis.mdx index 65089161157ae7..21577b23b4a91a 100644 --- a/api_docs/expression_partition_vis.mdx +++ b/api_docs/expression_partition_vis.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionPartitionVis title: "expressionPartitionVis" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionPartitionVis plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionPartitionVis'] --- import expressionPartitionVisObj from './expression_partition_vis.devdocs.json'; diff --git a/api_docs/expression_repeat_image.mdx b/api_docs/expression_repeat_image.mdx index b95194998b666c..b80c9123800cac 100644 --- a/api_docs/expression_repeat_image.mdx +++ b/api_docs/expression_repeat_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionRepeatImage title: "expressionRepeatImage" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionRepeatImage plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionRepeatImage'] --- import expressionRepeatImageObj from './expression_repeat_image.devdocs.json'; diff --git a/api_docs/expression_reveal_image.mdx b/api_docs/expression_reveal_image.mdx index 9f87a41301636f..1aba76752ef03f 100644 --- a/api_docs/expression_reveal_image.mdx +++ b/api_docs/expression_reveal_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionRevealImage title: "expressionRevealImage" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionRevealImage plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionRevealImage'] --- import expressionRevealImageObj from './expression_reveal_image.devdocs.json'; diff --git a/api_docs/expression_shape.devdocs.json b/api_docs/expression_shape.devdocs.json index 5cb96923eb8780..efd37d1f3b4d0c 100644 --- a/api_docs/expression_shape.devdocs.json +++ b/api_docs/expression_shape.devdocs.json @@ -612,7 +612,7 @@ "label": "strokeLinecap", "description": [], "signature": [ - "\"inherit\" | \"butt\" | \"round\" | \"square\" | undefined" + "\"butt\" | \"round\" | \"square\" | \"inherit\" | undefined" ], "path": "src/plugins/expression_shape/public/components/reusable/types.tsx", "deprecated": false @@ -651,7 +651,7 @@ "label": "strokeLinejoin", "description": [], "signature": [ - "\"inherit\" | \"round\" | \"miter\" | \"bevel\" | undefined" + "\"round\" | \"inherit\" | \"miter\" | \"bevel\" | undefined" ], "path": "src/plugins/expression_shape/public/components/reusable/types.tsx", "deprecated": false diff --git a/api_docs/expression_shape.mdx b/api_docs/expression_shape.mdx index 771a3ae316fb16..f8aead7c277eef 100644 --- a/api_docs/expression_shape.mdx +++ b/api_docs/expression_shape.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionShape title: "expressionShape" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionShape plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionShape'] --- import expressionShapeObj from './expression_shape.devdocs.json'; diff --git a/api_docs/expression_tagcloud.mdx b/api_docs/expression_tagcloud.mdx index c2bf747d52904a..030dd09c8fafc7 100644 --- a/api_docs/expression_tagcloud.mdx +++ b/api_docs/expression_tagcloud.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionTagcloud title: "expressionTagcloud" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionTagcloud plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionTagcloud'] --- import expressionTagcloudObj from './expression_tagcloud.devdocs.json'; diff --git a/api_docs/expression_x_y.devdocs.json b/api_docs/expression_x_y.devdocs.json index b1000cda6f9a88..a5afbe5ba1914a 100644 --- a/api_docs/expression_x_y.devdocs.json +++ b/api_docs/expression_x_y.devdocs.json @@ -721,7 +721,7 @@ "label": "xScaleType", "description": [], "signature": [ - "\"time\" | \"linear\" | \"ordinal\"" + "\"linear\" | \"time\" | \"ordinal\"" ], "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", "deprecated": false @@ -788,7 +788,13 @@ "label": "decorations", "description": [], "signature": [ - "DataDecorationConfigResult", + { + "pluginId": "expressionXY", + "scope": "common", + "docId": "kibExpressionXYPluginApi", + "section": "def-common.DataDecorationConfigResult", + "text": "DataDecorationConfigResult" + }, "[] | undefined" ], "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", @@ -1807,7 +1813,7 @@ "label": "AvailableReferenceLineIcon", "description": [], "signature": [ - "\"alert\" | \"circle\" | \"asterisk\" | \"bell\" | \"bolt\" | \"bug\" | \"editorComment\" | \"flag\" | \"heart\" | \"mapMarker\" | \"pinFilled\" | \"starEmpty\" | \"tag\" | \"triangle\" | \"empty\"" + "\"circle\" | \"asterisk\" | \"alert\" | \"bell\" | \"bolt\" | \"bug\" | \"editorComment\" | \"flag\" | \"heart\" | \"mapMarker\" | \"pinFilled\" | \"starEmpty\" | \"tag\" | \"triangle\" | \"empty\"" ], "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", "deprecated": false, @@ -2008,6 +2014,27 @@ "deprecated": false, "initialIsOpen": false }, + { + "parentPluginId": "expressionXY", + "id": "def-common.DataDecorationConfigResult", + "type": "Type", + "tags": [], + "label": "DataDecorationConfigResult", + "description": [], + "signature": [ + { + "pluginId": "expressionXY", + "scope": "common", + "docId": "kibExpressionXYPluginApi", + "section": "def-common.DataDecorationConfig", + "text": "DataDecorationConfig" + }, + " & { type: \"dataDecorationConfig\"; }" + ], + "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", + "deprecated": false, + "initialIsOpen": false + }, { "parentPluginId": "expressionXY", "id": "def-common.DataLayerConfig", @@ -2369,7 +2396,7 @@ "label": "XScaleType", "description": [], "signature": [ - "\"time\" | \"linear\" | \"ordinal\"" + "\"linear\" | \"time\" | \"ordinal\"" ], "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", "deprecated": false, @@ -2480,7 +2507,7 @@ "label": "YScaleType", "description": [], "signature": [ - "\"log\" | \"time\" | \"linear\" | \"sqrt\"" + "\"linear\" | \"log\" | \"time\" | \"sqrt\"" ], "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", "deprecated": false, diff --git a/api_docs/expression_x_y.mdx b/api_docs/expression_x_y.mdx index 0734781230c5a7..c47f2194050e83 100644 --- a/api_docs/expression_x_y.mdx +++ b/api_docs/expression_x_y.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionXY title: "expressionXY" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionXY plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionXY'] --- import expressionXYObj from './expression_x_y.devdocs.json'; @@ -21,7 +21,7 @@ Contact [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 151 | 0 | 141 | 12 | +| 152 | 0 | 142 | 11 | ## Client diff --git a/api_docs/expressions.devdocs.json b/api_docs/expressions.devdocs.json index 04f9f5ef5507d5..f39f113576e2a3 100644 --- a/api_docs/expressions.devdocs.json +++ b/api_docs/expressions.devdocs.json @@ -6980,7 +6980,7 @@ "\nTracks state of execution.\n\n- `not-started` - before .start() method was called.\n- `pending` - immediately after .start() method is called.\n- `result` - when expression execution completed.\n- `error` - when execution failed with error." ], "signature": [ - "\"error\" | \"result\" | \"not-started\" | \"pending\"" + "\"error\" | \"not-started\" | \"pending\" | \"result\"" ], "path": "src/plugins/expressions/common/execution/container.ts", "deprecated": false @@ -7966,10 +7966,6 @@ { "plugin": "canvas", "path": "x-pack/plugins/canvas/canvas_plugin_src/functions/server/pointseries/index.ts" - }, - { - "plugin": "visTypeXy", - "path": "src/plugins/vis_types/xy/public/expression_functions/xy_vis_fn.ts" } ] } @@ -10800,7 +10796,7 @@ "label": "padding", "description": [], "signature": [ - "\"s\" | \"m\" | \"l\" | \"xl\" | \"xs\" | undefined" + "\"m\" | \"s\" | \"xs\" | \"l\" | \"xl\" | undefined" ], "path": "src/plugins/expressions/public/react_expression_renderer/react_expression_renderer.tsx", "deprecated": false @@ -11601,7 +11597,7 @@ "\nAllowed column names in a PointSeries" ], "signature": [ - "\"color\" | \"size\" | \"x\" | \"y\" | \"text\"" + "\"color\" | \"size\" | \"text\" | \"y\" | \"x\"" ], "path": "src/plugins/expressions/common/expression_types/specs/pointseries.ts", "deprecated": false, @@ -17447,7 +17443,7 @@ "\nTracks state of execution.\n\n- `not-started` - before .start() method was called.\n- `pending` - immediately after .start() method is called.\n- `result` - when expression execution completed.\n- `error` - when execution failed with error." ], "signature": [ - "\"error\" | \"result\" | \"not-started\" | \"pending\"" + "\"error\" | \"not-started\" | \"pending\" | \"result\"" ], "path": "src/plugins/expressions/common/execution/container.ts", "deprecated": false @@ -18404,10 +18400,6 @@ { "plugin": "canvas", "path": "x-pack/plugins/canvas/canvas_plugin_src/functions/server/pointseries/index.ts" - }, - { - "plugin": "visTypeXy", - "path": "src/plugins/vis_types/xy/public/expression_functions/xy_vis_fn.ts" } ] } @@ -20629,7 +20621,7 @@ "\nAllowed column names in a PointSeries" ], "signature": [ - "\"color\" | \"size\" | \"x\" | \"y\" | \"text\"" + "\"color\" | \"size\" | \"text\" | \"y\" | \"x\"" ], "path": "src/plugins/expressions/common/expression_types/specs/pointseries.ts", "deprecated": false, @@ -28783,7 +28775,7 @@ "\nTracks state of execution.\n\n- `not-started` - before .start() method was called.\n- `pending` - immediately after .start() method is called.\n- `result` - when expression execution completed.\n- `error` - when execution failed with error." ], "signature": [ - "\"error\" | \"result\" | \"not-started\" | \"pending\"" + "\"error\" | \"not-started\" | \"pending\" | \"result\"" ], "path": "src/plugins/expressions/common/execution/container.ts", "deprecated": false @@ -30224,10 +30216,6 @@ { "plugin": "canvas", "path": "x-pack/plugins/canvas/canvas_plugin_src/functions/server/pointseries/index.ts" - }, - { - "plugin": "visTypeXy", - "path": "src/plugins/vis_types/xy/public/expression_functions/xy_vis_fn.ts" } ] } @@ -34711,7 +34699,7 @@ "label": "MathArguments", "description": [], "signature": [ - "{ expression: string; onError?: \"false\" | \"null\" | \"zero\" | \"throw\" | undefined; }" + "{ expression: string; onError?: \"null\" | \"zero\" | \"false\" | \"throw\" | undefined; }" ], "path": "src/plugins/expressions/common/expression_functions/specs/math.ts", "deprecated": false, @@ -34801,7 +34789,7 @@ "\nAllowed column names in a PointSeries" ], "signature": [ - "\"color\" | \"size\" | \"x\" | \"y\" | \"text\"" + "\"color\" | \"size\" | \"text\" | \"y\" | \"x\"" ], "path": "src/plugins/expressions/common/expression_types/specs/pointseries.ts", "deprecated": false, @@ -34915,14 +34903,6 @@ { "plugin": "canvas", "path": "x-pack/plugins/canvas/canvas_plugin_src/functions/common/table.ts" - }, - { - "plugin": "visTypeXy", - "path": "src/plugins/vis_types/xy/public/expression_functions/xy_vis_fn.ts" - }, - { - "plugin": "visTypeXy", - "path": "src/plugins/vis_types/xy/public/expression_functions/xy_vis_fn.ts" } ], "initialIsOpen": false @@ -38717,7 +38697,7 @@ "label": "options", "description": [], "signature": [ - "(\"false\" | \"null\" | \"zero\" | \"throw\")[]" + "(\"null\" | \"zero\" | \"false\" | \"throw\")[]" ], "path": "src/plugins/expressions/common/expression_functions/specs/math.ts", "deprecated": false @@ -40317,7 +40297,7 @@ "label": "options", "description": [], "signature": [ - "(\"sum\" | \"min\" | \"max\" | \"average\")[]" + "(\"min\" | \"max\" | \"sum\" | \"average\")[]" ], "path": "src/plugins/expressions/common/expression_functions/specs/overall_metric.ts", "deprecated": false diff --git a/api_docs/expressions.mdx b/api_docs/expressions.mdx index 034cd4e0b705de..6372a94dd496e8 100644 --- a/api_docs/expressions.mdx +++ b/api_docs/expressions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressions title: "expressions" image: https://source.unsplash.com/400x175/?github description: API docs for the expressions plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressions'] --- import expressionsObj from './expressions.devdocs.json'; diff --git a/api_docs/features.mdx b/api_docs/features.mdx index 2d6101640e9298..7dce368f42d0af 100644 --- a/api_docs/features.mdx +++ b/api_docs/features.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/features title: "features" image: https://source.unsplash.com/400x175/?github description: API docs for the features plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'features'] --- import featuresObj from './features.devdocs.json'; diff --git a/api_docs/field_formats.mdx b/api_docs/field_formats.mdx index dc11c9489a968b..58279ad756df8a 100644 --- a/api_docs/field_formats.mdx +++ b/api_docs/field_formats.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/fieldFormats title: "fieldFormats" image: https://source.unsplash.com/400x175/?github description: API docs for the fieldFormats plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'fieldFormats'] --- import fieldFormatsObj from './field_formats.devdocs.json'; diff --git a/api_docs/file_upload.mdx b/api_docs/file_upload.mdx index f5dbb0dd062052..d5d31f2257e78e 100644 --- a/api_docs/file_upload.mdx +++ b/api_docs/file_upload.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/fileUpload title: "fileUpload" image: https://source.unsplash.com/400x175/?github description: API docs for the fileUpload plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'fileUpload'] --- import fileUploadObj from './file_upload.devdocs.json'; diff --git a/api_docs/files.devdocs.json b/api_docs/files.devdocs.json index 61e62df3dcdd0b..a8715b305d5aad 100644 --- a/api_docs/files.devdocs.json +++ b/api_docs/files.devdocs.json @@ -141,7 +141,7 @@ "\nList all file objects, of a given {@link FileKind}.\n" ], "signature": [ - "(args: ", + "(args?: ", { "pluginId": "files", "scope": "common", @@ -149,7 +149,7 @@ "section": "def-common.Pagination", "text": "Pagination" }, - ") => Promise<{ files: ", + " | undefined) => Promise<{ files: ", { "pluginId": "files", "scope": "common", @@ -173,7 +173,7 @@ "- list files args" ], "signature": [ - "E[\"inputs\"][\"body\"] & E[\"inputs\"][\"params\"] & E[\"inputs\"][\"query\"]" + "(E[\"inputs\"][\"body\"] & E[\"inputs\"][\"params\"] & E[\"inputs\"][\"query\"]) | undefined" ], "path": "x-pack/plugins/files/public/types.ts", "deprecated": false @@ -280,7 +280,7 @@ "\nStream the contents of the file to Kibana server for storage.\n" ], "signature": [ - "(args: any) => Promise<{ ok: true; size: number; }>" + "(args: { body: unknown; } & { id: string; }) => Promise<{ ok: true; size: number; }>" ], "path": "x-pack/plugins/files/public/types.ts", "deprecated": false, @@ -575,6 +575,53 @@ "deprecated": false } ] + }, + { + "parentPluginId": "files", + "id": "def-public.FilesClient.getDownloadHref", + "type": "Function", + "tags": [], + "label": "getDownloadHref", + "description": [ + "\nGet a string for downloading a file that can be passed to a button element's\nhref for download." + ], + "signature": [ + "(file: ", + { + "pluginId": "files", + "scope": "common", + "docId": "kibFilesPluginApi", + "section": "def-common.FileJSON", + "text": "FileJSON" + }, + ") => string" + ], + "path": "x-pack/plugins/files/public/types.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "files", + "id": "def-public.FilesClient.getDownloadHref.$1", + "type": "Object", + "tags": [], + "label": "file", + "description": [], + "signature": [ + { + "pluginId": "files", + "scope": "common", + "docId": "kibFilesPluginApi", + "section": "def-common.FileJSON", + "text": "FileJSON" + }, + "" + ], + "path": "x-pack/plugins/files/public/types.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] } ], "initialIsOpen": false @@ -637,8 +684,116 @@ } ], "enums": [], - "misc": [], - "objects": [] + "misc": [ + { + "parentPluginId": "files", + "id": "def-public.FilesClientResponses", + "type": "Type", + "tags": [], + "label": "FilesClientResponses", + "description": [], + "signature": [ + "{ create: { file: ", + { + "pluginId": "files", + "scope": "common", + "docId": "kibFilesPluginApi", + "section": "def-common.FileJSON", + "text": "FileJSON" + }, + "; }; delete: { ok: true; }; getById: { file: ", + { + "pluginId": "files", + "scope": "common", + "docId": "kibFilesPluginApi", + "section": "def-common.FileJSON", + "text": "FileJSON" + }, + "; }; list: { files: ", + { + "pluginId": "files", + "scope": "common", + "docId": "kibFilesPluginApi", + "section": "def-common.FileJSON", + "text": "FileJSON" + }, + "[]; }; find: { files: ", + { + "pluginId": "files", + "scope": "common", + "docId": "kibFilesPluginApi", + "section": "def-common.FileJSON", + "text": "FileJSON" + }, + "[]; }; update: { file: ", + { + "pluginId": "files", + "scope": "common", + "docId": "kibFilesPluginApi", + "section": "def-common.FileJSON", + "text": "FileJSON" + }, + "; }; upload: { ok: true; size: number; }; download: any; share: ", + { + "pluginId": "files", + "scope": "common", + "docId": "kibFilesPluginApi", + "section": "def-common.FileShareJSON", + "text": "FileShareJSON" + }, + " & { token: string; }; unshare: { ok: true; }; getShare: { share: ", + { + "pluginId": "files", + "scope": "common", + "docId": "kibFilesPluginApi", + "section": "def-common.FileShareJSON", + "text": "FileShareJSON" + }, + "; }; listShares: { shares: ", + { + "pluginId": "files", + "scope": "common", + "docId": "kibFilesPluginApi", + "section": "def-common.FileShareJSON", + "text": "FileShareJSON" + }, + "[]; }; getMetrics: ", + { + "pluginId": "files", + "scope": "common", + "docId": "kibFilesPluginApi", + "section": "def-common.FilesMetrics", + "text": "FilesMetrics" + }, + "; publicDownload: any; getDownloadHref: string; }" + ], + "path": "x-pack/plugins/files/public/types.ts", + "deprecated": false, + "initialIsOpen": false + } + ], + "objects": [], + "start": { + "parentPluginId": "files", + "id": "def-public.FilesStart", + "type": "Type", + "tags": [], + "label": "FilesStart", + "description": [], + "signature": [ + { + "pluginId": "files", + "scope": "public", + "docId": "kibFilesPluginApi", + "section": "def-public.FilesSetup", + "text": "FilesSetup" + } + ], + "path": "x-pack/plugins/files/public/plugin.ts", + "deprecated": false, + "lifecycle": "start", + "initialIsOpen": true + } }, "server": { "classes": [], @@ -801,7 +956,9 @@ "TransportRequestOptions", " | undefined): Promise<", "WriteResponseBase", - ">; }; name: string | symbol; transform: ", + ">; }; cluster: ", + "default", + "; eql: ", "default", "; search: { >; }; cluster: ", - "default", - "; eql: ", - "default", - "; create: { (this: That, params: ", + ">; }; create: { (this: That, params: ", "CreateRequest", " | ", "CreateRequest", @@ -869,7 +1022,7 @@ "default", "; security: ", "default", - "; index: { (this: That, params: ", + "; name: string | symbol; index: { (this: That, params: ", "IndexRequest", " | ", "IndexRequest", @@ -1881,6 +2034,8 @@ "TermvectorsResponse", ">; }; textStructure: ", "default", + "; transform: ", + "default", "; updateByQuery: { (this: That, params: ", "UpdateByQueryRequest", " | ", @@ -2218,22 +2373,12 @@ "children": [ { "parentPluginId": "files", - "id": "def-server.DeleteForFileArgs.file", - "type": "Object", + "id": "def-server.DeleteForFileArgs.id", + "type": "string", "tags": [], - "label": "file", + "label": "id", "description": [ - "\nThe file object to delete the shares for." - ], - "signature": [ - { - "pluginId": "files", - "scope": "common", - "docId": "kibFilesPluginApi", - "section": "def-common.File", - "text": "File" - }, - "" + "\nThe file id to delete the shares for." ], "path": "x-pack/plugins/files/server/file_share_service/internal_file_share_service.ts", "deprecated": false @@ -2250,7 +2395,7 @@ "description": [ "\nWraps the {@link FileMetadataClient} and {@link BlobStorageClient} client\nto provide basic file CRUD functionality.\n\nFor now this is just a shallow type of the implementation for export purposes." ], - "path": "x-pack/plugins/files/server/file_client/file_client.ts", + "path": "x-pack/plugins/files/server/file_client/types.ts", "deprecated": false, "children": [ { @@ -2262,7 +2407,7 @@ "description": [ "See {@link FileMetadata.FileKind}." ], - "path": "x-pack/plugins/files/server/file_client/file_client.ts", + "path": "x-pack/plugins/files/server/file_client/types.ts", "deprecated": false }, { @@ -2275,19 +2420,19 @@ "\nSee {@link FileMetadataClient.create}.\n" ], "signature": [ - "(arg: ", + "(arg: ", "CreateArgs", ") => Promise<", { "pluginId": "files", - "scope": "server", + "scope": "common", "docId": "kibFilesPluginApi", - "section": "def-server.FileDescriptor", - "text": "FileDescriptor" + "section": "def-common.File", + "text": "File" }, - ">" + ">" ], - "path": "x-pack/plugins/files/server/file_client/file_client.ts", + "path": "x-pack/plugins/files/server/file_client/types.ts", "deprecated": false, "children": [ { @@ -2302,7 +2447,7 @@ "signature": [ "CreateArgs" ], - "path": "x-pack/plugins/files/server/file_client/file_client.ts", + "path": "x-pack/plugins/files/server/file_client/types.ts", "deprecated": false, "isRequired": true } @@ -2319,7 +2464,7 @@ "\nSee {@link FileMetadataClient.get}\n" ], "signature": [ - "(arg: ", + "(arg: ", { "pluginId": "files", "scope": "server", @@ -2330,16 +2475,15 @@ ") => Promise<", { "pluginId": "files", - "scope": "server", + "scope": "common", "docId": "kibFilesPluginApi", - "section": "def-server.FileDescriptor", - "text": "FileDescriptor" + "section": "def-common.File", + "text": "File" }, - ">" + ">" ], - "path": "x-pack/plugins/files/server/file_client/file_client.ts", + "path": "x-pack/plugins/files/server/file_client/types.ts", "deprecated": false, - "returnComment": [], "children": [ { "parentPluginId": "files", @@ -2359,10 +2503,12 @@ "text": "GetArg" } ], - "path": "x-pack/plugins/files/server/file_client/file_metadata_client/file_metadata_client.ts", - "deprecated": false + "path": "x-pack/plugins/files/server/file_client/types.ts", + "deprecated": false, + "isRequired": true } - ] + ], + "returnComment": [] }, { "parentPluginId": "files", @@ -2374,51 +2520,60 @@ "\n{@link FileMetadataClient.update}\n" ], "signature": [ - "(arg: ", + "(id: string, metadata: ", { "pluginId": "files", - "scope": "server", - "docId": "kibFilesPluginApi", - "section": "def-server.UpdateArgs", - "text": "UpdateArgs" - }, - ") => Promise<", - { - "pluginId": "files", - "scope": "server", + "scope": "common", "docId": "kibFilesPluginApi", - "section": "def-server.FileDescriptor", - "text": "FileDescriptor" + "section": "def-common.UpdatableFileMetadata", + "text": "UpdatableFileMetadata" }, - ">" + ") => Promise" ], - "path": "x-pack/plugins/files/server/file_client/file_client.ts", + "path": "x-pack/plugins/files/server/file_client/types.ts", "deprecated": false, - "returnComment": [], "children": [ { "parentPluginId": "files", "id": "def-server.FileClient.update.$1", + "type": "string", + "tags": [], + "label": "id", + "description": [ + "- File id" + ], + "signature": [ + "string" + ], + "path": "x-pack/plugins/files/server/file_client/types.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "files", + "id": "def-server.FileClient.update.$2", "type": "Object", "tags": [], - "label": "arg", + "label": "metadata", "description": [ - "- Argument to get a file" + "- new file metadata" ], "signature": [ { "pluginId": "files", - "scope": "server", + "scope": "common", "docId": "kibFilesPluginApi", - "section": "def-server.UpdateArgs", - "text": "UpdateArgs" + "section": "def-common.UpdatableFileMetadata", + "text": "UpdatableFileMetadata" }, - "" + "" ], - "path": "x-pack/plugins/files/server/file_client/file_metadata_client/file_metadata_client.ts", - "deprecated": false + "path": "x-pack/plugins/files/server/file_client/types.ts", + "deprecated": false, + "isRequired": true } - ] + ], + "returnComment": [] }, { "parentPluginId": "files", @@ -2440,7 +2595,7 @@ }, ") => Promise" ], - "path": "x-pack/plugins/files/server/file_client/file_client.ts", + "path": "x-pack/plugins/files/server/file_client/types.ts", "deprecated": false, "children": [ { @@ -2461,43 +2616,13 @@ "text": "DeleteArgs" } ], - "path": "x-pack/plugins/files/server/file_client/file_client.ts", + "path": "x-pack/plugins/files/server/file_client/types.ts", "deprecated": false, "isRequired": true } ], "returnComment": [] }, - { - "parentPluginId": "files", - "id": "def-server.FileClient.deleteContent", - "type": "Function", - "tags": [], - "label": "deleteContent", - "description": [ - "\nSee {@link BlobStorageClient.delete}\n" - ], - "signature": [ - "(id: string) => Promise" - ], - "path": "x-pack/plugins/files/server/file_client/file_client.ts", - "deprecated": false, - "returnComment": [], - "children": [ - { - "parentPluginId": "files", - "id": "def-server.FileClient.deleteContent.$1", - "type": "string", - "tags": [], - "label": "id", - "description": [ - "- Argument to delete a file" - ], - "path": "x-pack/plugins/files/server/blob_storage_service/types.ts", - "deprecated": false - } - ] - }, { "parentPluginId": "files", "id": "def-server.FileClient.list", @@ -2519,16 +2644,15 @@ " | undefined) => Promise<", { "pluginId": "files", - "scope": "server", + "scope": "common", "docId": "kibFilesPluginApi", - "section": "def-server.FileDescriptor", - "text": "FileDescriptor" + "section": "def-common.File", + "text": "File" }, "[]>" ], - "path": "x-pack/plugins/files/server/file_client/file_client.ts", + "path": "x-pack/plugins/files/server/file_client/types.ts", "deprecated": false, - "returnComment": [], "children": [ { "parentPluginId": "files", @@ -2549,10 +2673,12 @@ }, " | undefined" ], - "path": "x-pack/plugins/files/server/file_client/file_metadata_client/file_metadata_client.ts", - "deprecated": false + "path": "x-pack/plugins/files/server/file_client/types.ts", + "deprecated": false, + "isRequired": false } - ] + ], + "returnComment": [] }, { "parentPluginId": "files", @@ -2575,16 +2701,15 @@ ") => Promise<", { "pluginId": "files", - "scope": "server", + "scope": "common", "docId": "kibFilesPluginApi", - "section": "def-server.FileDescriptor", - "text": "FileDescriptor" + "section": "def-common.File", + "text": "File" }, "[]>" ], - "path": "x-pack/plugins/files/server/file_client/file_client.ts", + "path": "x-pack/plugins/files/server/file_client/types.ts", "deprecated": false, - "returnComment": [], "children": [ { "parentPluginId": "files", @@ -2604,113 +2729,147 @@ "text": "FindFileArgs" } ], - "path": "x-pack/plugins/files/server/file_client/file_metadata_client/file_metadata_client.ts", - "deprecated": false + "path": "x-pack/plugins/files/server/file_client/types.ts", + "deprecated": false, + "isRequired": true } - ] + ], + "returnComment": [] }, { "parentPluginId": "files", - "id": "def-server.FileClient.upload", + "id": "def-server.FileClient.share", "type": "Function", - "tags": [], - "label": "upload", + "tags": [ + "note" + ], + "label": "share", "description": [ - "\nSee {@link BlobStorageClient.upload}\n" + "\nCreate a file share instance for this file.\n" ], "signature": [ - "(id: string, rs: ", - "Readable", - ", opts?: ", - "UploadOptions", - " | undefined) => Promise<{ id: string; size: number; }>" + "(args: ", + "ShareArgs", + ") => Promise<", + { + "pluginId": "files", + "scope": "common", + "docId": "kibFilesPluginApi", + "section": "def-common.FileShareJSONWithToken", + "text": "FileShareJSONWithToken" + }, + ">" ], - "path": "x-pack/plugins/files/server/file_client/file_client.ts", + "path": "x-pack/plugins/files/server/file_client/types.ts", "deprecated": false, "children": [ { "parentPluginId": "files", - "id": "def-server.FileClient.upload.$1", - "type": "string", - "tags": [], - "label": "id", - "description": [ - "- Readable stream to upload" - ], - "signature": [ - "string" - ], - "path": "x-pack/plugins/files/server/file_client/file_client.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "files", - "id": "def-server.FileClient.upload.$2", + "id": "def-server.FileClient.share.$1", "type": "Object", "tags": [], - "label": "rs", + "label": "args", "description": [ - "- Readable stream to upload" + "- Arguments to create a file share" ], "signature": [ - "Readable" + "ShareArgs" ], - "path": "x-pack/plugins/files/server/file_client/file_client.ts", + "path": "x-pack/plugins/files/server/file_client/types.ts", "deprecated": false, "isRequired": true - }, + } + ], + "returnComment": [] + }, + { + "parentPluginId": "files", + "id": "def-server.FileClient.unshare", + "type": "Function", + "tags": [ + "note" + ], + "label": "unshare", + "description": [ + "\nCreate a file share instance for this file.\n" + ], + "signature": [ + "(args: IdArg) => Promise" + ], + "path": "x-pack/plugins/files/server/file_client/types.ts", + "deprecated": false, + "returnComment": [], + "children": [ { "parentPluginId": "files", - "id": "def-server.FileClient.upload.$3", + "id": "def-server.FileClient.unshare.$1", "type": "Object", "tags": [], - "label": "opts", + "label": "args", "description": [ - "- Argument for uploads" + "- Arguments to remove a file share" ], "signature": [ - "UploadOptions", - " | undefined" + "IdArg" ], - "path": "x-pack/plugins/files/server/file_client/file_client.ts", - "deprecated": false, - "isRequired": false + "path": "x-pack/plugins/files/server/file_share_service/types.ts", + "deprecated": false } - ], - "returnComment": [] + ] }, { "parentPluginId": "files", - "id": "def-server.FileClient.download", + "id": "def-server.FileClient.listShares", "type": "Function", - "tags": [], - "label": "download", + "tags": [ + "note" + ], + "label": "listShares", "description": [ - "\nSee {@link BlobStorageClient.download}\n" + "\nCreate a file share instance for this file.\n" ], "signature": [ - "(args: { id: string; size?: number | undefined; }) => Promise<", - "Readable", - ">" + "(arg: ", + { + "pluginId": "files", + "scope": "server", + "docId": "kibFilesPluginApi", + "section": "def-server.ListArgs", + "text": "ListArgs" + }, + ") => Promise<{ shares: ", + { + "pluginId": "files", + "scope": "common", + "docId": "kibFilesPluginApi", + "section": "def-common.FileShareJSON", + "text": "FileShareJSON" + }, + "[]; }>" ], - "path": "x-pack/plugins/files/server/file_client/file_client.ts", + "path": "x-pack/plugins/files/server/file_client/types.ts", "deprecated": false, "returnComment": [], "children": [ { "parentPluginId": "files", - "id": "def-server.FileClient.download.$1", + "id": "def-server.FileClient.listShares.$1", "type": "Object", "tags": [], - "label": "args", + "label": "arg", "description": [ - "- to download a file" + "- Arguments to remove a file share" ], "signature": [ - "{ id: string; size?: number | undefined; }" + { + "pluginId": "files", + "scope": "server", + "docId": "kibFilesPluginApi", + "section": "def-server.ListArgs", + "text": "ListArgs" + } ], - "path": "x-pack/plugins/files/server/blob_storage_service/types.ts", + "path": "x-pack/plugins/files/server/file_share_service/types.ts", "deprecated": false } ] @@ -3352,7 +3511,7 @@ "\nUpdate updatable file attributes like name and meta.\n" ], "signature": [ - "(args: ", + "(args: ", { "pluginId": "files", "scope": "server", @@ -3360,15 +3519,7 @@ "section": "def-server.UpdateFileArgs", "text": "UpdateFileArgs" }, - ") => Promise<", - { - "pluginId": "files", - "scope": "common", - "docId": "kibFilesPluginApi", - "section": "def-common.File", - "text": "File" - }, - ">" + ") => Promise" ], "path": "x-pack/plugins/files/server/file_service/file_service.ts", "deprecated": false, @@ -4803,19 +4954,45 @@ "section": "def-common.File", "text": "File" }, - " extends ", - { - "pluginId": "files", - "scope": "common", - "docId": "kibFilesPluginApi", - "section": "def-common.FileJSON", - "text": "FileJSON" - }, "" ], "path": "x-pack/plugins/files/common/types.ts", "deprecated": false, "children": [ + { + "parentPluginId": "files", + "id": "def-common.File.id", + "type": "string", + "tags": [], + "label": "id", + "description": [ + "\nThe file ID" + ], + "path": "x-pack/plugins/files/common/types.ts", + "deprecated": false + }, + { + "parentPluginId": "files", + "id": "def-common.File.data", + "type": "Object", + "tags": [], + "label": "data", + "description": [ + "\nFile metadata in camelCase form." + ], + "signature": [ + { + "pluginId": "files", + "scope": "common", + "docId": "kibFilesPluginApi", + "section": "def-common.FileJSON", + "text": "FileJSON" + }, + "" + ], + "path": "x-pack/plugins/files/common/types.ts", + "deprecated": false + }, { "parentPluginId": "files", "id": "def-common.File.update", @@ -4886,7 +5063,15 @@ "signature": [ "(content: ", "Readable", - ") => Promise" + ") => Promise<", + { + "pluginId": "files", + "scope": "common", + "docId": "kibFilesPluginApi", + "section": "def-common.File", + "text": "File" + }, + ">" ], "path": "x-pack/plugins/files/common/types.ts", "deprecated": false, @@ -5319,10 +5504,12 @@ "parentPluginId": "files", "id": "def-common.FileKind.maxSizeBytes", "type": "number", - "tags": [], + "tags": [ + "default" + ], "label": "maxSizeBytes", "description": [ - "\nMaximum size, in bytes, a file of this kind can be." + "\nMaximum size, in bytes, a file of this kind can be.\n" ], "signature": [ "number | undefined" diff --git a/api_docs/files.mdx b/api_docs/files.mdx index 4ee1ba78dd7912..d3b2685131c82e 100644 --- a/api_docs/files.mdx +++ b/api_docs/files.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/files title: "files" image: https://source.unsplash.com/400x175/?github description: API docs for the files plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'files'] --- import filesObj from './files.devdocs.json'; @@ -21,13 +21,19 @@ Contact [@elastic/kibana-app-services](https://github.com/orgs/elastic/teams/tea | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 236 | 0 | 3 | 2 | +| 243 | 0 | 6 | 2 | ## Client +### Start + + ### Interfaces +### Consts, variables and types + + ## Server ### Setup diff --git a/api_docs/fleet.devdocs.json b/api_docs/fleet.devdocs.json index ca2f3009b30327..3f9ade60240177 100644 --- a/api_docs/fleet.devdocs.json +++ b/api_docs/fleet.devdocs.json @@ -3933,7 +3933,7 @@ "signature": [ "(soClient: ", "SavedObjectsClientContract", - ", ids: string[], options?: { fields?: string[] | undefined; }) => Promise<", + ", ids: string[], options?: { fields?: string[] | undefined; withPackagePolicies?: boolean | undefined; ignoreMissing?: boolean | undefined; }) => Promise<", { "pluginId": "fleet", "scope": "common", @@ -3981,7 +3981,7 @@ "label": "options", "description": [], "signature": [ - "{ fields?: string[] | undefined; }" + "{ fields?: string[] | undefined; withPackagePolicies?: boolean | undefined; ignoreMissing?: boolean | undefined; }" ], "path": "x-pack/plugins/fleet/server/services/agent_policy.ts", "deprecated": false @@ -5302,6 +5302,60 @@ ], "returnComment": [] }, + { + "parentPluginId": "fleet", + "id": "def-server.PackagePolicyServiceInterface.findAllForAgentPolicy", + "type": "Function", + "tags": [], + "label": "findAllForAgentPolicy", + "description": [], + "signature": [ + "(soClient: ", + "SavedObjectsClientContract", + ", agentPolicyId: string) => Promise<", + { + "pluginId": "fleet", + "scope": "common", + "docId": "kibFleetPluginApi", + "section": "def-common.PackagePolicy", + "text": "PackagePolicy" + }, + "[]>" + ], + "path": "x-pack/plugins/fleet/server/services/package_policy.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "fleet", + "id": "def-server.PackagePolicyServiceInterface.findAllForAgentPolicy.$1", + "type": "Object", + "tags": [], + "label": "soClient", + "description": [], + "signature": [ + "SavedObjectsClientContract" + ], + "path": "x-pack/plugins/fleet/server/services/package_policy.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "fleet", + "id": "def-server.PackagePolicyServiceInterface.findAllForAgentPolicy.$2", + "type": "string", + "tags": [], + "label": "agentPolicyId", + "description": [], + "signature": [ + "string" + ], + "path": "x-pack/plugins/fleet/server/services/package_policy.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, { "parentPluginId": "fleet", "id": "def-server.PackagePolicyServiceInterface.getByIDs", @@ -5312,7 +5366,7 @@ "signature": [ "(soClient: ", "SavedObjectsClientContract", - ", ids: string[]) => Promise<", + ", ids: string[], options?: { ignoreMissing?: boolean | undefined; } | undefined) => Promise<", { "pluginId": "fleet", "scope": "common", @@ -5352,6 +5406,31 @@ "path": "x-pack/plugins/fleet/server/services/package_policy.ts", "deprecated": false, "isRequired": true + }, + { + "parentPluginId": "fleet", + "id": "def-server.PackagePolicyServiceInterface.getByIDs.$3", + "type": "Object", + "tags": [], + "label": "options", + "description": [], + "path": "x-pack/plugins/fleet/server/services/package_policy.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "fleet", + "id": "def-server.PackagePolicyServiceInterface.getByIDs.$3.ignoreMissing", + "type": "CompoundType", + "tags": [], + "label": "ignoreMissing", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "x-pack/plugins/fleet/server/services/package_policy.ts", + "deprecated": false + } + ] } ], "returnComment": [] @@ -7437,12 +7516,11 @@ { "parentPluginId": "fleet", "id": "def-common.AgentPolicy.package_policies", - "type": "CompoundType", + "type": "Array", "tags": [], "label": "package_policies", "description": [], "signature": [ - "string[] | ", { "pluginId": "fleet", "scope": "common", @@ -7450,7 +7528,7 @@ "section": "def-common.PackagePolicy", "text": "PackagePolicy" }, - "[]" + "[] | undefined" ], "path": "x-pack/plugins/fleet/common/types/models/agent_policy.ts", "deprecated": false @@ -12842,6 +12920,52 @@ "deprecated": false, "initialIsOpen": false }, + { + "parentPluginId": "fleet", + "id": "def-common.BulkGetAgentPoliciesResponse", + "type": "Type", + "tags": [], + "label": "BulkGetAgentPoliciesResponse", + "description": [], + "signature": [ + "BulkGetResult", + "<", + { + "pluginId": "fleet", + "scope": "common", + "docId": "kibFleetPluginApi", + "section": "def-common.GetAgentPoliciesResponseItem", + "text": "GetAgentPoliciesResponseItem" + }, + ">" + ], + "path": "x-pack/plugins/fleet/common/types/rest_spec/agent_policy.ts", + "deprecated": false, + "initialIsOpen": false + }, + { + "parentPluginId": "fleet", + "id": "def-common.BulkGetPackagePoliciesResponse", + "type": "Type", + "tags": [], + "label": "BulkGetPackagePoliciesResponse", + "description": [], + "signature": [ + "BulkGetResult", + "<", + { + "pluginId": "fleet", + "scope": "common", + "docId": "kibFleetPluginApi", + "section": "def-common.PackagePolicy", + "text": "PackagePolicy" + }, + ">" + ], + "path": "x-pack/plugins/fleet/common/types/rest_spec/package_policy.ts", + "deprecated": false, + "initialIsOpen": false + }, { "parentPluginId": "fleet", "id": "def-common.DeletePackagePoliciesResponse", @@ -13933,7 +14057,7 @@ "label": "RegistrySearchResult", "description": [], "signature": [ - "{ type?: \"integration\" | undefined; path: string; name: string; version: string; title: string; download: string; description: string; icons?: (", + "{ type?: \"integration\" | undefined; path: string; download: string; title: string; description: string; icons?: (", { "pluginId": "fleet", "scope": "common", @@ -13957,7 +14081,7 @@ "section": "def-common.PackageSpecCategory", "text": "PackageSpecCategory" }, - " | undefined)[] | undefined; internal?: boolean | undefined; release?: \"experimental\" | \"beta\" | \"ga\" | undefined; policy_templates?: ", + " | undefined)[] | undefined; name: string; version: string; internal?: boolean | undefined; release?: \"experimental\" | \"beta\" | \"ga\" | undefined; policy_templates?: ", { "pluginId": "fleet", "scope": "common", @@ -14292,6 +14416,16 @@ "path": "x-pack/plugins/fleet/common/constants/routes.ts", "deprecated": false }, + { + "parentPluginId": "fleet", + "id": "def-common.AGENT_POLICY_API_ROUTES.BULK_GET_PATTERN", + "type": "string", + "tags": [], + "label": "BULK_GET_PATTERN", + "description": [], + "path": "x-pack/plugins/fleet/common/constants/routes.ts", + "deprecated": false + }, { "parentPluginId": "fleet", "id": "def-common.AGENT_POLICY_API_ROUTES.INFO_PATTERN", @@ -14390,6 +14524,21 @@ "children": [], "returnComment": [] }, + { + "parentPluginId": "fleet", + "id": "def-common.agentPolicyRouteService.getBulkGetPath", + "type": "Function", + "tags": [], + "label": "getBulkGetPath", + "description": [], + "signature": [ + "() => string" + ], + "path": "x-pack/plugins/fleet/common/services/routes.ts", + "deprecated": false, + "children": [], + "returnComment": [] + }, { "parentPluginId": "fleet", "id": "def-common.agentPolicyRouteService.getInfoPath", @@ -15641,6 +15790,16 @@ "path": "x-pack/plugins/fleet/common/constants/routes.ts", "deprecated": false }, + { + "parentPluginId": "fleet", + "id": "def-common.PACKAGE_POLICY_API_ROUTES.BULK_GET_PATTERN", + "type": "string", + "tags": [], + "label": "BULK_GET_PATTERN", + "description": [], + "path": "x-pack/plugins/fleet/common/constants/routes.ts", + "deprecated": false + }, { "parentPluginId": "fleet", "id": "def-common.PACKAGE_POLICY_API_ROUTES.INFO_PATTERN", diff --git a/api_docs/fleet.mdx b/api_docs/fleet.mdx index 72ce43f8bc0ca0..ad7e65aede44cd 100644 --- a/api_docs/fleet.mdx +++ b/api_docs/fleet.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/fleet title: "fleet" image: https://source.unsplash.com/400x175/?github description: API docs for the fleet plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'fleet'] --- import fleetObj from './fleet.devdocs.json'; @@ -21,7 +21,7 @@ Contact [Fleet](https://github.com/orgs/elastic/teams/fleet) for questions regar | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 957 | 3 | 862 | 9 | +| 967 | 3 | 872 | 10 | ## Client diff --git a/api_docs/global_search.mdx b/api_docs/global_search.mdx index b870873315862c..e575be7d5b39c3 100644 --- a/api_docs/global_search.mdx +++ b/api_docs/global_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/globalSearch title: "globalSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the globalSearch plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'globalSearch'] --- import globalSearchObj from './global_search.devdocs.json'; diff --git a/api_docs/home.devdocs.json b/api_docs/home.devdocs.json index 14a039d123e3da..907464f15b49ba 100644 --- a/api_docs/home.devdocs.json +++ b/api_docs/home.devdocs.json @@ -375,7 +375,7 @@ "{@link FeatureCatalogueCategory} to display this feature in." ], "signature": [ - "\"other\" | \"data\" | \"admin\"" + "\"data\" | \"other\" | \"admin\"" ], "path": "src/plugins/home/public/services/feature_catalogue/feature_catalogue_registry.ts", "deprecated": false @@ -708,7 +708,7 @@ "label": "FeatureCatalogueCategory", "description": [], "signature": [ - "\"other\" | \"data\" | \"admin\"" + "\"data\" | \"other\" | \"admin\"" ], "path": "src/plugins/home/public/services/feature_catalogue/feature_catalogue_registry.ts", "deprecated": false, @@ -1598,7 +1598,7 @@ "label": "InstructionSetSchema", "description": [], "signature": [ - "{ readonly title?: string | undefined; readonly callOut?: Readonly<{ message?: string | undefined; iconType?: string | undefined; } & { title: string; }> | undefined; readonly statusCheck?: Readonly<{ error?: string | undefined; title?: string | undefined; success?: string | undefined; text?: string | undefined; btnLabel?: string | undefined; } & { esHitsCheck: Readonly<{} & { query: Record; index: string | string[]; }>; }> | undefined; readonly instructionVariants: Readonly<{ initialSelected?: boolean | undefined; } & { id: string; instructions: Readonly<{ title?: string | undefined; commands?: string[] | undefined; textPre?: string | undefined; textPost?: string | undefined; customComponentName?: string | undefined; } & {}>[]; }>[]; }" + "{ readonly title?: string | undefined; readonly callOut?: Readonly<{ message?: string | undefined; iconType?: string | undefined; } & { title: string; }> | undefined; readonly statusCheck?: Readonly<{ error?: string | undefined; success?: string | undefined; text?: string | undefined; title?: string | undefined; btnLabel?: string | undefined; } & { esHitsCheck: Readonly<{} & { query: Record; index: string | string[]; }>; }> | undefined; readonly instructionVariants: Readonly<{ initialSelected?: boolean | undefined; } & { id: string; instructions: Readonly<{ title?: string | undefined; commands?: string[] | undefined; textPre?: string | undefined; textPost?: string | undefined; customComponentName?: string | undefined; } & {}>[]; }>[]; }" ], "path": "src/plugins/home/server/services/tutorials/lib/tutorial_schema.ts", "deprecated": false, @@ -1612,7 +1612,7 @@ "label": "InstructionsSchema", "description": [], "signature": [ - "{ readonly params?: Readonly<{ defaultValue?: any; } & { type: \"string\" | \"number\"; id: string; label: string; }>[] | undefined; readonly instructionSets: Readonly<{ title?: string | undefined; callOut?: Readonly<{ message?: string | undefined; iconType?: string | undefined; } & { title: string; }> | undefined; statusCheck?: Readonly<{ error?: string | undefined; title?: string | undefined; success?: string | undefined; text?: string | undefined; btnLabel?: string | undefined; } & { esHitsCheck: Readonly<{} & { query: Record; index: string | string[]; }>; }> | undefined; } & { instructionVariants: Readonly<{ initialSelected?: boolean | undefined; } & { id: string; instructions: Readonly<{ title?: string | undefined; commands?: string[] | undefined; textPre?: string | undefined; textPost?: string | undefined; customComponentName?: string | undefined; } & {}>[]; }>[]; }>[]; }" + "{ readonly params?: Readonly<{ defaultValue?: any; } & { type: \"string\" | \"number\"; label: string; id: string; }>[] | undefined; readonly instructionSets: Readonly<{ title?: string | undefined; callOut?: Readonly<{ message?: string | undefined; iconType?: string | undefined; } & { title: string; }> | undefined; statusCheck?: Readonly<{ error?: string | undefined; success?: string | undefined; text?: string | undefined; title?: string | undefined; btnLabel?: string | undefined; } & { esHitsCheck: Readonly<{} & { query: Record; index: string | string[]; }>; }> | undefined; } & { instructionVariants: Readonly<{ initialSelected?: boolean | undefined; } & { id: string; instructions: Readonly<{ title?: string | undefined; commands?: string[] | undefined; textPre?: string | undefined; textPost?: string | undefined; customComponentName?: string | undefined; } & {}>[]; }>[]; }>[]; }" ], "path": "src/plugins/home/server/services/tutorials/lib/tutorial_schema.ts", "deprecated": false, @@ -1628,7 +1628,7 @@ "signature": [ "{ getSampleDatasets: () => ", "Writable", - "[]; previewImagePath: string; overviewDashboard: string; defaultIndex: string; dataIndices: Readonly<{} & { id: string; fields: Record; timeFields: string[]; dataPath: string; currentTimeMarker: string; preserveDayOfWeekTimeOfDay: boolean; }>[]; }>>[]; addSavedObjectsToSampleDataset: (id: string, savedObjects: ", + "[]; previewImagePath: string; overviewDashboard: string; defaultIndex: string; dataIndices: Readonly<{} & { id: string; fields: Record; timeFields: string[]; dataPath: string; currentTimeMarker: string; preserveDayOfWeekTimeOfDay: boolean; }>[]; }>>[]; addSavedObjectsToSampleDataset: (id: string, savedObjects: ", "SavedObject", "[]) => void; addAppLinksToSampleDataset: (id: string, appLinks: ", { @@ -1662,7 +1662,7 @@ "signature": [ "() => ", "Writable", - "[]; previewImagePath: string; overviewDashboard: string; defaultIndex: string; dataIndices: Readonly<{} & { id: string; fields: Record; timeFields: string[]; dataPath: string; currentTimeMarker: string; preserveDayOfWeekTimeOfDay: boolean; }>[]; }>>" + "[]; previewImagePath: string; overviewDashboard: string; defaultIndex: string; dataIndices: Readonly<{} & { id: string; fields: Record; timeFields: string[]; dataPath: string; currentTimeMarker: string; preserveDayOfWeekTimeOfDay: boolean; }>[]; }>>" ], "path": "src/plugins/home/server/services/sample_data/lib/sample_dataset_registry_types.ts", "deprecated": false, @@ -1716,7 +1716,7 @@ "section": "def-server.TutorialContext", "text": "TutorialContext" }, - ") => Readonly<{ isBeta?: boolean | undefined; savedObjects?: any[] | undefined; euiIconType?: string | undefined; previewImagePath?: string | undefined; moduleName?: string | undefined; completionTimeMinutes?: number | undefined; elasticCloud?: Readonly<{ params?: Readonly<{ defaultValue?: any; } & { type: \"string\" | \"number\"; id: string; label: string; }>[] | undefined; } & { instructionSets: Readonly<{ title?: string | undefined; callOut?: Readonly<{ message?: string | undefined; iconType?: string | undefined; } & { title: string; }> | undefined; statusCheck?: Readonly<{ error?: string | undefined; title?: string | undefined; success?: string | undefined; text?: string | undefined; btnLabel?: string | undefined; } & { esHitsCheck: Readonly<{} & { query: Record; index: string | string[]; }>; }> | undefined; } & { instructionVariants: Readonly<{ initialSelected?: boolean | undefined; } & { id: string; instructions: Readonly<{ title?: string | undefined; commands?: string[] | undefined; textPre?: string | undefined; textPost?: string | undefined; customComponentName?: string | undefined; } & {}>[]; }>[]; }>[]; }> | undefined; onPremElasticCloud?: Readonly<{ params?: Readonly<{ defaultValue?: any; } & { type: \"string\" | \"number\"; id: string; label: string; }>[] | undefined; } & { instructionSets: Readonly<{ title?: string | undefined; callOut?: Readonly<{ message?: string | undefined; iconType?: string | undefined; } & { title: string; }> | undefined; statusCheck?: Readonly<{ error?: string | undefined; title?: string | undefined; success?: string | undefined; text?: string | undefined; btnLabel?: string | undefined; } & { esHitsCheck: Readonly<{} & { query: Record; index: string | string[]; }>; }> | undefined; } & { instructionVariants: Readonly<{ initialSelected?: boolean | undefined; } & { id: string; instructions: Readonly<{ title?: string | undefined; commands?: string[] | undefined; textPre?: string | undefined; textPost?: string | undefined; customComponentName?: string | undefined; } & {}>[]; }>[]; }>[]; }> | undefined; artifacts?: Readonly<{ application?: Readonly<{} & { path: string; label: string; }> | undefined; exportedFields?: Readonly<{} & { documentationUrl: string; }> | undefined; } & { dashboards: Readonly<{ linkLabel?: string | undefined; } & { id: string; isOverview: boolean; }>[]; }> | undefined; savedObjectsInstallMsg?: string | undefined; customStatusCheckName?: string | undefined; integrationBrowserCategories?: string[] | undefined; eprPackageOverlap?: string | undefined; } & { id: string; name: string; category: \"other\" | \"security\" | \"metrics\" | \"logging\"; shortDescription: string; longDescription: string; onPrem: Readonly<{ params?: Readonly<{ defaultValue?: any; } & { type: \"string\" | \"number\"; id: string; label: string; }>[] | undefined; } & { instructionSets: Readonly<{ title?: string | undefined; callOut?: Readonly<{ message?: string | undefined; iconType?: string | undefined; } & { title: string; }> | undefined; statusCheck?: Readonly<{ error?: string | undefined; title?: string | undefined; success?: string | undefined; text?: string | undefined; btnLabel?: string | undefined; } & { esHitsCheck: Readonly<{} & { query: Record; index: string | string[]; }>; }> | undefined; } & { instructionVariants: Readonly<{ initialSelected?: boolean | undefined; } & { id: string; instructions: Readonly<{ title?: string | undefined; commands?: string[] | undefined; textPre?: string | undefined; textPost?: string | undefined; customComponentName?: string | undefined; } & {}>[]; }>[]; }>[]; }>; }>" + ") => Readonly<{ isBeta?: boolean | undefined; savedObjects?: any[] | undefined; euiIconType?: string | undefined; previewImagePath?: string | undefined; moduleName?: string | undefined; completionTimeMinutes?: number | undefined; elasticCloud?: Readonly<{ params?: Readonly<{ defaultValue?: any; } & { type: \"string\" | \"number\"; label: string; id: string; }>[] | undefined; } & { instructionSets: Readonly<{ title?: string | undefined; callOut?: Readonly<{ message?: string | undefined; iconType?: string | undefined; } & { title: string; }> | undefined; statusCheck?: Readonly<{ error?: string | undefined; success?: string | undefined; text?: string | undefined; title?: string | undefined; btnLabel?: string | undefined; } & { esHitsCheck: Readonly<{} & { query: Record; index: string | string[]; }>; }> | undefined; } & { instructionVariants: Readonly<{ initialSelected?: boolean | undefined; } & { id: string; instructions: Readonly<{ title?: string | undefined; commands?: string[] | undefined; textPre?: string | undefined; textPost?: string | undefined; customComponentName?: string | undefined; } & {}>[]; }>[]; }>[]; }> | undefined; onPremElasticCloud?: Readonly<{ params?: Readonly<{ defaultValue?: any; } & { type: \"string\" | \"number\"; label: string; id: string; }>[] | undefined; } & { instructionSets: Readonly<{ title?: string | undefined; callOut?: Readonly<{ message?: string | undefined; iconType?: string | undefined; } & { title: string; }> | undefined; statusCheck?: Readonly<{ error?: string | undefined; success?: string | undefined; text?: string | undefined; title?: string | undefined; btnLabel?: string | undefined; } & { esHitsCheck: Readonly<{} & { query: Record; index: string | string[]; }>; }> | undefined; } & { instructionVariants: Readonly<{ initialSelected?: boolean | undefined; } & { id: string; instructions: Readonly<{ title?: string | undefined; commands?: string[] | undefined; textPre?: string | undefined; textPost?: string | undefined; customComponentName?: string | undefined; } & {}>[]; }>[]; }>[]; }> | undefined; artifacts?: Readonly<{ application?: Readonly<{} & { path: string; label: string; }> | undefined; exportedFields?: Readonly<{} & { documentationUrl: string; }> | undefined; } & { dashboards: Readonly<{ linkLabel?: string | undefined; } & { id: string; isOverview: boolean; }>[]; }> | undefined; savedObjectsInstallMsg?: string | undefined; customStatusCheckName?: string | undefined; integrationBrowserCategories?: string[] | undefined; eprPackageOverlap?: string | undefined; } & { id: string; name: string; category: \"other\" | \"security\" | \"metrics\" | \"logging\"; shortDescription: string; longDescription: string; onPrem: Readonly<{ params?: Readonly<{ defaultValue?: any; } & { type: \"string\" | \"number\"; label: string; id: string; }>[] | undefined; } & { instructionSets: Readonly<{ title?: string | undefined; callOut?: Readonly<{ message?: string | undefined; iconType?: string | undefined; } & { title: string; }> | undefined; statusCheck?: Readonly<{ error?: string | undefined; success?: string | undefined; text?: string | undefined; title?: string | undefined; btnLabel?: string | undefined; } & { esHitsCheck: Readonly<{} & { query: Record; index: string | string[]; }>; }> | undefined; } & { instructionVariants: Readonly<{ initialSelected?: boolean | undefined; } & { id: string; instructions: Readonly<{ title?: string | undefined; commands?: string[] | undefined; textPre?: string | undefined; textPost?: string | undefined; customComponentName?: string | undefined; } & {}>[]; }>[]; }>[]; }>; }>" ], "path": "src/plugins/home/server/services/tutorials/lib/tutorials_registry_types.ts", "deprecated": false, @@ -1752,7 +1752,7 @@ "label": "TutorialSchema", "description": [], "signature": [ - "{ readonly isBeta?: boolean | undefined; readonly savedObjects?: any[] | undefined; readonly euiIconType?: string | undefined; readonly previewImagePath?: string | undefined; readonly moduleName?: string | undefined; readonly completionTimeMinutes?: number | undefined; readonly elasticCloud?: Readonly<{ params?: Readonly<{ defaultValue?: any; } & { type: \"string\" | \"number\"; id: string; label: string; }>[] | undefined; } & { instructionSets: Readonly<{ title?: string | undefined; callOut?: Readonly<{ message?: string | undefined; iconType?: string | undefined; } & { title: string; }> | undefined; statusCheck?: Readonly<{ error?: string | undefined; title?: string | undefined; success?: string | undefined; text?: string | undefined; btnLabel?: string | undefined; } & { esHitsCheck: Readonly<{} & { query: Record; index: string | string[]; }>; }> | undefined; } & { instructionVariants: Readonly<{ initialSelected?: boolean | undefined; } & { id: string; instructions: Readonly<{ title?: string | undefined; commands?: string[] | undefined; textPre?: string | undefined; textPost?: string | undefined; customComponentName?: string | undefined; } & {}>[]; }>[]; }>[]; }> | undefined; readonly onPremElasticCloud?: Readonly<{ params?: Readonly<{ defaultValue?: any; } & { type: \"string\" | \"number\"; id: string; label: string; }>[] | undefined; } & { instructionSets: Readonly<{ title?: string | undefined; callOut?: Readonly<{ message?: string | undefined; iconType?: string | undefined; } & { title: string; }> | undefined; statusCheck?: Readonly<{ error?: string | undefined; title?: string | undefined; success?: string | undefined; text?: string | undefined; btnLabel?: string | undefined; } & { esHitsCheck: Readonly<{} & { query: Record; index: string | string[]; }>; }> | undefined; } & { instructionVariants: Readonly<{ initialSelected?: boolean | undefined; } & { id: string; instructions: Readonly<{ title?: string | undefined; commands?: string[] | undefined; textPre?: string | undefined; textPost?: string | undefined; customComponentName?: string | undefined; } & {}>[]; }>[]; }>[]; }> | undefined; readonly artifacts?: Readonly<{ application?: Readonly<{} & { path: string; label: string; }> | undefined; exportedFields?: Readonly<{} & { documentationUrl: string; }> | undefined; } & { dashboards: Readonly<{ linkLabel?: string | undefined; } & { id: string; isOverview: boolean; }>[]; }> | undefined; readonly savedObjectsInstallMsg?: string | undefined; readonly customStatusCheckName?: string | undefined; readonly integrationBrowserCategories?: string[] | undefined; readonly eprPackageOverlap?: string | undefined; readonly id: string; readonly name: string; readonly category: \"other\" | \"security\" | \"metrics\" | \"logging\"; readonly shortDescription: string; readonly longDescription: string; readonly onPrem: Readonly<{ params?: Readonly<{ defaultValue?: any; } & { type: \"string\" | \"number\"; id: string; label: string; }>[] | undefined; } & { instructionSets: Readonly<{ title?: string | undefined; callOut?: Readonly<{ message?: string | undefined; iconType?: string | undefined; } & { title: string; }> | undefined; statusCheck?: Readonly<{ error?: string | undefined; title?: string | undefined; success?: string | undefined; text?: string | undefined; btnLabel?: string | undefined; } & { esHitsCheck: Readonly<{} & { query: Record; index: string | string[]; }>; }> | undefined; } & { instructionVariants: Readonly<{ initialSelected?: boolean | undefined; } & { id: string; instructions: Readonly<{ title?: string | undefined; commands?: string[] | undefined; textPre?: string | undefined; textPost?: string | undefined; customComponentName?: string | undefined; } & {}>[]; }>[]; }>[]; }>; }" + "{ readonly isBeta?: boolean | undefined; readonly savedObjects?: any[] | undefined; readonly euiIconType?: string | undefined; readonly previewImagePath?: string | undefined; readonly moduleName?: string | undefined; readonly completionTimeMinutes?: number | undefined; readonly elasticCloud?: Readonly<{ params?: Readonly<{ defaultValue?: any; } & { type: \"string\" | \"number\"; label: string; id: string; }>[] | undefined; } & { instructionSets: Readonly<{ title?: string | undefined; callOut?: Readonly<{ message?: string | undefined; iconType?: string | undefined; } & { title: string; }> | undefined; statusCheck?: Readonly<{ error?: string | undefined; success?: string | undefined; text?: string | undefined; title?: string | undefined; btnLabel?: string | undefined; } & { esHitsCheck: Readonly<{} & { query: Record; index: string | string[]; }>; }> | undefined; } & { instructionVariants: Readonly<{ initialSelected?: boolean | undefined; } & { id: string; instructions: Readonly<{ title?: string | undefined; commands?: string[] | undefined; textPre?: string | undefined; textPost?: string | undefined; customComponentName?: string | undefined; } & {}>[]; }>[]; }>[]; }> | undefined; readonly onPremElasticCloud?: Readonly<{ params?: Readonly<{ defaultValue?: any; } & { type: \"string\" | \"number\"; label: string; id: string; }>[] | undefined; } & { instructionSets: Readonly<{ title?: string | undefined; callOut?: Readonly<{ message?: string | undefined; iconType?: string | undefined; } & { title: string; }> | undefined; statusCheck?: Readonly<{ error?: string | undefined; success?: string | undefined; text?: string | undefined; title?: string | undefined; btnLabel?: string | undefined; } & { esHitsCheck: Readonly<{} & { query: Record; index: string | string[]; }>; }> | undefined; } & { instructionVariants: Readonly<{ initialSelected?: boolean | undefined; } & { id: string; instructions: Readonly<{ title?: string | undefined; commands?: string[] | undefined; textPre?: string | undefined; textPost?: string | undefined; customComponentName?: string | undefined; } & {}>[]; }>[]; }>[]; }> | undefined; readonly artifacts?: Readonly<{ application?: Readonly<{} & { path: string; label: string; }> | undefined; exportedFields?: Readonly<{} & { documentationUrl: string; }> | undefined; } & { dashboards: Readonly<{ linkLabel?: string | undefined; } & { id: string; isOverview: boolean; }>[]; }> | undefined; readonly savedObjectsInstallMsg?: string | undefined; readonly customStatusCheckName?: string | undefined; readonly integrationBrowserCategories?: string[] | undefined; readonly eprPackageOverlap?: string | undefined; readonly id: string; readonly name: string; readonly category: \"other\" | \"security\" | \"metrics\" | \"logging\"; readonly shortDescription: string; readonly longDescription: string; readonly onPrem: Readonly<{ params?: Readonly<{ defaultValue?: any; } & { type: \"string\" | \"number\"; label: string; id: string; }>[] | undefined; } & { instructionSets: Readonly<{ title?: string | undefined; callOut?: Readonly<{ message?: string | undefined; iconType?: string | undefined; } & { title: string; }> | undefined; statusCheck?: Readonly<{ error?: string | undefined; success?: string | undefined; text?: string | undefined; title?: string | undefined; btnLabel?: string | undefined; } & { esHitsCheck: Readonly<{} & { query: Record; index: string | string[]; }>; }> | undefined; } & { instructionVariants: Readonly<{ initialSelected?: boolean | undefined; } & { id: string; instructions: Readonly<{ title?: string | undefined; commands?: string[] | undefined; textPre?: string | undefined; textPost?: string | undefined; customComponentName?: string | undefined; } & {}>[]; }>[]; }>[]; }>; }" ], "path": "src/plugins/home/server/services/tutorials/lib/tutorial_schema.ts", "deprecated": false, @@ -2021,7 +2021,7 @@ "signature": [ "{ getSampleDatasets: () => ", "Writable", - "[]; previewImagePath: string; overviewDashboard: string; defaultIndex: string; dataIndices: Readonly<{} & { id: string; fields: Record; timeFields: string[]; dataPath: string; currentTimeMarker: string; preserveDayOfWeekTimeOfDay: boolean; }>[]; }>>[]; addSavedObjectsToSampleDataset: (id: string, savedObjects: ", + "[]; previewImagePath: string; overviewDashboard: string; defaultIndex: string; dataIndices: Readonly<{} & { id: string; fields: Record; timeFields: string[]; dataPath: string; currentTimeMarker: string; preserveDayOfWeekTimeOfDay: boolean; }>[]; }>>[]; addSavedObjectsToSampleDataset: (id: string, savedObjects: ", "SavedObject", "[]) => void; addAppLinksToSampleDataset: (id: string, appLinks: ", { diff --git a/api_docs/home.mdx b/api_docs/home.mdx index bb18eef28d326b..ca30d6b5d5f9b6 100644 --- a/api_docs/home.mdx +++ b/api_docs/home.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/home title: "home" image: https://source.unsplash.com/400x175/?github description: API docs for the home plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'home'] --- import homeObj from './home.devdocs.json'; diff --git a/api_docs/index_lifecycle_management.mdx b/api_docs/index_lifecycle_management.mdx index 6b742541962e43..5d96e076554999 100644 --- a/api_docs/index_lifecycle_management.mdx +++ b/api_docs/index_lifecycle_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/indexLifecycleManagement title: "indexLifecycleManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the indexLifecycleManagement plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'indexLifecycleManagement'] --- import indexLifecycleManagementObj from './index_lifecycle_management.devdocs.json'; diff --git a/api_docs/index_management.mdx b/api_docs/index_management.mdx index f46718927087cc..34179c055ada06 100644 --- a/api_docs/index_management.mdx +++ b/api_docs/index_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/indexManagement title: "indexManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the indexManagement plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'indexManagement'] --- import indexManagementObj from './index_management.devdocs.json'; diff --git a/api_docs/infra.mdx b/api_docs/infra.mdx index e7660fc9833619..f1dcac4c6aca2e 100644 --- a/api_docs/infra.mdx +++ b/api_docs/infra.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/infra title: "infra" image: https://source.unsplash.com/400x175/?github description: API docs for the infra plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'infra'] --- import infraObj from './infra.devdocs.json'; diff --git a/api_docs/inspector.mdx b/api_docs/inspector.mdx index 67c4f24e628976..ddf15aa1554131 100644 --- a/api_docs/inspector.mdx +++ b/api_docs/inspector.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/inspector title: "inspector" image: https://source.unsplash.com/400x175/?github description: API docs for the inspector plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'inspector'] --- import inspectorObj from './inspector.devdocs.json'; diff --git a/api_docs/interactive_setup.mdx b/api_docs/interactive_setup.mdx index 7b881dc798db42..3434a7fe7975e3 100644 --- a/api_docs/interactive_setup.mdx +++ b/api_docs/interactive_setup.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/interactiveSetup title: "interactiveSetup" image: https://source.unsplash.com/400x175/?github description: API docs for the interactiveSetup plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'interactiveSetup'] --- import interactiveSetupObj from './interactive_setup.devdocs.json'; diff --git a/api_docs/kbn_ace.mdx b/api_docs/kbn_ace.mdx index b180b9937f9c98..67ae17fffb6a77 100644 --- a/api_docs/kbn_ace.mdx +++ b/api_docs/kbn_ace.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ace title: "@kbn/ace" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ace plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ace'] --- import kbnAceObj from './kbn_ace.devdocs.json'; diff --git a/api_docs/kbn_aiops_components.mdx b/api_docs/kbn_aiops_components.mdx index c79a2fcbf83737..41db863b23c80f 100644 --- a/api_docs/kbn_aiops_components.mdx +++ b/api_docs/kbn_aiops_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-aiops-components title: "@kbn/aiops-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/aiops-components plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/aiops-components'] --- import kbnAiopsComponentsObj from './kbn_aiops_components.devdocs.json'; diff --git a/api_docs/kbn_aiops_utils.mdx b/api_docs/kbn_aiops_utils.mdx index 760641ee7da5e3..cf19a2d85db0c4 100644 --- a/api_docs/kbn_aiops_utils.mdx +++ b/api_docs/kbn_aiops_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-aiops-utils title: "@kbn/aiops-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/aiops-utils plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/aiops-utils'] --- import kbnAiopsUtilsObj from './kbn_aiops_utils.devdocs.json'; diff --git a/api_docs/kbn_alerts.mdx b/api_docs/kbn_alerts.mdx index b8a5efb75ffb63..2c8e2f428f2191 100644 --- a/api_docs/kbn_alerts.mdx +++ b/api_docs/kbn_alerts.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerts title: "@kbn/alerts" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerts plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/alerts'] --- import kbnAlertsObj from './kbn_alerts.devdocs.json'; diff --git a/api_docs/kbn_analytics.mdx b/api_docs/kbn_analytics.mdx index 90107aaa0cf761..56db18606a6e25 100644 --- a/api_docs/kbn_analytics.mdx +++ b/api_docs/kbn_analytics.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics title: "@kbn/analytics" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics'] --- import kbnAnalyticsObj from './kbn_analytics.devdocs.json'; diff --git a/api_docs/kbn_analytics_client.devdocs.json b/api_docs/kbn_analytics_client.devdocs.json index 25b6744b3f9bc7..4bf4b8891da73f 100644 --- a/api_docs/kbn_analytics_client.devdocs.json +++ b/api_docs/kbn_analytics_client.devdocs.json @@ -1760,7 +1760,7 @@ "Types matching string values" ], "signature": [ - "\"date\" | \"text\" | \"keyword\"" + "\"date\" | \"keyword\" | \"text\"" ], "path": "packages/analytics/client/src/schema/types.ts", "deprecated": false, @@ -1776,7 +1776,7 @@ "\nPossible type values in the schema" ], "signature": [ - "\"boolean\" | \"date\" | \"text\" | \"keyword\" | \"long\" | \"double\" | \"short\" | \"float\" | \"integer\" | \"byte\"" + "\"boolean\" | \"date\" | \"keyword\" | \"text\" | \"long\" | \"double\" | \"short\" | \"float\" | \"integer\" | \"byte\"" ], "path": "packages/analytics/client/src/schema/types.ts", "deprecated": false, diff --git a/api_docs/kbn_analytics_client.mdx b/api_docs/kbn_analytics_client.mdx index 0edc8e3e93c5a8..5f1d53fda7be61 100644 --- a/api_docs/kbn_analytics_client.mdx +++ b/api_docs/kbn_analytics_client.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-client title: "@kbn/analytics-client" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-client plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-client'] --- import kbnAnalyticsClientObj from './kbn_analytics_client.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx b/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx index 7889e48404ffc0..298cd2096e20b5 100644 --- a/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx +++ b/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-elastic-v3-browser title: "@kbn/analytics-shippers-elastic-v3-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-elastic-v3-browser plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-elastic-v3-browser'] --- import kbnAnalyticsShippersElasticV3BrowserObj from './kbn_analytics_shippers_elastic_v3_browser.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx b/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx index 02fd6eb7e55892..9b7c86af50dc40 100644 --- a/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx +++ b/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-elastic-v3-common title: "@kbn/analytics-shippers-elastic-v3-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-elastic-v3-common plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-elastic-v3-common'] --- import kbnAnalyticsShippersElasticV3CommonObj from './kbn_analytics_shippers_elastic_v3_common.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx b/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx index 1d460acfb2d8bd..1bb7a69ea11eec 100644 --- a/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx +++ b/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-elastic-v3-server title: "@kbn/analytics-shippers-elastic-v3-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-elastic-v3-server plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-elastic-v3-server'] --- import kbnAnalyticsShippersElasticV3ServerObj from './kbn_analytics_shippers_elastic_v3_server.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_fullstory.mdx b/api_docs/kbn_analytics_shippers_fullstory.mdx index 1a3b6ec186fac6..5e7a42f8f6f2ae 100644 --- a/api_docs/kbn_analytics_shippers_fullstory.mdx +++ b/api_docs/kbn_analytics_shippers_fullstory.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-fullstory title: "@kbn/analytics-shippers-fullstory" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-fullstory plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-fullstory'] --- import kbnAnalyticsShippersFullstoryObj from './kbn_analytics_shippers_fullstory.devdocs.json'; diff --git a/api_docs/kbn_apm_config_loader.mdx b/api_docs/kbn_apm_config_loader.mdx index f8533ba8a70c14..7cd3d739b78aeb 100644 --- a/api_docs/kbn_apm_config_loader.mdx +++ b/api_docs/kbn_apm_config_loader.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-config-loader title: "@kbn/apm-config-loader" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-config-loader plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-config-loader'] --- import kbnApmConfigLoaderObj from './kbn_apm_config_loader.devdocs.json'; diff --git a/api_docs/elastic_apm_synthtrace.devdocs.json b/api_docs/kbn_apm_synthtrace.devdocs.json similarity index 75% rename from api_docs/elastic_apm_synthtrace.devdocs.json rename to api_docs/kbn_apm_synthtrace.devdocs.json index 7795015f81289c..142d988330fbdd 100644 --- a/api_docs/elastic_apm_synthtrace.devdocs.json +++ b/api_docs/kbn_apm_synthtrace.devdocs.json @@ -1,5 +1,5 @@ { - "id": "@elastic/apm-synthtrace", + "id": "@kbn/apm-synthtrace", "client": { "classes": [], "functions": [], @@ -11,17 +11,17 @@ "server": { "classes": [ { - "parentPluginId": "@elastic/apm-synthtrace", + "parentPluginId": "@kbn/apm-synthtrace", "id": "def-server.ApmSynthtraceEsClient", "type": "Class", "tags": [], "label": "ApmSynthtraceEsClient", "description": [], - "path": "packages/elastic-apm-synthtrace/src/lib/apm/client/apm_synthtrace_es_client.ts", + "path": "packages/kbn-apm-synthtrace/src/lib/apm/client/apm_synthtrace_es_client.ts", "deprecated": false, "children": [ { - "parentPluginId": "@elastic/apm-synthtrace", + "parentPluginId": "@kbn/apm-synthtrace", "id": "def-server.ApmSynthtraceEsClient.Unnamed", "type": "Function", "tags": [], @@ -30,11 +30,11 @@ "signature": [ "any" ], - "path": "packages/elastic-apm-synthtrace/src/lib/apm/client/apm_synthtrace_es_client.ts", + "path": "packages/kbn-apm-synthtrace/src/lib/apm/client/apm_synthtrace_es_client.ts", "deprecated": false, "children": [ { - "parentPluginId": "@elastic/apm-synthtrace", + "parentPluginId": "@kbn/apm-synthtrace", "id": "def-server.ApmSynthtraceEsClient.Unnamed.$1", "type": "Object", "tags": [], @@ -43,12 +43,12 @@ "signature": [ "default" ], - "path": "packages/elastic-apm-synthtrace/src/lib/apm/client/apm_synthtrace_es_client.ts", + "path": "packages/kbn-apm-synthtrace/src/lib/apm/client/apm_synthtrace_es_client.ts", "deprecated": false, "isRequired": true }, { - "parentPluginId": "@elastic/apm-synthtrace", + "parentPluginId": "@kbn/apm-synthtrace", "id": "def-server.ApmSynthtraceEsClient.Unnamed.$2", "type": "Object", "tags": [], @@ -57,12 +57,12 @@ "signature": [ "{ perf: (name: string, cb: () => T) => T; debug: (...args: any[]) => void; info: (...args: any[]) => void; error: (...args: any[]) => void; }" ], - "path": "packages/elastic-apm-synthtrace/src/lib/apm/client/apm_synthtrace_es_client.ts", + "path": "packages/kbn-apm-synthtrace/src/lib/apm/client/apm_synthtrace_es_client.ts", "deprecated": false, "isRequired": true }, { - "parentPluginId": "@elastic/apm-synthtrace", + "parentPluginId": "@kbn/apm-synthtrace", "id": "def-server.ApmSynthtraceEsClient.Unnamed.$3", "type": "Object", "tags": [], @@ -72,7 +72,7 @@ "ApmSynthtraceEsClientOptions", " | undefined" ], - "path": "packages/elastic-apm-synthtrace/src/lib/apm/client/apm_synthtrace_es_client.ts", + "path": "packages/kbn-apm-synthtrace/src/lib/apm/client/apm_synthtrace_es_client.ts", "deprecated": false, "isRequired": false } @@ -80,7 +80,7 @@ "returnComment": [] }, { - "parentPluginId": "@elastic/apm-synthtrace", + "parentPluginId": "@kbn/apm-synthtrace", "id": "def-server.ApmSynthtraceEsClient.runningVersion", "type": "Function", "tags": [], @@ -89,13 +89,13 @@ "signature": [ "() => Promise" ], - "path": "packages/elastic-apm-synthtrace/src/lib/apm/client/apm_synthtrace_es_client.ts", + "path": "packages/kbn-apm-synthtrace/src/lib/apm/client/apm_synthtrace_es_client.ts", "deprecated": false, "children": [], "returnComment": [] }, { - "parentPluginId": "@elastic/apm-synthtrace", + "parentPluginId": "@kbn/apm-synthtrace", "id": "def-server.ApmSynthtraceEsClient.clean", "type": "Function", "tags": [], @@ -104,11 +104,11 @@ "signature": [ "(dataStreams?: string[] | undefined) => Promise" ], - "path": "packages/elastic-apm-synthtrace/src/lib/apm/client/apm_synthtrace_es_client.ts", + "path": "packages/kbn-apm-synthtrace/src/lib/apm/client/apm_synthtrace_es_client.ts", "deprecated": false, "children": [ { - "parentPluginId": "@elastic/apm-synthtrace", + "parentPluginId": "@kbn/apm-synthtrace", "id": "def-server.ApmSynthtraceEsClient.clean.$1", "type": "Array", "tags": [], @@ -117,7 +117,7 @@ "signature": [ "string[] | undefined" ], - "path": "packages/elastic-apm-synthtrace/src/lib/apm/client/apm_synthtrace_es_client.ts", + "path": "packages/kbn-apm-synthtrace/src/lib/apm/client/apm_synthtrace_es_client.ts", "deprecated": false, "isRequired": false } @@ -125,7 +125,7 @@ "returnComment": [] }, { - "parentPluginId": "@elastic/apm-synthtrace", + "parentPluginId": "@kbn/apm-synthtrace", "id": "def-server.ApmSynthtraceEsClient.updateComponentTemplates", "type": "Function", "tags": [], @@ -134,11 +134,11 @@ "signature": [ "(numberOfPrimaryShards: number) => Promise" ], - "path": "packages/elastic-apm-synthtrace/src/lib/apm/client/apm_synthtrace_es_client.ts", + "path": "packages/kbn-apm-synthtrace/src/lib/apm/client/apm_synthtrace_es_client.ts", "deprecated": false, "children": [ { - "parentPluginId": "@elastic/apm-synthtrace", + "parentPluginId": "@kbn/apm-synthtrace", "id": "def-server.ApmSynthtraceEsClient.updateComponentTemplates.$1", "type": "number", "tags": [], @@ -147,7 +147,7 @@ "signature": [ "number" ], - "path": "packages/elastic-apm-synthtrace/src/lib/apm/client/apm_synthtrace_es_client.ts", + "path": "packages/kbn-apm-synthtrace/src/lib/apm/client/apm_synthtrace_es_client.ts", "deprecated": false, "isRequired": true } @@ -155,7 +155,7 @@ "returnComment": [] }, { - "parentPluginId": "@elastic/apm-synthtrace", + "parentPluginId": "@kbn/apm-synthtrace", "id": "def-server.ApmSynthtraceEsClient.registerGcpRepository", "type": "Function", "tags": [], @@ -164,11 +164,11 @@ "signature": [ "(connectionString: string) => Promise" ], - "path": "packages/elastic-apm-synthtrace/src/lib/apm/client/apm_synthtrace_es_client.ts", + "path": "packages/kbn-apm-synthtrace/src/lib/apm/client/apm_synthtrace_es_client.ts", "deprecated": false, "children": [ { - "parentPluginId": "@elastic/apm-synthtrace", + "parentPluginId": "@kbn/apm-synthtrace", "id": "def-server.ApmSynthtraceEsClient.registerGcpRepository.$1", "type": "string", "tags": [], @@ -177,7 +177,7 @@ "signature": [ "string" ], - "path": "packages/elastic-apm-synthtrace/src/lib/apm/client/apm_synthtrace_es_client.ts", + "path": "packages/kbn-apm-synthtrace/src/lib/apm/client/apm_synthtrace_es_client.ts", "deprecated": false, "isRequired": true } @@ -185,7 +185,7 @@ "returnComment": [] }, { - "parentPluginId": "@elastic/apm-synthtrace", + "parentPluginId": "@kbn/apm-synthtrace", "id": "def-server.ApmSynthtraceEsClient.refresh", "type": "Function", "tags": [], @@ -196,13 +196,13 @@ "ShardsOperationResponseBase", ">" ], - "path": "packages/elastic-apm-synthtrace/src/lib/apm/client/apm_synthtrace_es_client.ts", + "path": "packages/kbn-apm-synthtrace/src/lib/apm/client/apm_synthtrace_es_client.ts", "deprecated": false, "children": [], "returnComment": [] }, { - "parentPluginId": "@elastic/apm-synthtrace", + "parentPluginId": "@kbn/apm-synthtrace", "id": "def-server.ApmSynthtraceEsClient.index", "type": "Function", "tags": [], @@ -211,17 +211,17 @@ "signature": [ "(events: ", { - "pluginId": "@elastic/apm-synthtrace", + "pluginId": "@kbn/apm-synthtrace", "scope": "server", - "docId": "kibElasticApmSynthtracePluginApi", + "docId": "kibKbnApmSynthtracePluginApi", "section": "def-server.EntityIterable", "text": "EntityIterable" }, " | ", { - "pluginId": "@elastic/apm-synthtrace", + "pluginId": "@kbn/apm-synthtrace", "scope": "server", - "docId": "kibElasticApmSynthtracePluginApi", + "docId": "kibKbnApmSynthtracePluginApi", "section": "def-server.EntityIterable", "text": "EntityIterable" }, @@ -229,9 +229,9 @@ "StreamToBulkOptions", "<", { - "pluginId": "@elastic/apm-synthtrace", + "pluginId": "@kbn/apm-synthtrace", "scope": "server", - "docId": "kibElasticApmSynthtracePluginApi", + "docId": "kibKbnApmSynthtracePluginApi", "section": "def-server.ApmFields", "text": "ApmFields" }, @@ -239,19 +239,19 @@ "StreamProcessor", "<", { - "pluginId": "@elastic/apm-synthtrace", + "pluginId": "@kbn/apm-synthtrace", "scope": "server", - "docId": "kibElasticApmSynthtracePluginApi", + "docId": "kibKbnApmSynthtracePluginApi", "section": "def-server.ApmFields", "text": "ApmFields" }, "> | undefined) => Promise" ], - "path": "packages/elastic-apm-synthtrace/src/lib/apm/client/apm_synthtrace_es_client.ts", + "path": "packages/kbn-apm-synthtrace/src/lib/apm/client/apm_synthtrace_es_client.ts", "deprecated": false, "children": [ { - "parentPluginId": "@elastic/apm-synthtrace", + "parentPluginId": "@kbn/apm-synthtrace", "id": "def-server.ApmSynthtraceEsClient.index.$1", "type": "CompoundType", "tags": [], @@ -259,28 +259,28 @@ "description": [], "signature": [ { - "pluginId": "@elastic/apm-synthtrace", + "pluginId": "@kbn/apm-synthtrace", "scope": "server", - "docId": "kibElasticApmSynthtracePluginApi", + "docId": "kibKbnApmSynthtracePluginApi", "section": "def-server.EntityIterable", "text": "EntityIterable" }, " | ", { - "pluginId": "@elastic/apm-synthtrace", + "pluginId": "@kbn/apm-synthtrace", "scope": "server", - "docId": "kibElasticApmSynthtracePluginApi", + "docId": "kibKbnApmSynthtracePluginApi", "section": "def-server.EntityIterable", "text": "EntityIterable" }, "[]" ], - "path": "packages/elastic-apm-synthtrace/src/lib/apm/client/apm_synthtrace_es_client.ts", + "path": "packages/kbn-apm-synthtrace/src/lib/apm/client/apm_synthtrace_es_client.ts", "deprecated": false, "isRequired": true }, { - "parentPluginId": "@elastic/apm-synthtrace", + "parentPluginId": "@kbn/apm-synthtrace", "id": "def-server.ApmSynthtraceEsClient.index.$2", "type": "Object", "tags": [], @@ -290,20 +290,20 @@ "StreamToBulkOptions", "<", { - "pluginId": "@elastic/apm-synthtrace", + "pluginId": "@kbn/apm-synthtrace", "scope": "server", - "docId": "kibElasticApmSynthtracePluginApi", + "docId": "kibKbnApmSynthtracePluginApi", "section": "def-server.ApmFields", "text": "ApmFields" }, "> | undefined" ], - "path": "packages/elastic-apm-synthtrace/src/lib/apm/client/apm_synthtrace_es_client.ts", + "path": "packages/kbn-apm-synthtrace/src/lib/apm/client/apm_synthtrace_es_client.ts", "deprecated": false, "isRequired": false }, { - "parentPluginId": "@elastic/apm-synthtrace", + "parentPluginId": "@kbn/apm-synthtrace", "id": "def-server.ApmSynthtraceEsClient.index.$3", "type": "Object", "tags": [], @@ -313,15 +313,15 @@ "StreamProcessor", "<", { - "pluginId": "@elastic/apm-synthtrace", + "pluginId": "@kbn/apm-synthtrace", "scope": "server", - "docId": "kibElasticApmSynthtracePluginApi", + "docId": "kibKbnApmSynthtracePluginApi", "section": "def-server.ApmFields", "text": "ApmFields" }, "> | undefined" ], - "path": "packages/elastic-apm-synthtrace/src/lib/apm/client/apm_synthtrace_es_client.ts", + "path": "packages/kbn-apm-synthtrace/src/lib/apm/client/apm_synthtrace_es_client.ts", "deprecated": false, "isRequired": false } @@ -329,7 +329,7 @@ "returnComment": [] }, { - "parentPluginId": "@elastic/apm-synthtrace", + "parentPluginId": "@kbn/apm-synthtrace", "id": "def-server.ApmSynthtraceEsClient.createDataStream", "type": "Function", "tags": [], @@ -340,19 +340,19 @@ "StreamAggregator", "<", { - "pluginId": "@elastic/apm-synthtrace", + "pluginId": "@kbn/apm-synthtrace", "scope": "server", - "docId": "kibElasticApmSynthtracePluginApi", + "docId": "kibKbnApmSynthtracePluginApi", "section": "def-server.ApmFields", "text": "ApmFields" }, ">) => Promise" ], - "path": "packages/elastic-apm-synthtrace/src/lib/apm/client/apm_synthtrace_es_client.ts", + "path": "packages/kbn-apm-synthtrace/src/lib/apm/client/apm_synthtrace_es_client.ts", "deprecated": false, "children": [ { - "parentPluginId": "@elastic/apm-synthtrace", + "parentPluginId": "@kbn/apm-synthtrace", "id": "def-server.ApmSynthtraceEsClient.createDataStream.$1", "type": "Object", "tags": [], @@ -362,15 +362,15 @@ "StreamAggregator", "<", { - "pluginId": "@elastic/apm-synthtrace", + "pluginId": "@kbn/apm-synthtrace", "scope": "server", - "docId": "kibElasticApmSynthtracePluginApi", + "docId": "kibKbnApmSynthtracePluginApi", "section": "def-server.ApmFields", "text": "ApmFields" }, ">" ], - "path": "packages/elastic-apm-synthtrace/src/lib/apm/client/apm_synthtrace_es_client.ts", + "path": "packages/kbn-apm-synthtrace/src/lib/apm/client/apm_synthtrace_es_client.ts", "deprecated": false, "isRequired": true } @@ -381,7 +381,7 @@ "initialIsOpen": false }, { - "parentPluginId": "@elastic/apm-synthtrace", + "parentPluginId": "@kbn/apm-synthtrace", "id": "def-server.EntityArrayIterable", "type": "Class", "tags": [], @@ -389,27 +389,27 @@ "description": [], "signature": [ { - "pluginId": "@elastic/apm-synthtrace", + "pluginId": "@kbn/apm-synthtrace", "scope": "server", - "docId": "kibElasticApmSynthtracePluginApi", + "docId": "kibKbnApmSynthtracePluginApi", "section": "def-server.EntityArrayIterable", "text": "EntityArrayIterable" }, " implements ", { - "pluginId": "@elastic/apm-synthtrace", + "pluginId": "@kbn/apm-synthtrace", "scope": "server", - "docId": "kibElasticApmSynthtracePluginApi", + "docId": "kibKbnApmSynthtracePluginApi", "section": "def-server.EntityIterable", "text": "EntityIterable" }, "" ], - "path": "packages/elastic-apm-synthtrace/src/lib/entity_iterable.ts", + "path": "packages/kbn-apm-synthtrace/src/lib/entity_iterable.ts", "deprecated": false, "children": [ { - "parentPluginId": "@elastic/apm-synthtrace", + "parentPluginId": "@kbn/apm-synthtrace", "id": "def-server.EntityArrayIterable.Unnamed", "type": "Function", "tags": [], @@ -418,11 +418,11 @@ "signature": [ "any" ], - "path": "packages/elastic-apm-synthtrace/src/lib/entity_iterable.ts", + "path": "packages/kbn-apm-synthtrace/src/lib/entity_iterable.ts", "deprecated": false, "children": [ { - "parentPluginId": "@elastic/apm-synthtrace", + "parentPluginId": "@kbn/apm-synthtrace", "id": "def-server.EntityArrayIterable.Unnamed.$1", "type": "Array", "tags": [], @@ -431,7 +431,7 @@ "signature": [ "TFields[]" ], - "path": "packages/elastic-apm-synthtrace/src/lib/entity_iterable.ts", + "path": "packages/kbn-apm-synthtrace/src/lib/entity_iterable.ts", "deprecated": false, "isRequired": true } @@ -439,7 +439,7 @@ "returnComment": [] }, { - "parentPluginId": "@elastic/apm-synthtrace", + "parentPluginId": "@kbn/apm-synthtrace", "id": "def-server.EntityArrayIterable.order", "type": "Function", "tags": [], @@ -448,13 +448,13 @@ "signature": [ "() => \"asc\" | \"desc\"" ], - "path": "packages/elastic-apm-synthtrace/src/lib/entity_iterable.ts", + "path": "packages/kbn-apm-synthtrace/src/lib/entity_iterable.ts", "deprecated": false, "children": [], "returnComment": [] }, { - "parentPluginId": "@elastic/apm-synthtrace", + "parentPluginId": "@kbn/apm-synthtrace", "id": "def-server.EntityArrayIterable.ratePerMinute", "type": "Function", "tags": [], @@ -463,13 +463,13 @@ "signature": [ "() => number" ], - "path": "packages/elastic-apm-synthtrace/src/lib/entity_iterable.ts", + "path": "packages/kbn-apm-synthtrace/src/lib/entity_iterable.ts", "deprecated": false, "children": [], "returnComment": [] }, { - "parentPluginId": "@elastic/apm-synthtrace", + "parentPluginId": "@kbn/apm-synthtrace", "id": "def-server.EntityArrayIterable.Symbol.asyncIterator", "type": "Function", "tags": [], @@ -478,13 +478,13 @@ "signature": [ "() => AsyncIterator" ], - "path": "packages/elastic-apm-synthtrace/src/lib/entity_iterable.ts", + "path": "packages/kbn-apm-synthtrace/src/lib/entity_iterable.ts", "deprecated": false, "children": [], "returnComment": [] }, { - "parentPluginId": "@elastic/apm-synthtrace", + "parentPluginId": "@kbn/apm-synthtrace", "id": "def-server.EntityArrayIterable.Symbol.iterator", "type": "Function", "tags": [], @@ -493,13 +493,13 @@ "signature": [ "() => Iterator" ], - "path": "packages/elastic-apm-synthtrace/src/lib/entity_iterable.ts", + "path": "packages/kbn-apm-synthtrace/src/lib/entity_iterable.ts", "deprecated": false, "children": [], "returnComment": [] }, { - "parentPluginId": "@elastic/apm-synthtrace", + "parentPluginId": "@kbn/apm-synthtrace", "id": "def-server.EntityArrayIterable.merge", "type": "Function", "tags": [], @@ -508,9 +508,9 @@ "signature": [ "(...iterables: ", { - "pluginId": "@elastic/apm-synthtrace", + "pluginId": "@kbn/apm-synthtrace", "scope": "server", - "docId": "kibElasticApmSynthtracePluginApi", + "docId": "kibKbnApmSynthtracePluginApi", "section": "def-server.EntityIterable", "text": "EntityIterable" }, @@ -518,11 +518,11 @@ "EntityStreams", "" ], - "path": "packages/elastic-apm-synthtrace/src/lib/entity_iterable.ts", + "path": "packages/kbn-apm-synthtrace/src/lib/entity_iterable.ts", "deprecated": false, "children": [ { - "parentPluginId": "@elastic/apm-synthtrace", + "parentPluginId": "@kbn/apm-synthtrace", "id": "def-server.EntityArrayIterable.merge.$1", "type": "Array", "tags": [], @@ -530,15 +530,15 @@ "description": [], "signature": [ { - "pluginId": "@elastic/apm-synthtrace", + "pluginId": "@kbn/apm-synthtrace", "scope": "server", - "docId": "kibElasticApmSynthtracePluginApi", + "docId": "kibKbnApmSynthtracePluginApi", "section": "def-server.EntityIterable", "text": "EntityIterable" }, "[]" ], - "path": "packages/elastic-apm-synthtrace/src/lib/entity_iterable.ts", + "path": "packages/kbn-apm-synthtrace/src/lib/entity_iterable.ts", "deprecated": false, "isRequired": true } @@ -546,7 +546,7 @@ "returnComment": [] }, { - "parentPluginId": "@elastic/apm-synthtrace", + "parentPluginId": "@kbn/apm-synthtrace", "id": "def-server.EntityArrayIterable.toArray", "type": "Function", "tags": [], @@ -555,7 +555,7 @@ "signature": [ "() => TFields[]" ], - "path": "packages/elastic-apm-synthtrace/src/lib/entity_iterable.ts", + "path": "packages/kbn-apm-synthtrace/src/lib/entity_iterable.ts", "deprecated": false, "children": [], "returnComment": [] @@ -566,7 +566,7 @@ ], "functions": [ { - "parentPluginId": "@elastic/apm-synthtrace", + "parentPluginId": "@kbn/apm-synthtrace", "id": "def-server.cleanWriteTargets", "type": "Function", "tags": [], @@ -577,21 +577,21 @@ "default", "; logger: { perf: (name: string, cb: () => T) => T; debug: (...args: any[]) => void; info: (...args: any[]) => void; error: (...args: any[]) => void; }; }) => Promise" ], - "path": "packages/elastic-apm-synthtrace/src/lib/utils/clean_write_targets.ts", + "path": "packages/kbn-apm-synthtrace/src/lib/utils/clean_write_targets.ts", "deprecated": false, "children": [ { - "parentPluginId": "@elastic/apm-synthtrace", + "parentPluginId": "@kbn/apm-synthtrace", "id": "def-server.cleanWriteTargets.$1", "type": "Object", "tags": [], "label": "{\n targets,\n client,\n logger,\n}", "description": [], - "path": "packages/elastic-apm-synthtrace/src/lib/utils/clean_write_targets.ts", + "path": "packages/kbn-apm-synthtrace/src/lib/utils/clean_write_targets.ts", "deprecated": false, "children": [ { - "parentPluginId": "@elastic/apm-synthtrace", + "parentPluginId": "@kbn/apm-synthtrace", "id": "def-server.cleanWriteTargets.$1.targets", "type": "Array", "tags": [], @@ -600,11 +600,11 @@ "signature": [ "string[]" ], - "path": "packages/elastic-apm-synthtrace/src/lib/utils/clean_write_targets.ts", + "path": "packages/kbn-apm-synthtrace/src/lib/utils/clean_write_targets.ts", "deprecated": false }, { - "parentPluginId": "@elastic/apm-synthtrace", + "parentPluginId": "@kbn/apm-synthtrace", "id": "def-server.cleanWriteTargets.$1.client", "type": "Object", "tags": [], @@ -613,11 +613,11 @@ "signature": [ "default" ], - "path": "packages/elastic-apm-synthtrace/src/lib/utils/clean_write_targets.ts", + "path": "packages/kbn-apm-synthtrace/src/lib/utils/clean_write_targets.ts", "deprecated": false }, { - "parentPluginId": "@elastic/apm-synthtrace", + "parentPluginId": "@kbn/apm-synthtrace", "id": "def-server.cleanWriteTargets.$1.logger", "type": "Object", "tags": [], @@ -626,7 +626,7 @@ "signature": [ "{ perf: (name: string, cb: () => T) => T; debug: (...args: any[]) => void; info: (...args: any[]) => void; error: (...args: any[]) => void; }" ], - "path": "packages/elastic-apm-synthtrace/src/lib/utils/clean_write_targets.ts", + "path": "packages/kbn-apm-synthtrace/src/lib/utils/clean_write_targets.ts", "deprecated": false } ] @@ -636,7 +636,7 @@ "initialIsOpen": false }, { - "parentPluginId": "@elastic/apm-synthtrace", + "parentPluginId": "@kbn/apm-synthtrace", "id": "def-server.createLogger", "type": "Function", "tags": [], @@ -645,19 +645,19 @@ "signature": [ "(logLevel: ", { - "pluginId": "@elastic/apm-synthtrace", + "pluginId": "@kbn/apm-synthtrace", "scope": "server", - "docId": "kibElasticApmSynthtracePluginApi", + "docId": "kibKbnApmSynthtracePluginApi", "section": "def-server.LogLevel", "text": "LogLevel" }, ") => { perf: (name: string, cb: () => T) => T; debug: (...args: any[]) => void; info: (...args: any[]) => void; error: (...args: any[]) => void; }" ], - "path": "packages/elastic-apm-synthtrace/src/lib/utils/create_logger.ts", + "path": "packages/kbn-apm-synthtrace/src/lib/utils/create_logger.ts", "deprecated": false, "children": [ { - "parentPluginId": "@elastic/apm-synthtrace", + "parentPluginId": "@kbn/apm-synthtrace", "id": "def-server.createLogger.$1", "type": "Enum", "tags": [], @@ -665,14 +665,14 @@ "description": [], "signature": [ { - "pluginId": "@elastic/apm-synthtrace", + "pluginId": "@kbn/apm-synthtrace", "scope": "server", - "docId": "kibElasticApmSynthtracePluginApi", + "docId": "kibKbnApmSynthtracePluginApi", "section": "def-server.LogLevel", "text": "LogLevel" } ], - "path": "packages/elastic-apm-synthtrace/src/lib/utils/create_logger.ts", + "path": "packages/kbn-apm-synthtrace/src/lib/utils/create_logger.ts", "deprecated": false, "isRequired": true } @@ -681,7 +681,7 @@ "initialIsOpen": false }, { - "parentPluginId": "@elastic/apm-synthtrace", + "parentPluginId": "@kbn/apm-synthtrace", "id": "def-server.observer", "type": "Function", "tags": [], @@ -691,14 +691,14 @@ "() => ", "Observer" ], - "path": "packages/elastic-apm-synthtrace/src/lib/agent_config/observer.ts", + "path": "packages/kbn-apm-synthtrace/src/lib/agent_config/observer.ts", "deprecated": false, "children": [], "returnComment": [], "initialIsOpen": false }, { - "parentPluginId": "@elastic/apm-synthtrace", + "parentPluginId": "@kbn/apm-synthtrace", "id": "def-server.timerange", "type": "Function", "tags": [], @@ -708,11 +708,11 @@ "(from: number | Date, to: number | Date) => ", "Timerange" ], - "path": "packages/elastic-apm-synthtrace/src/lib/timerange.ts", + "path": "packages/kbn-apm-synthtrace/src/lib/timerange.ts", "deprecated": false, "children": [ { - "parentPluginId": "@elastic/apm-synthtrace", + "parentPluginId": "@kbn/apm-synthtrace", "id": "def-server.timerange.$1", "type": "CompoundType", "tags": [], @@ -721,12 +721,12 @@ "signature": [ "number | Date" ], - "path": "packages/elastic-apm-synthtrace/src/lib/timerange.ts", + "path": "packages/kbn-apm-synthtrace/src/lib/timerange.ts", "deprecated": false, "isRequired": true }, { - "parentPluginId": "@elastic/apm-synthtrace", + "parentPluginId": "@kbn/apm-synthtrace", "id": "def-server.timerange.$2", "type": "CompoundType", "tags": [], @@ -735,7 +735,7 @@ "signature": [ "number | Date" ], - "path": "packages/elastic-apm-synthtrace/src/lib/timerange.ts", + "path": "packages/kbn-apm-synthtrace/src/lib/timerange.ts", "deprecated": false, "isRequired": true } @@ -746,30 +746,30 @@ ], "interfaces": [ { - "parentPluginId": "@elastic/apm-synthtrace", + "parentPluginId": "@kbn/apm-synthtrace", "id": "def-server.ApmException", "type": "Interface", "tags": [], "label": "ApmException", "description": [], - "path": "packages/elastic-apm-synthtrace/src/lib/apm/apm_fields.ts", + "path": "packages/kbn-apm-synthtrace/src/lib/apm/apm_fields.ts", "deprecated": false, "children": [ { - "parentPluginId": "@elastic/apm-synthtrace", + "parentPluginId": "@kbn/apm-synthtrace", "id": "def-server.ApmException.message", "type": "string", "tags": [], "label": "message", "description": [], - "path": "packages/elastic-apm-synthtrace/src/lib/apm/apm_fields.ts", + "path": "packages/kbn-apm-synthtrace/src/lib/apm/apm_fields.ts", "deprecated": false } ], "initialIsOpen": false }, { - "parentPluginId": "@elastic/apm-synthtrace", + "parentPluginId": "@kbn/apm-synthtrace", "id": "def-server.EntityIterable", "type": "Interface", "tags": [], @@ -777,19 +777,19 @@ "description": [], "signature": [ { - "pluginId": "@elastic/apm-synthtrace", + "pluginId": "@kbn/apm-synthtrace", "scope": "server", - "docId": "kibElasticApmSynthtracePluginApi", + "docId": "kibKbnApmSynthtracePluginApi", "section": "def-server.EntityIterable", "text": "EntityIterable" }, " extends Iterable,AsyncIterable" ], - "path": "packages/elastic-apm-synthtrace/src/lib/entity_iterable.ts", + "path": "packages/kbn-apm-synthtrace/src/lib/entity_iterable.ts", "deprecated": false, "children": [ { - "parentPluginId": "@elastic/apm-synthtrace", + "parentPluginId": "@kbn/apm-synthtrace", "id": "def-server.EntityIterable.order", "type": "Function", "tags": [], @@ -798,13 +798,13 @@ "signature": [ "() => \"asc\" | \"desc\"" ], - "path": "packages/elastic-apm-synthtrace/src/lib/entity_iterable.ts", + "path": "packages/kbn-apm-synthtrace/src/lib/entity_iterable.ts", "deprecated": false, "children": [], "returnComment": [] }, { - "parentPluginId": "@elastic/apm-synthtrace", + "parentPluginId": "@kbn/apm-synthtrace", "id": "def-server.EntityIterable.ratePerMinute", "type": "Function", "tags": [], @@ -813,13 +813,13 @@ "signature": [ "() => number" ], - "path": "packages/elastic-apm-synthtrace/src/lib/entity_iterable.ts", + "path": "packages/kbn-apm-synthtrace/src/lib/entity_iterable.ts", "deprecated": false, "children": [], "returnComment": [] }, { - "parentPluginId": "@elastic/apm-synthtrace", + "parentPluginId": "@kbn/apm-synthtrace", "id": "def-server.EntityIterable.toArray", "type": "Function", "tags": [], @@ -828,21 +828,21 @@ "signature": [ "() => ", { - "pluginId": "@elastic/apm-synthtrace", + "pluginId": "@kbn/apm-synthtrace", "scope": "server", - "docId": "kibElasticApmSynthtracePluginApi", + "docId": "kibKbnApmSynthtracePluginApi", "section": "def-server.ApmFields", "text": "ApmFields" }, "[]" ], - "path": "packages/elastic-apm-synthtrace/src/lib/entity_iterable.ts", + "path": "packages/kbn-apm-synthtrace/src/lib/entity_iterable.ts", "deprecated": false, "children": [], "returnComment": [] }, { - "parentPluginId": "@elastic/apm-synthtrace", + "parentPluginId": "@kbn/apm-synthtrace", "id": "def-server.EntityIterable.merge", "type": "Function", "tags": [], @@ -851,9 +851,9 @@ "signature": [ "(...iterables: ", { - "pluginId": "@elastic/apm-synthtrace", + "pluginId": "@kbn/apm-synthtrace", "scope": "server", - "docId": "kibElasticApmSynthtracePluginApi", + "docId": "kibKbnApmSynthtracePluginApi", "section": "def-server.EntityIterable", "text": "EntityIterable" }, @@ -861,11 +861,11 @@ "EntityStreams", "" ], - "path": "packages/elastic-apm-synthtrace/src/lib/entity_iterable.ts", + "path": "packages/kbn-apm-synthtrace/src/lib/entity_iterable.ts", "deprecated": false, "children": [ { - "parentPluginId": "@elastic/apm-synthtrace", + "parentPluginId": "@kbn/apm-synthtrace", "id": "def-server.EntityIterable.merge.$1", "type": "Array", "tags": [], @@ -873,15 +873,15 @@ "description": [], "signature": [ { - "pluginId": "@elastic/apm-synthtrace", + "pluginId": "@kbn/apm-synthtrace", "scope": "server", - "docId": "kibElasticApmSynthtracePluginApi", + "docId": "kibKbnApmSynthtracePluginApi", "section": "def-server.EntityIterable", "text": "EntityIterable" }, "[]" ], - "path": "packages/elastic-apm-synthtrace/src/lib/entity_iterable.ts", + "path": "packages/kbn-apm-synthtrace/src/lib/entity_iterable.ts", "deprecated": false, "isRequired": true } @@ -892,17 +892,17 @@ "initialIsOpen": false }, { - "parentPluginId": "@elastic/apm-synthtrace", + "parentPluginId": "@kbn/apm-synthtrace", "id": "def-server.Fields", "type": "Interface", "tags": [], "label": "Fields", "description": [], - "path": "packages/elastic-apm-synthtrace/src/lib/entity.ts", + "path": "packages/kbn-apm-synthtrace/src/lib/entity.ts", "deprecated": false, "children": [ { - "parentPluginId": "@elastic/apm-synthtrace", + "parentPluginId": "@kbn/apm-synthtrace", "id": "def-server.Fields.timestamp", "type": "number", "tags": [], @@ -911,7 +911,7 @@ "signature": [ "number | undefined" ], - "path": "packages/elastic-apm-synthtrace/src/lib/entity.ts", + "path": "packages/kbn-apm-synthtrace/src/lib/entity.ts", "deprecated": false } ], @@ -920,20 +920,20 @@ ], "enums": [ { - "parentPluginId": "@elastic/apm-synthtrace", + "parentPluginId": "@kbn/apm-synthtrace", "id": "def-server.LogLevel", "type": "Enum", "tags": [], "label": "LogLevel", "description": [], - "path": "packages/elastic-apm-synthtrace/src/lib/utils/create_logger.ts", + "path": "packages/kbn-apm-synthtrace/src/lib/utils/create_logger.ts", "deprecated": false, "initialIsOpen": false } ], "misc": [ { - "parentPluginId": "@elastic/apm-synthtrace", + "parentPluginId": "@kbn/apm-synthtrace", "id": "def-server.ApmFields", "type": "Type", "tags": [], @@ -941,17 +941,17 @@ "description": [], "signature": [ { - "pluginId": "@elastic/apm-synthtrace", + "pluginId": "@kbn/apm-synthtrace", "scope": "server", - "docId": "kibElasticApmSynthtracePluginApi", + "docId": "kibKbnApmSynthtracePluginApi", "section": "def-server.Fields", "text": "Fields" }, " & Partial<{ 'timestamp.us'?: number | undefined; 'agent.name': string; 'agent.version': string; 'container.id': string; 'ecs.version': string; 'event.outcome': string; 'event.ingested': number; 'error.id': string; 'error.exception': ", { - "pluginId": "@elastic/apm-synthtrace", + "pluginId": "@kbn/apm-synthtrace", "scope": "server", - "docId": "kibElasticApmSynthtracePluginApi", + "docId": "kibKbnApmSynthtracePluginApi", "section": "def-server.ApmException", "text": "ApmException" }, @@ -959,24 +959,24 @@ "Observer", "; 'parent.id': string; 'processor.event': string; 'processor.name': string; 'trace.id': string; 'transaction.name': string; 'transaction.type': string; 'transaction.id': string; 'transaction.duration.us': number; 'transaction.duration.histogram': { values: number[]; counts: number[]; }; 'transaction.sampled': true; 'service.name': string; 'service.version': string; 'service.environment': string; 'service.node.name': string; 'service.runtime.name': string; 'service.runtime.version': string; 'service.framework.name': string; 'span.id': string; 'span.name': string; 'span.type': string; 'span.subtype': string; 'span.duration.us': number; 'span.destination.service.name': string; 'span.destination.service.resource': string; 'span.destination.service.type': string; 'span.destination.service.response_time.sum.us': number; 'span.destination.service.response_time.count': number; 'span.self_time.count': number; 'span.self_time.sum.us': number; 'span.links': { trace: { id: string; }; span: { id: string; }; }[]; 'cloud.provider': string; 'cloud.project.name': string; 'cloud.service.name': string; 'cloud.availability_zone': string; 'cloud.machine.type': string; 'cloud.region': string; 'host.os.platform': string; 'faas.id': string; 'faas.coldstart': boolean; 'faas.execution': string; 'faas.trigger.type': string; 'faas.trigger.request_id': string; }> & Partial<{ 'system.process.memory.size': number; 'system.memory.actual.free': number; 'system.memory.total': number; 'system.cpu.total.norm.pct': number; 'system.process.memory.rss.bytes': number; 'system.process.cpu.total.norm.pct': number; 'jvm.memory.heap.used': number; 'jvm.memory.non_heap.used': number; 'jvm.thread.count': number; }>" ], - "path": "packages/elastic-apm-synthtrace/src/lib/apm/apm_fields.ts", + "path": "packages/kbn-apm-synthtrace/src/lib/apm/apm_fields.ts", "deprecated": false, "initialIsOpen": false } ], "objects": [ { - "parentPluginId": "@elastic/apm-synthtrace", + "parentPluginId": "@kbn/apm-synthtrace", "id": "def-server.apm", "type": "Object", "tags": [], "label": "apm", "description": [], - "path": "packages/elastic-apm-synthtrace/src/lib/apm/index.ts", + "path": "packages/kbn-apm-synthtrace/src/lib/apm/index.ts", "deprecated": false, "children": [ { - "parentPluginId": "@elastic/apm-synthtrace", + "parentPluginId": "@kbn/apm-synthtrace", "id": "def-server.apm.service", "type": "Function", "tags": [], @@ -986,44 +986,44 @@ "(name: string, environment: string, agentName: string) => ", "Service" ], - "path": "packages/elastic-apm-synthtrace/src/lib/apm/index.ts", + "path": "packages/kbn-apm-synthtrace/src/lib/apm/index.ts", "deprecated": false, "returnComment": [], "children": [ { - "parentPluginId": "@elastic/apm-synthtrace", + "parentPluginId": "@kbn/apm-synthtrace", "id": "def-server.apm.service.$1", "type": "string", "tags": [], "label": "name", "description": [], - "path": "packages/elastic-apm-synthtrace/src/lib/apm/service.ts", + "path": "packages/kbn-apm-synthtrace/src/lib/apm/service.ts", "deprecated": false }, { - "parentPluginId": "@elastic/apm-synthtrace", + "parentPluginId": "@kbn/apm-synthtrace", "id": "def-server.apm.service.$2", "type": "string", "tags": [], "label": "environment", "description": [], - "path": "packages/elastic-apm-synthtrace/src/lib/apm/service.ts", + "path": "packages/kbn-apm-synthtrace/src/lib/apm/service.ts", "deprecated": false }, { - "parentPluginId": "@elastic/apm-synthtrace", + "parentPluginId": "@kbn/apm-synthtrace", "id": "def-server.apm.service.$3", "type": "string", "tags": [], "label": "agentName", "description": [], - "path": "packages/elastic-apm-synthtrace/src/lib/apm/service.ts", + "path": "packages/kbn-apm-synthtrace/src/lib/apm/service.ts", "deprecated": false } ] }, { - "parentPluginId": "@elastic/apm-synthtrace", + "parentPluginId": "@kbn/apm-synthtrace", "id": "def-server.apm.browser", "type": "Function", "tags": [], @@ -1033,32 +1033,32 @@ "(serviceName: string, production: string, userAgent: Partial<{ 'user_agent.original': string; 'user_agent.os.name': string; 'user_agent.name': string; 'user_agent.device.name': string; 'user_agent.version': number; }>) => ", "Browser" ], - "path": "packages/elastic-apm-synthtrace/src/lib/apm/index.ts", + "path": "packages/kbn-apm-synthtrace/src/lib/apm/index.ts", "deprecated": false, "returnComment": [], "children": [ { - "parentPluginId": "@elastic/apm-synthtrace", + "parentPluginId": "@kbn/apm-synthtrace", "id": "def-server.apm.browser.$1", "type": "string", "tags": [], "label": "serviceName", "description": [], - "path": "packages/elastic-apm-synthtrace/src/lib/apm/browser.ts", + "path": "packages/kbn-apm-synthtrace/src/lib/apm/browser.ts", "deprecated": false }, { - "parentPluginId": "@elastic/apm-synthtrace", + "parentPluginId": "@kbn/apm-synthtrace", "id": "def-server.apm.browser.$2", "type": "string", "tags": [], "label": "production", "description": [], - "path": "packages/elastic-apm-synthtrace/src/lib/apm/browser.ts", + "path": "packages/kbn-apm-synthtrace/src/lib/apm/browser.ts", "deprecated": false }, { - "parentPluginId": "@elastic/apm-synthtrace", + "parentPluginId": "@kbn/apm-synthtrace", "id": "def-server.apm.browser.$3", "type": "Object", "tags": [], @@ -1067,13 +1067,13 @@ "signature": [ "{ 'user_agent.original'?: string | undefined; 'user_agent.os.name'?: string | undefined; 'user_agent.name'?: string | undefined; 'user_agent.device.name'?: string | undefined; 'user_agent.version'?: number | undefined; }" ], - "path": "packages/elastic-apm-synthtrace/src/lib/apm/browser.ts", + "path": "packages/kbn-apm-synthtrace/src/lib/apm/browser.ts", "deprecated": false } ] }, { - "parentPluginId": "@elastic/apm-synthtrace", + "parentPluginId": "@kbn/apm-synthtrace", "id": "def-server.apm.getTransactionMetrics", "type": "Function", "tags": [], @@ -1082,17 +1082,17 @@ "signature": [ "(events: ", { - "pluginId": "@elastic/apm-synthtrace", + "pluginId": "@kbn/apm-synthtrace", "scope": "server", - "docId": "kibElasticApmSynthtracePluginApi", + "docId": "kibKbnApmSynthtracePluginApi", "section": "def-server.ApmFields", "text": "ApmFields" }, "[]) => { 'metricset.name': string; 'transaction.duration.histogram': { values: number[]; counts: number[]; }; _doc_count: number; '@timestamp'?: number | undefined; 'timestamp.us'?: number | undefined; 'agent.name'?: string | undefined; 'agent.version'?: string | undefined; 'container.id'?: string | undefined; 'ecs.version'?: string | undefined; 'event.outcome'?: string | undefined; 'event.ingested'?: number | undefined; 'error.id'?: string | undefined; 'error.exception'?: ", { - "pluginId": "@elastic/apm-synthtrace", + "pluginId": "@kbn/apm-synthtrace", "scope": "server", - "docId": "kibElasticApmSynthtracePluginApi", + "docId": "kibKbnApmSynthtracePluginApi", "section": "def-server.ApmException", "text": "ApmException" }, @@ -1100,12 +1100,12 @@ "Observer", " | undefined; 'parent.id'?: string | undefined; 'processor.event'?: string | undefined; 'processor.name'?: string | undefined; 'trace.id'?: string | undefined; 'transaction.name'?: string | undefined; 'transaction.type'?: string | undefined; 'transaction.id'?: string | undefined; 'transaction.duration.us'?: number | undefined; 'transaction.sampled'?: true | undefined; 'service.name'?: string | undefined; 'service.version'?: string | undefined; 'service.environment'?: string | undefined; 'service.node.name'?: string | undefined; 'service.runtime.name'?: string | undefined; 'service.runtime.version'?: string | undefined; 'service.framework.name'?: string | undefined; 'span.id'?: string | undefined; 'span.name'?: string | undefined; 'span.type'?: string | undefined; 'span.subtype'?: string | undefined; 'span.duration.us'?: number | undefined; 'span.destination.service.name'?: string | undefined; 'span.destination.service.resource'?: string | undefined; 'span.destination.service.type'?: string | undefined; 'span.destination.service.response_time.sum.us'?: number | undefined; 'span.destination.service.response_time.count'?: number | undefined; 'span.self_time.count'?: number | undefined; 'span.self_time.sum.us'?: number | undefined; 'span.links'?: { trace: { id: string; }; span: { id: string; }; }[] | undefined; 'cloud.provider'?: string | undefined; 'cloud.project.name'?: string | undefined; 'cloud.service.name'?: string | undefined; 'cloud.availability_zone'?: string | undefined; 'cloud.machine.type'?: string | undefined; 'cloud.region'?: string | undefined; 'host.os.platform'?: string | undefined; 'faas.id'?: string | undefined; 'faas.coldstart'?: boolean | undefined; 'faas.execution'?: string | undefined; 'faas.trigger.type'?: string | undefined; 'faas.trigger.request_id'?: string | undefined; 'system.process.memory.size'?: number | undefined; 'system.memory.actual.free'?: number | undefined; 'system.memory.total'?: number | undefined; 'system.cpu.total.norm.pct'?: number | undefined; 'system.process.memory.rss.bytes'?: number | undefined; 'system.process.cpu.total.norm.pct'?: number | undefined; 'jvm.memory.heap.used'?: number | undefined; 'jvm.memory.non_heap.used'?: number | undefined; 'jvm.thread.count'?: number | undefined; }[]" ], - "path": "packages/elastic-apm-synthtrace/src/lib/apm/index.ts", + "path": "packages/kbn-apm-synthtrace/src/lib/apm/index.ts", "deprecated": false, "returnComment": [], "children": [ { - "parentPluginId": "@elastic/apm-synthtrace", + "parentPluginId": "@kbn/apm-synthtrace", "id": "def-server.apm.getTransactionMetrics.$1", "type": "Array", "tags": [], @@ -1113,21 +1113,21 @@ "description": [], "signature": [ { - "pluginId": "@elastic/apm-synthtrace", + "pluginId": "@kbn/apm-synthtrace", "scope": "server", - "docId": "kibElasticApmSynthtracePluginApi", + "docId": "kibKbnApmSynthtracePluginApi", "section": "def-server.ApmFields", "text": "ApmFields" }, "[]" ], - "path": "packages/elastic-apm-synthtrace/src/lib/apm/processors/get_transaction_metrics.ts", + "path": "packages/kbn-apm-synthtrace/src/lib/apm/processors/get_transaction_metrics.ts", "deprecated": false } ] }, { - "parentPluginId": "@elastic/apm-synthtrace", + "parentPluginId": "@kbn/apm-synthtrace", "id": "def-server.apm.getSpanDestinationMetrics", "type": "Function", "tags": [], @@ -1136,17 +1136,17 @@ "signature": [ "(events: ", { - "pluginId": "@elastic/apm-synthtrace", + "pluginId": "@kbn/apm-synthtrace", "scope": "server", - "docId": "kibElasticApmSynthtracePluginApi", + "docId": "kibKbnApmSynthtracePluginApi", "section": "def-server.ApmFields", "text": "ApmFields" }, "[]) => { \"metricset.name\": string; 'span.destination.service.response_time.sum.us': number; 'span.destination.service.response_time.count': number; '@timestamp'?: number | undefined; 'timestamp.us'?: number | undefined; 'agent.name'?: string | undefined; 'agent.version'?: string | undefined; 'container.id'?: string | undefined; 'ecs.version'?: string | undefined; 'event.outcome'?: string | undefined; 'event.ingested'?: number | undefined; 'error.id'?: string | undefined; 'error.exception'?: ", { - "pluginId": "@elastic/apm-synthtrace", + "pluginId": "@kbn/apm-synthtrace", "scope": "server", - "docId": "kibElasticApmSynthtracePluginApi", + "docId": "kibKbnApmSynthtracePluginApi", "section": "def-server.ApmException", "text": "ApmException" }, @@ -1154,12 +1154,12 @@ "Observer", " | undefined; 'parent.id'?: string | undefined; 'processor.event'?: string | undefined; 'processor.name'?: string | undefined; 'trace.id'?: string | undefined; 'transaction.name'?: string | undefined; 'transaction.type'?: string | undefined; 'transaction.id'?: string | undefined; 'transaction.duration.us'?: number | undefined; 'transaction.duration.histogram'?: { values: number[]; counts: number[]; } | undefined; 'transaction.sampled'?: true | undefined; 'service.name'?: string | undefined; 'service.version'?: string | undefined; 'service.environment'?: string | undefined; 'service.node.name'?: string | undefined; 'service.runtime.name'?: string | undefined; 'service.runtime.version'?: string | undefined; 'service.framework.name'?: string | undefined; 'span.id'?: string | undefined; 'span.name'?: string | undefined; 'span.type'?: string | undefined; 'span.subtype'?: string | undefined; 'span.duration.us'?: number | undefined; 'span.destination.service.name'?: string | undefined; 'span.destination.service.resource'?: string | undefined; 'span.destination.service.type'?: string | undefined; 'span.self_time.count'?: number | undefined; 'span.self_time.sum.us'?: number | undefined; 'span.links'?: { trace: { id: string; }; span: { id: string; }; }[] | undefined; 'cloud.provider'?: string | undefined; 'cloud.project.name'?: string | undefined; 'cloud.service.name'?: string | undefined; 'cloud.availability_zone'?: string | undefined; 'cloud.machine.type'?: string | undefined; 'cloud.region'?: string | undefined; 'host.os.platform'?: string | undefined; 'faas.id'?: string | undefined; 'faas.coldstart'?: boolean | undefined; 'faas.execution'?: string | undefined; 'faas.trigger.type'?: string | undefined; 'faas.trigger.request_id'?: string | undefined; 'system.process.memory.size'?: number | undefined; 'system.memory.actual.free'?: number | undefined; 'system.memory.total'?: number | undefined; 'system.cpu.total.norm.pct'?: number | undefined; 'system.process.memory.rss.bytes'?: number | undefined; 'system.process.cpu.total.norm.pct'?: number | undefined; 'jvm.memory.heap.used'?: number | undefined; 'jvm.memory.non_heap.used'?: number | undefined; 'jvm.thread.count'?: number | undefined; }[]" ], - "path": "packages/elastic-apm-synthtrace/src/lib/apm/index.ts", + "path": "packages/kbn-apm-synthtrace/src/lib/apm/index.ts", "deprecated": false, "returnComment": [], "children": [ { - "parentPluginId": "@elastic/apm-synthtrace", + "parentPluginId": "@kbn/apm-synthtrace", "id": "def-server.apm.getSpanDestinationMetrics.$1", "type": "Array", "tags": [], @@ -1167,21 +1167,21 @@ "description": [], "signature": [ { - "pluginId": "@elastic/apm-synthtrace", + "pluginId": "@kbn/apm-synthtrace", "scope": "server", - "docId": "kibElasticApmSynthtracePluginApi", + "docId": "kibKbnApmSynthtracePluginApi", "section": "def-server.ApmFields", "text": "ApmFields" }, "[]" ], - "path": "packages/elastic-apm-synthtrace/src/lib/apm/processors/get_span_destination_metrics.ts", + "path": "packages/kbn-apm-synthtrace/src/lib/apm/processors/get_span_destination_metrics.ts", "deprecated": false } ] }, { - "parentPluginId": "@elastic/apm-synthtrace", + "parentPluginId": "@kbn/apm-synthtrace", "id": "def-server.apm.getChromeUserAgentDefaults", "type": "Function", "tags": [], @@ -1190,13 +1190,13 @@ "signature": [ "() => Partial<{ 'user_agent.original': string; 'user_agent.os.name': string; 'user_agent.name': string; 'user_agent.device.name': string; 'user_agent.version': number; }>" ], - "path": "packages/elastic-apm-synthtrace/src/lib/apm/index.ts", + "path": "packages/kbn-apm-synthtrace/src/lib/apm/index.ts", "deprecated": false, "returnComment": [], "children": [] }, { - "parentPluginId": "@elastic/apm-synthtrace", + "parentPluginId": "@kbn/apm-synthtrace", "id": "def-server.apm.getBreakdownMetrics", "type": "Function", "tags": [], @@ -1205,28 +1205,28 @@ "signature": [ "(events: ", { - "pluginId": "@elastic/apm-synthtrace", + "pluginId": "@kbn/apm-synthtrace", "scope": "server", - "docId": "kibElasticApmSynthtracePluginApi", + "docId": "kibKbnApmSynthtracePluginApi", "section": "def-server.ApmFields", "text": "ApmFields" }, "[]) => ", { - "pluginId": "@elastic/apm-synthtrace", + "pluginId": "@kbn/apm-synthtrace", "scope": "server", - "docId": "kibElasticApmSynthtracePluginApi", + "docId": "kibKbnApmSynthtracePluginApi", "section": "def-server.ApmFields", "text": "ApmFields" }, "[]" ], - "path": "packages/elastic-apm-synthtrace/src/lib/apm/index.ts", + "path": "packages/kbn-apm-synthtrace/src/lib/apm/index.ts", "deprecated": false, "returnComment": [], "children": [ { - "parentPluginId": "@elastic/apm-synthtrace", + "parentPluginId": "@kbn/apm-synthtrace", "id": "def-server.apm.getBreakdownMetrics.$1", "type": "Array", "tags": [], @@ -1234,21 +1234,21 @@ "description": [], "signature": [ { - "pluginId": "@elastic/apm-synthtrace", + "pluginId": "@kbn/apm-synthtrace", "scope": "server", - "docId": "kibElasticApmSynthtracePluginApi", + "docId": "kibKbnApmSynthtracePluginApi", "section": "def-server.ApmFields", "text": "ApmFields" }, "[]" ], - "path": "packages/elastic-apm-synthtrace/src/lib/apm/processors/get_breakdown_metrics.ts", + "path": "packages/kbn-apm-synthtrace/src/lib/apm/processors/get_breakdown_metrics.ts", "deprecated": false } ] }, { - "parentPluginId": "@elastic/apm-synthtrace", + "parentPluginId": "@kbn/apm-synthtrace", "id": "def-server.apm.getApmWriteTargets", "type": "Function", "tags": [], @@ -1261,12 +1261,12 @@ "ApmElasticsearchOutputWriteTargets", ">" ], - "path": "packages/elastic-apm-synthtrace/src/lib/apm/index.ts", + "path": "packages/kbn-apm-synthtrace/src/lib/apm/index.ts", "deprecated": false, "returnComment": [], "children": [ { - "parentPluginId": "@elastic/apm-synthtrace", + "parentPluginId": "@kbn/apm-synthtrace", "id": "def-server.apm.getApmWriteTargets.$1", "type": "Object", "tags": [], @@ -1277,13 +1277,13 @@ "default", "; forceLegacyIndices?: boolean | undefined; }" ], - "path": "packages/elastic-apm-synthtrace/src/lib/apm/utils/get_apm_write_targets.ts", + "path": "packages/kbn-apm-synthtrace/src/lib/apm/utils/get_apm_write_targets.ts", "deprecated": false } ] }, { - "parentPluginId": "@elastic/apm-synthtrace", + "parentPluginId": "@kbn/apm-synthtrace", "id": "def-server.apm.ApmSynthtraceEsClient", "type": "Object", "tags": [], @@ -1292,31 +1292,45 @@ "signature": [ "typeof ", { - "pluginId": "@elastic/apm-synthtrace", + "pluginId": "@kbn/apm-synthtrace", "scope": "server", - "docId": "kibElasticApmSynthtracePluginApi", + "docId": "kibKbnApmSynthtracePluginApi", "section": "def-server.ApmSynthtraceEsClient", "text": "ApmSynthtraceEsClient" } ], - "path": "packages/elastic-apm-synthtrace/src/lib/apm/index.ts", + "path": "packages/kbn-apm-synthtrace/src/lib/apm/index.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/apm-synthtrace", + "id": "def-server.apm.ApmSynthtraceKibanaClient", + "type": "Object", + "tags": [], + "label": "ApmSynthtraceKibanaClient", + "description": [], + "signature": [ + "typeof ", + "ApmSynthtraceKibanaClient" + ], + "path": "packages/kbn-apm-synthtrace/src/lib/apm/index.ts", "deprecated": false } ], "initialIsOpen": false }, { - "parentPluginId": "@elastic/apm-synthtrace", + "parentPluginId": "@kbn/apm-synthtrace", "id": "def-server.stackMonitoring", "type": "Object", "tags": [], "label": "stackMonitoring", "description": [], - "path": "packages/elastic-apm-synthtrace/src/lib/stack_monitoring/index.ts", + "path": "packages/kbn-apm-synthtrace/src/lib/stack_monitoring/index.ts", "deprecated": false, "children": [ { - "parentPluginId": "@elastic/apm-synthtrace", + "parentPluginId": "@kbn/apm-synthtrace", "id": "def-server.stackMonitoring.cluster", "type": "Function", "tags": [], @@ -1326,18 +1340,18 @@ "(name: string) => ", "Cluster" ], - "path": "packages/elastic-apm-synthtrace/src/lib/stack_monitoring/index.ts", + "path": "packages/kbn-apm-synthtrace/src/lib/stack_monitoring/index.ts", "deprecated": false, "returnComment": [], "children": [ { - "parentPluginId": "@elastic/apm-synthtrace", + "parentPluginId": "@kbn/apm-synthtrace", "id": "def-server.stackMonitoring.cluster.$1", "type": "string", "tags": [], "label": "name", "description": [], - "path": "packages/elastic-apm-synthtrace/src/lib/stack_monitoring/cluster.ts", + "path": "packages/kbn-apm-synthtrace/src/lib/stack_monitoring/cluster.ts", "deprecated": false } ] diff --git a/api_docs/kbn_apm_synthtrace.mdx b/api_docs/kbn_apm_synthtrace.mdx new file mode 100644 index 00000000000000..2884d443bd1153 --- /dev/null +++ b/api_docs/kbn_apm_synthtrace.mdx @@ -0,0 +1,45 @@ +--- +#### +#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system. +#### Reach out in #docs-engineering for more info. +#### +id: kibKbnApmSynthtracePluginApi +slug: /kibana-dev-docs/api/kbn-apm-synthtrace +title: "@kbn/apm-synthtrace" +image: https://source.unsplash.com/400x175/?github +description: API docs for the @kbn/apm-synthtrace plugin +date: 2022-08-24 +tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-synthtrace'] +--- +import kbnApmSynthtraceObj from './kbn_apm_synthtrace.devdocs.json'; + +Elastic APM trace data generator + +Contact [Owner missing] for questions regarding this plugin. + +**Code health stats** + +| Public API count | Any count | Items lacking comments | Missing exports | +|-------------------|-----------|------------------------|-----------------| +| 75 | 0 | 75 | 12 | + +## Server + +### Objects + + +### Functions + + +### Classes + + +### Interfaces + + +### Enums + + +### Consts, variables and types + + diff --git a/api_docs/kbn_apm_utils.mdx b/api_docs/kbn_apm_utils.mdx index 5d2a8629b8c1eb..757eabfd9b5b9e 100644 --- a/api_docs/kbn_apm_utils.mdx +++ b/api_docs/kbn_apm_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-utils title: "@kbn/apm-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-utils plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-utils'] --- import kbnApmUtilsObj from './kbn_apm_utils.devdocs.json'; diff --git a/api_docs/kbn_axe_config.mdx b/api_docs/kbn_axe_config.mdx index c509541a26912d..ff4d385f54ee8d 100644 --- a/api_docs/kbn_axe_config.mdx +++ b/api_docs/kbn_axe_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-axe-config title: "@kbn/axe-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/axe-config plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/axe-config'] --- import kbnAxeConfigObj from './kbn_axe_config.devdocs.json'; diff --git a/api_docs/kbn_bazel_packages.devdocs.json b/api_docs/kbn_bazel_packages.devdocs.json deleted file mode 100644 index 23cf46d140b558..00000000000000 --- a/api_docs/kbn_bazel_packages.devdocs.json +++ /dev/null @@ -1,333 +0,0 @@ -{ - "id": "@kbn/bazel-packages", - "client": { - "classes": [], - "functions": [], - "interfaces": [], - "enums": [], - "misc": [], - "objects": [] - }, - "server": { - "classes": [ - { - "parentPluginId": "@kbn/bazel-packages", - "id": "def-server.BazelPackage", - "type": "Class", - "tags": [], - "label": "BazelPackage", - "description": [ - "\nRepresentation of a Bazel Package in the Kibana repository" - ], - "path": "packages/kbn-bazel-packages/src/bazel_package.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/bazel-packages", - "id": "def-server.BazelPackage.fromDir", - "type": "Function", - "tags": [], - "label": "fromDir", - "description": [ - "\nCreate a BazelPackage object from a package directory. Reads some files from the package and returns\na Promise for a BazelPackage instance." - ], - "signature": [ - "(dir: string) => Promise<", - { - "pluginId": "@kbn/bazel-packages", - "scope": "server", - "docId": "kibKbnBazelPackagesPluginApi", - "section": "def-server.BazelPackage", - "text": "BazelPackage" - }, - ">" - ], - "path": "packages/kbn-bazel-packages/src/bazel_package.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/bazel-packages", - "id": "def-server.BazelPackage.fromDir.$1", - "type": "string", - "tags": [], - "label": "dir", - "description": [], - "signature": [ - "string" - ], - "path": "packages/kbn-bazel-packages/src/bazel_package.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [] - }, - { - "parentPluginId": "@kbn/bazel-packages", - "id": "def-server.BazelPackage.Unnamed", - "type": "Function", - "tags": [], - "label": "Constructor", - "description": [], - "signature": [ - "any" - ], - "path": "packages/kbn-bazel-packages/src/bazel_package.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/bazel-packages", - "id": "def-server.BazelPackage.Unnamed.$1", - "type": "string", - "tags": [], - "label": "normalizedRepoRelativeDir", - "description": [], - "signature": [ - "string" - ], - "path": "packages/kbn-bazel-packages/src/bazel_package.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "@kbn/bazel-packages", - "id": "def-server.BazelPackage.Unnamed.$2", - "type": "Object", - "tags": [], - "label": "pkg", - "description": [], - "signature": [ - "ParsedPackageJson" - ], - "path": "packages/kbn-bazel-packages/src/bazel_package.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "@kbn/bazel-packages", - "id": "def-server.BazelPackage.Unnamed.$3", - "type": "string", - "tags": [], - "label": "buildBazelContent", - "description": [], - "signature": [ - "string | undefined" - ], - "path": "packages/kbn-bazel-packages/src/bazel_package.ts", - "deprecated": false, - "isRequired": false - } - ], - "returnComment": [] - }, - { - "parentPluginId": "@kbn/bazel-packages", - "id": "def-server.BazelPackage.hasBuildRule", - "type": "Function", - "tags": [], - "label": "hasBuildRule", - "description": [ - "\nReturns true if the package includes a `:build` bazel rule" - ], - "signature": [ - "() => boolean" - ], - "path": "packages/kbn-bazel-packages/src/bazel_package.ts", - "deprecated": false, - "children": [], - "returnComment": [] - }, - { - "parentPluginId": "@kbn/bazel-packages", - "id": "def-server.BazelPackage.hasBuildTypesRule", - "type": "Function", - "tags": [], - "label": "hasBuildTypesRule", - "description": [ - "\nReturns true if the package includes a `:build_types` bazel rule" - ], - "signature": [ - "() => boolean" - ], - "path": "packages/kbn-bazel-packages/src/bazel_package.ts", - "deprecated": false, - "children": [], - "returnComment": [] - }, - { - "parentPluginId": "@kbn/bazel-packages", - "id": "def-server.BazelPackage.isDevOnly", - "type": "Function", - "tags": [], - "label": "isDevOnly", - "description": [ - "\nReturns true if the package is not intended to be in the build" - ], - "signature": [ - "() => boolean" - ], - "path": "packages/kbn-bazel-packages/src/bazel_package.ts", - "deprecated": false, - "children": [], - "returnComment": [] - }, - { - "parentPluginId": "@kbn/bazel-packages", - "id": "def-server.BazelPackage.inspect.custom", - "type": "Function", - "tags": [], - "label": "[inspect.custom]", - "description": [ - "\nCustom inspect handler so that logging variables in scripts/generate doesn't\nprint all the BUILD.bazel files" - ], - "signature": [ - "() => string" - ], - "path": "packages/kbn-bazel-packages/src/bazel_package.ts", - "deprecated": false, - "children": [], - "returnComment": [] - } - ], - "initialIsOpen": false - } - ], - "functions": [ - { - "parentPluginId": "@kbn/bazel-packages", - "id": "def-server.discoverBazelPackageLocations", - "type": "Function", - "tags": [], - "label": "discoverBazelPackageLocations", - "description": [], - "signature": [ - "(repoRoot: string) => string[]" - ], - "path": "packages/kbn-bazel-packages/src/discover_packages.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/bazel-packages", - "id": "def-server.discoverBazelPackageLocations.$1", - "type": "string", - "tags": [], - "label": "repoRoot", - "description": [], - "signature": [ - "string" - ], - "path": "packages/kbn-bazel-packages/src/discover_packages.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [], - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/bazel-packages", - "id": "def-server.discoverBazelPackages", - "type": "Function", - "tags": [], - "label": "discoverBazelPackages", - "description": [], - "signature": [ - "(repoRoot: string) => Promise<", - { - "pluginId": "@kbn/bazel-packages", - "scope": "server", - "docId": "kibKbnBazelPackagesPluginApi", - "section": "def-server.BazelPackage", - "text": "BazelPackage" - }, - "[]>" - ], - "path": "packages/kbn-bazel-packages/src/discover_packages.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/bazel-packages", - "id": "def-server.discoverBazelPackages.$1", - "type": "string", - "tags": [], - "label": "repoRoot", - "description": [], - "signature": [ - "string" - ], - "path": "packages/kbn-bazel-packages/src/discover_packages.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [], - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/bazel-packages", - "id": "def-server.getAllBazelPackageDirs", - "type": "Function", - "tags": [], - "label": "getAllBazelPackageDirs", - "description": [ - "\nResolve all the BAZEL_PACKAGE_DIRS to absolute paths" - ], - "signature": [ - "() => string[]" - ], - "path": "packages/kbn-bazel-packages/src/bazel_package_dirs.ts", - "deprecated": false, - "children": [], - "returnComment": [], - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/bazel-packages", - "id": "def-server.getAllRepoRelativeBazelPackageDirs", - "type": "Function", - "tags": [], - "label": "getAllRepoRelativeBazelPackageDirs", - "description": [ - "\nResolve all the BAZEL_PACKAGE_DIRS to repo-relative paths" - ], - "signature": [ - "() => string[]" - ], - "path": "packages/kbn-bazel-packages/src/bazel_package_dirs.ts", - "deprecated": false, - "children": [], - "returnComment": [], - "initialIsOpen": false - } - ], - "interfaces": [], - "enums": [], - "misc": [ - { - "parentPluginId": "@kbn/bazel-packages", - "id": "def-server.BAZEL_PACKAGE_DIRS", - "type": "Array", - "tags": [], - "label": "BAZEL_PACKAGE_DIRS", - "description": [ - "\nThis is a list of repo-relative paths to directories containing packages. Do not\ninclude `**` in these, one or two `*` segments is acceptable, we need this search\nto be super fast so please avoid deep recursive searching.\n\n eg. src/vis_editors => would find a package at src/vis_editors/foo/package.json\n src/vis_editors/* => would find a package at src/vis_editors/foo/bar/package.json" - ], - "signature": [ - "string[]" - ], - "path": "packages/kbn-bazel-packages/src/bazel_package_dirs.ts", - "deprecated": false, - "initialIsOpen": false - } - ], - "objects": [] - }, - "common": { - "classes": [], - "functions": [], - "interfaces": [], - "enums": [], - "misc": [], - "objects": [] - } -} \ No newline at end of file diff --git a/api_docs/kbn_bazel_packages.mdx b/api_docs/kbn_bazel_packages.mdx deleted file mode 100644 index 53b929d9e7ba57..00000000000000 --- a/api_docs/kbn_bazel_packages.mdx +++ /dev/null @@ -1,36 +0,0 @@ ---- -#### -#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system. -#### Reach out in #docs-engineering for more info. -#### -id: kibKbnBazelPackagesPluginApi -slug: /kibana-dev-docs/api/kbn-bazel-packages -title: "@kbn/bazel-packages" -image: https://source.unsplash.com/400x175/?github -description: API docs for the @kbn/bazel-packages plugin -date: 2022-08-17 -tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/bazel-packages'] ---- -import kbnBazelPackagesObj from './kbn_bazel_packages.devdocs.json'; - - - -Contact [Owner missing] for questions regarding this plugin. - -**Code health stats** - -| Public API count | Any count | Items lacking comments | Missing exports | -|-------------------|-----------|------------------------|-----------------| -| 18 | 0 | 9 | 1 | - -## Server - -### Functions - - -### Classes - - -### Consts, variables and types - - diff --git a/api_docs/kbn_chart_icons.devdocs.json b/api_docs/kbn_chart_icons.devdocs.json new file mode 100644 index 00000000000000..aad32da9e72868 --- /dev/null +++ b/api_docs/kbn_chart_icons.devdocs.json @@ -0,0 +1,1253 @@ +{ + "id": "@kbn/chart-icons", + "client": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "server": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "common": { + "classes": [], + "functions": [ + { + "parentPluginId": "@kbn/chart-icons", + "id": "def-common.DropIllustration", + "type": "Function", + "tags": [], + "label": "DropIllustration", + "description": [], + "signature": [ + "({ title, titleId, ...props }: Omit<", + "EuiIconProps", + ", \"type\">) => JSX.Element" + ], + "path": "packages/kbn-chart-icons/src/assets/drop_illustration.tsx", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/chart-icons", + "id": "def-common.DropIllustration.$1", + "type": "Object", + "tags": [], + "label": "{ title, titleId, ...props }", + "description": [], + "signature": [ + "Omit<", + "EuiIconProps", + ", \"type\">" + ], + "path": "packages/kbn-chart-icons/src/assets/drop_illustration.tsx", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/chart-icons", + "id": "def-common.EuiIconAxisBottom", + "type": "Function", + "tags": [], + "label": "EuiIconAxisBottom", + "description": [], + "signature": [ + "({ title, titleId, ...props }: { title: string; titleId: string; }) => JSX.Element" + ], + "path": "packages/kbn-chart-icons/src/assets/axis_bottom.tsx", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/chart-icons", + "id": "def-common.EuiIconAxisBottom.$1", + "type": "Object", + "tags": [], + "label": "{\n title,\n titleId,\n ...props\n}", + "description": [], + "path": "packages/kbn-chart-icons/src/assets/axis_bottom.tsx", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/chart-icons", + "id": "def-common.EuiIconAxisBottom.$1.title", + "type": "string", + "tags": [], + "label": "title", + "description": [], + "path": "packages/kbn-chart-icons/src/assets/axis_bottom.tsx", + "deprecated": false + }, + { + "parentPluginId": "@kbn/chart-icons", + "id": "def-common.EuiIconAxisBottom.$1.titleId", + "type": "string", + "tags": [], + "label": "titleId", + "description": [], + "path": "packages/kbn-chart-icons/src/assets/axis_bottom.tsx", + "deprecated": false + } + ] + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/chart-icons", + "id": "def-common.EuiIconAxisLeft", + "type": "Function", + "tags": [], + "label": "EuiIconAxisLeft", + "description": [], + "signature": [ + "({ title, titleId, ...props }: { title: string; titleId: string; }) => JSX.Element" + ], + "path": "packages/kbn-chart-icons/src/assets/axis_left.tsx", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/chart-icons", + "id": "def-common.EuiIconAxisLeft.$1", + "type": "Object", + "tags": [], + "label": "{\n title,\n titleId,\n ...props\n}", + "description": [], + "path": "packages/kbn-chart-icons/src/assets/axis_left.tsx", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/chart-icons", + "id": "def-common.EuiIconAxisLeft.$1.title", + "type": "string", + "tags": [], + "label": "title", + "description": [], + "path": "packages/kbn-chart-icons/src/assets/axis_left.tsx", + "deprecated": false + }, + { + "parentPluginId": "@kbn/chart-icons", + "id": "def-common.EuiIconAxisLeft.$1.titleId", + "type": "string", + "tags": [], + "label": "titleId", + "description": [], + "path": "packages/kbn-chart-icons/src/assets/axis_left.tsx", + "deprecated": false + } + ] + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/chart-icons", + "id": "def-common.EuiIconAxisRight", + "type": "Function", + "tags": [], + "label": "EuiIconAxisRight", + "description": [], + "signature": [ + "({ title, titleId, ...props }: { title: string; titleId: string; }) => JSX.Element" + ], + "path": "packages/kbn-chart-icons/src/assets/axis_right.tsx", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/chart-icons", + "id": "def-common.EuiIconAxisRight.$1", + "type": "Object", + "tags": [], + "label": "{\n title,\n titleId,\n ...props\n}", + "description": [], + "path": "packages/kbn-chart-icons/src/assets/axis_right.tsx", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/chart-icons", + "id": "def-common.EuiIconAxisRight.$1.title", + "type": "string", + "tags": [], + "label": "title", + "description": [], + "path": "packages/kbn-chart-icons/src/assets/axis_right.tsx", + "deprecated": false + }, + { + "parentPluginId": "@kbn/chart-icons", + "id": "def-common.EuiIconAxisRight.$1.titleId", + "type": "string", + "tags": [], + "label": "titleId", + "description": [], + "path": "packages/kbn-chart-icons/src/assets/axis_right.tsx", + "deprecated": false + } + ] + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/chart-icons", + "id": "def-common.EuiIconAxisTop", + "type": "Function", + "tags": [], + "label": "EuiIconAxisTop", + "description": [], + "signature": [ + "({ title, titleId, ...props }: { title: string; titleId: string; }) => JSX.Element" + ], + "path": "packages/kbn-chart-icons/src/assets/axis_top.tsx", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/chart-icons", + "id": "def-common.EuiIconAxisTop.$1", + "type": "Object", + "tags": [], + "label": "{\n title,\n titleId,\n ...props\n}", + "description": [], + "path": "packages/kbn-chart-icons/src/assets/axis_top.tsx", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/chart-icons", + "id": "def-common.EuiIconAxisTop.$1.title", + "type": "string", + "tags": [], + "label": "title", + "description": [], + "path": "packages/kbn-chart-icons/src/assets/axis_top.tsx", + "deprecated": false + }, + { + "parentPluginId": "@kbn/chart-icons", + "id": "def-common.EuiIconAxisTop.$1.titleId", + "type": "string", + "tags": [], + "label": "titleId", + "description": [], + "path": "packages/kbn-chart-icons/src/assets/axis_top.tsx", + "deprecated": false + } + ] + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/chart-icons", + "id": "def-common.EuiIconLegend", + "type": "Function", + "tags": [], + "label": "EuiIconLegend", + "description": [], + "signature": [ + "({ title, titleId, ...props }: { title: string; titleId: string; }) => JSX.Element" + ], + "path": "packages/kbn-chart-icons/src/assets/legend.tsx", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/chart-icons", + "id": "def-common.EuiIconLegend.$1", + "type": "Object", + "tags": [], + "label": "{ title, titleId, ...props }", + "description": [], + "path": "packages/kbn-chart-icons/src/assets/legend.tsx", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/chart-icons", + "id": "def-common.EuiIconLegend.$1.title", + "type": "string", + "tags": [], + "label": "title", + "description": [], + "path": "packages/kbn-chart-icons/src/assets/legend.tsx", + "deprecated": false + }, + { + "parentPluginId": "@kbn/chart-icons", + "id": "def-common.EuiIconLegend.$1.titleId", + "type": "string", + "tags": [], + "label": "titleId", + "description": [], + "path": "packages/kbn-chart-icons/src/assets/legend.tsx", + "deprecated": false + } + ] + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/chart-icons", + "id": "def-common.GlobeIllustration", + "type": "Function", + "tags": [], + "label": "GlobeIllustration", + "description": [], + "signature": [ + "({ title, titleId, ...props }: Omit<", + "EuiIconProps", + ", \"type\">) => JSX.Element" + ], + "path": "packages/kbn-chart-icons/src/assets/globe_illustration.tsx", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/chart-icons", + "id": "def-common.GlobeIllustration.$1", + "type": "Object", + "tags": [], + "label": "{ title, titleId, ...props }", + "description": [], + "signature": [ + "Omit<", + "EuiIconProps", + ", \"type\">" + ], + "path": "packages/kbn-chart-icons/src/assets/globe_illustration.tsx", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/chart-icons", + "id": "def-common.IconChartArea", + "type": "Function", + "tags": [], + "label": "IconChartArea", + "description": [], + "signature": [ + "({ title, titleId, ...props }: Omit<", + "EuiIconProps", + ", \"type\">) => JSX.Element" + ], + "path": "packages/kbn-chart-icons/src/assets/chart_area.tsx", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/chart-icons", + "id": "def-common.IconChartArea.$1", + "type": "Object", + "tags": [], + "label": "{ title, titleId, ...props }", + "description": [], + "signature": [ + "Omit<", + "EuiIconProps", + ", \"type\">" + ], + "path": "packages/kbn-chart-icons/src/assets/chart_area.tsx", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/chart-icons", + "id": "def-common.IconChartAreaPercentage", + "type": "Function", + "tags": [], + "label": "IconChartAreaPercentage", + "description": [], + "signature": [ + "({ title, titleId, ...props }: Omit<", + "EuiIconProps", + ", \"type\">) => JSX.Element" + ], + "path": "packages/kbn-chart-icons/src/assets/chart_area_percentage.tsx", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/chart-icons", + "id": "def-common.IconChartAreaPercentage.$1", + "type": "Object", + "tags": [], + "label": "{\n title,\n titleId,\n ...props\n}", + "description": [], + "signature": [ + "Omit<", + "EuiIconProps", + ", \"type\">" + ], + "path": "packages/kbn-chart-icons/src/assets/chart_area_percentage.tsx", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/chart-icons", + "id": "def-common.IconChartAreaStacked", + "type": "Function", + "tags": [], + "label": "IconChartAreaStacked", + "description": [], + "signature": [ + "({ title, titleId, ...props }: Omit<", + "EuiIconProps", + ", \"type\">) => JSX.Element" + ], + "path": "packages/kbn-chart-icons/src/assets/chart_area_stacked.tsx", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/chart-icons", + "id": "def-common.IconChartAreaStacked.$1", + "type": "Object", + "tags": [], + "label": "{ title, titleId, ...props }", + "description": [], + "signature": [ + "Omit<", + "EuiIconProps", + ", \"type\">" + ], + "path": "packages/kbn-chart-icons/src/assets/chart_area_stacked.tsx", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/chart-icons", + "id": "def-common.IconChartBar", + "type": "Function", + "tags": [], + "label": "IconChartBar", + "description": [], + "signature": [ + "({ title, titleId, ...props }: Omit<", + "EuiIconProps", + ", \"type\">) => JSX.Element" + ], + "path": "packages/kbn-chart-icons/src/assets/chart_bar.tsx", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/chart-icons", + "id": "def-common.IconChartBar.$1", + "type": "Object", + "tags": [], + "label": "{ title, titleId, ...props }", + "description": [], + "signature": [ + "Omit<", + "EuiIconProps", + ", \"type\">" + ], + "path": "packages/kbn-chart-icons/src/assets/chart_bar.tsx", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/chart-icons", + "id": "def-common.IconChartBarAnnotations", + "type": "Function", + "tags": [], + "label": "IconChartBarAnnotations", + "description": [], + "signature": [ + "({ title, titleId, ...props }: Omit<", + "EuiIconProps", + ", \"type\">) => JSX.Element" + ], + "path": "packages/kbn-chart-icons/src/assets/chart_bar_annotations.tsx", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/chart-icons", + "id": "def-common.IconChartBarAnnotations.$1", + "type": "Object", + "tags": [], + "label": "{\n title,\n titleId,\n ...props\n}", + "description": [], + "signature": [ + "Omit<", + "EuiIconProps", + ", \"type\">" + ], + "path": "packages/kbn-chart-icons/src/assets/chart_bar_annotations.tsx", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/chart-icons", + "id": "def-common.IconChartBarHorizontal", + "type": "Function", + "tags": [], + "label": "IconChartBarHorizontal", + "description": [], + "signature": [ + "({ title, titleId, ...props }: Omit<", + "EuiIconProps", + ", \"type\">) => JSX.Element" + ], + "path": "packages/kbn-chart-icons/src/assets/chart_bar_horizontal.tsx", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/chart-icons", + "id": "def-common.IconChartBarHorizontal.$1", + "type": "Object", + "tags": [], + "label": "{\n title,\n titleId,\n ...props\n}", + "description": [], + "signature": [ + "Omit<", + "EuiIconProps", + ", \"type\">" + ], + "path": "packages/kbn-chart-icons/src/assets/chart_bar_horizontal.tsx", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/chart-icons", + "id": "def-common.IconChartBarHorizontalPercentage", + "type": "Function", + "tags": [], + "label": "IconChartBarHorizontalPercentage", + "description": [], + "signature": [ + "({ title, titleId, ...props }: Omit<", + "EuiIconProps", + ", \"type\">) => JSX.Element" + ], + "path": "packages/kbn-chart-icons/src/assets/chart_bar_horizontal_percentage.tsx", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/chart-icons", + "id": "def-common.IconChartBarHorizontalPercentage.$1", + "type": "Object", + "tags": [], + "label": "{\n title,\n titleId,\n ...props\n}", + "description": [], + "signature": [ + "Omit<", + "EuiIconProps", + ", \"type\">" + ], + "path": "packages/kbn-chart-icons/src/assets/chart_bar_horizontal_percentage.tsx", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/chart-icons", + "id": "def-common.IconChartBarHorizontalStacked", + "type": "Function", + "tags": [], + "label": "IconChartBarHorizontalStacked", + "description": [], + "signature": [ + "({ title, titleId, ...props }: Omit<", + "EuiIconProps", + ", \"type\">) => JSX.Element" + ], + "path": "packages/kbn-chart-icons/src/assets/chart_bar_horizontal_stacked.tsx", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/chart-icons", + "id": "def-common.IconChartBarHorizontalStacked.$1", + "type": "Object", + "tags": [], + "label": "{\n title,\n titleId,\n ...props\n}", + "description": [], + "signature": [ + "Omit<", + "EuiIconProps", + ", \"type\">" + ], + "path": "packages/kbn-chart-icons/src/assets/chart_bar_horizontal_stacked.tsx", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/chart-icons", + "id": "def-common.IconChartBarPercentage", + "type": "Function", + "tags": [], + "label": "IconChartBarPercentage", + "description": [], + "signature": [ + "({ title, titleId, ...props }: Omit<", + "EuiIconProps", + ", \"type\">) => JSX.Element" + ], + "path": "packages/kbn-chart-icons/src/assets/chart_bar_percentage.tsx", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/chart-icons", + "id": "def-common.IconChartBarPercentage.$1", + "type": "Object", + "tags": [], + "label": "{\n title,\n titleId,\n ...props\n}", + "description": [], + "signature": [ + "Omit<", + "EuiIconProps", + ", \"type\">" + ], + "path": "packages/kbn-chart-icons/src/assets/chart_bar_percentage.tsx", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/chart-icons", + "id": "def-common.IconChartBarReferenceLine", + "type": "Function", + "tags": [], + "label": "IconChartBarReferenceLine", + "description": [], + "signature": [ + "({ title, titleId, ...props }: Omit<", + "EuiIconProps", + ", \"type\">) => JSX.Element" + ], + "path": "packages/kbn-chart-icons/src/assets/chart_bar_reference_line.tsx", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/chart-icons", + "id": "def-common.IconChartBarReferenceLine.$1", + "type": "Object", + "tags": [], + "label": "{\n title,\n titleId,\n ...props\n}", + "description": [], + "signature": [ + "Omit<", + "EuiIconProps", + ", \"type\">" + ], + "path": "packages/kbn-chart-icons/src/assets/chart_bar_reference_line.tsx", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/chart-icons", + "id": "def-common.IconChartBarStacked", + "type": "Function", + "tags": [], + "label": "IconChartBarStacked", + "description": [], + "signature": [ + "({ title, titleId, ...props }: Omit<", + "EuiIconProps", + ", \"type\">) => JSX.Element" + ], + "path": "packages/kbn-chart-icons/src/assets/chart_bar_stacked.tsx", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/chart-icons", + "id": "def-common.IconChartBarStacked.$1", + "type": "Object", + "tags": [], + "label": "{ title, titleId, ...props }", + "description": [], + "signature": [ + "Omit<", + "EuiIconProps", + ", \"type\">" + ], + "path": "packages/kbn-chart-icons/src/assets/chart_bar_stacked.tsx", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/chart-icons", + "id": "def-common.IconChartDatatable", + "type": "Function", + "tags": [], + "label": "IconChartDatatable", + "description": [], + "signature": [ + "({ title, titleId, ...props }: Omit<", + "EuiIconProps", + ", \"type\">) => JSX.Element" + ], + "path": "packages/kbn-chart-icons/src/assets/chart_datatable.tsx", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/chart-icons", + "id": "def-common.IconChartDatatable.$1", + "type": "Object", + "tags": [], + "label": "{ title, titleId, ...props }", + "description": [], + "signature": [ + "Omit<", + "EuiIconProps", + ", \"type\">" + ], + "path": "packages/kbn-chart-icons/src/assets/chart_datatable.tsx", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/chart-icons", + "id": "def-common.IconChartDonut", + "type": "Function", + "tags": [], + "label": "IconChartDonut", + "description": [], + "signature": [ + "({ title, titleId, ...props }: Omit<", + "EuiIconProps", + ", \"type\">) => JSX.Element" + ], + "path": "packages/kbn-chart-icons/src/assets/chart_donut.tsx", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/chart-icons", + "id": "def-common.IconChartDonut.$1", + "type": "Object", + "tags": [], + "label": "{ title, titleId, ...props }", + "description": [], + "signature": [ + "Omit<", + "EuiIconProps", + ", \"type\">" + ], + "path": "packages/kbn-chart-icons/src/assets/chart_donut.tsx", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/chart-icons", + "id": "def-common.IconChartHeatmap", + "type": "Function", + "tags": [], + "label": "IconChartHeatmap", + "description": [], + "signature": [ + "({ title, titleId, ...props }: Omit<", + "EuiIconProps", + ", \"type\">) => JSX.Element" + ], + "path": "packages/kbn-chart-icons/src/assets/chart_heatmap.tsx", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/chart-icons", + "id": "def-common.IconChartHeatmap.$1", + "type": "Object", + "tags": [], + "label": "{ title, titleId, ...props }", + "description": [], + "signature": [ + "Omit<", + "EuiIconProps", + ", \"type\">" + ], + "path": "packages/kbn-chart-icons/src/assets/chart_heatmap.tsx", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/chart-icons", + "id": "def-common.IconChartHorizontalBullet", + "type": "Function", + "tags": [], + "label": "IconChartHorizontalBullet", + "description": [], + "signature": [ + "({ title, titleId, ...props }: Omit<", + "EuiIconProps", + ", \"type\">) => JSX.Element" + ], + "path": "packages/kbn-chart-icons/src/assets/chart_horizontal_bullet.tsx", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/chart-icons", + "id": "def-common.IconChartHorizontalBullet.$1", + "type": "Object", + "tags": [], + "label": "{\n title,\n titleId,\n ...props\n}", + "description": [], + "signature": [ + "Omit<", + "EuiIconProps", + ", \"type\">" + ], + "path": "packages/kbn-chart-icons/src/assets/chart_horizontal_bullet.tsx", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/chart-icons", + "id": "def-common.IconChartLine", + "type": "Function", + "tags": [], + "label": "IconChartLine", + "description": [], + "signature": [ + "({ title, titleId, ...props }: Omit<", + "EuiIconProps", + ", \"type\">) => JSX.Element" + ], + "path": "packages/kbn-chart-icons/src/assets/chart_line.tsx", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/chart-icons", + "id": "def-common.IconChartLine.$1", + "type": "Object", + "tags": [], + "label": "{ title, titleId, ...props }", + "description": [], + "signature": [ + "Omit<", + "EuiIconProps", + ", \"type\">" + ], + "path": "packages/kbn-chart-icons/src/assets/chart_line.tsx", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/chart-icons", + "id": "def-common.IconChartMetric", + "type": "Function", + "tags": [], + "label": "IconChartMetric", + "description": [], + "signature": [ + "({ title, titleId, ...props }: Omit<", + "EuiIconProps", + ", \"type\">) => JSX.Element" + ], + "path": "packages/kbn-chart-icons/src/assets/chart_metric.tsx", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/chart-icons", + "id": "def-common.IconChartMetric.$1", + "type": "Object", + "tags": [], + "label": "{ title, titleId, ...props }", + "description": [], + "signature": [ + "Omit<", + "EuiIconProps", + ", \"type\">" + ], + "path": "packages/kbn-chart-icons/src/assets/chart_metric.tsx", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/chart-icons", + "id": "def-common.IconChartMixedXy", + "type": "Function", + "tags": [], + "label": "IconChartMixedXy", + "description": [], + "signature": [ + "({ title, titleId, ...props }: Omit<", + "EuiIconProps", + ", \"type\">) => JSX.Element" + ], + "path": "packages/kbn-chart-icons/src/assets/chart_mixed_xy.tsx", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/chart-icons", + "id": "def-common.IconChartMixedXy.$1", + "type": "Object", + "tags": [], + "label": "{ title, titleId, ...props }", + "description": [], + "signature": [ + "Omit<", + "EuiIconProps", + ", \"type\">" + ], + "path": "packages/kbn-chart-icons/src/assets/chart_mixed_xy.tsx", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/chart-icons", + "id": "def-common.IconChartMosaic", + "type": "Function", + "tags": [], + "label": "IconChartMosaic", + "description": [], + "signature": [ + "({ title, titleId, ...props }: Omit<", + "EuiIconProps", + ", \"type\">) => JSX.Element" + ], + "path": "packages/kbn-chart-icons/src/assets/chart_mosaic.tsx", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/chart-icons", + "id": "def-common.IconChartMosaic.$1", + "type": "Object", + "tags": [], + "label": "{ title, titleId, ...props }", + "description": [], + "signature": [ + "Omit<", + "EuiIconProps", + ", \"type\">" + ], + "path": "packages/kbn-chart-icons/src/assets/chart_mosaic.tsx", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/chart-icons", + "id": "def-common.IconChartPie", + "type": "Function", + "tags": [], + "label": "IconChartPie", + "description": [], + "signature": [ + "({ title, titleId, ...props }: Omit<", + "EuiIconProps", + ", \"type\">) => JSX.Element" + ], + "path": "packages/kbn-chart-icons/src/assets/chart_pie.tsx", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/chart-icons", + "id": "def-common.IconChartPie.$1", + "type": "Object", + "tags": [], + "label": "{ title, titleId, ...props }", + "description": [], + "signature": [ + "Omit<", + "EuiIconProps", + ", \"type\">" + ], + "path": "packages/kbn-chart-icons/src/assets/chart_pie.tsx", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/chart-icons", + "id": "def-common.IconChartTreemap", + "type": "Function", + "tags": [], + "label": "IconChartTreemap", + "description": [], + "signature": [ + "({ title, titleId, ...props }: Omit<", + "EuiIconProps", + ", \"type\">) => JSX.Element" + ], + "path": "packages/kbn-chart-icons/src/assets/chart_treemap.tsx", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/chart-icons", + "id": "def-common.IconChartTreemap.$1", + "type": "Object", + "tags": [], + "label": "{ title, titleId, ...props }", + "description": [], + "signature": [ + "Omit<", + "EuiIconProps", + ", \"type\">" + ], + "path": "packages/kbn-chart-icons/src/assets/chart_treemap.tsx", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/chart-icons", + "id": "def-common.IconChartVerticalBullet", + "type": "Function", + "tags": [], + "label": "IconChartVerticalBullet", + "description": [], + "signature": [ + "({ title, titleId, ...props }: Omit<", + "EuiIconProps", + ", \"type\">) => JSX.Element" + ], + "path": "packages/kbn-chart-icons/src/assets/chart_vertical_bullet.tsx", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/chart-icons", + "id": "def-common.IconChartVerticalBullet.$1", + "type": "Object", + "tags": [], + "label": "{\n title,\n titleId,\n ...props\n}", + "description": [], + "signature": [ + "Omit<", + "EuiIconProps", + ", \"type\">" + ], + "path": "packages/kbn-chart-icons/src/assets/chart_vertical_bullet.tsx", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/chart-icons", + "id": "def-common.IconChartWaffle", + "type": "Function", + "tags": [], + "label": "IconChartWaffle", + "description": [], + "signature": [ + "({ title, titleId, ...props }: Omit<", + "EuiIconProps", + ", \"type\">) => JSX.Element" + ], + "path": "packages/kbn-chart-icons/src/assets/chart_waffle.tsx", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/chart-icons", + "id": "def-common.IconChartWaffle.$1", + "type": "Object", + "tags": [], + "label": "{ title, titleId, ...props }", + "description": [], + "signature": [ + "Omit<", + "EuiIconProps", + ", \"type\">" + ], + "path": "packages/kbn-chart-icons/src/assets/chart_waffle.tsx", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/chart-icons", + "id": "def-common.IconCircle", + "type": "Function", + "tags": [], + "label": "IconCircle", + "description": [], + "signature": [ + "({ title, titleId, ...props }: Omit<", + "EuiIconProps", + ", \"type\">) => JSX.Element" + ], + "path": "packages/kbn-chart-icons/src/assets/annotation_icons/circle.tsx", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/chart-icons", + "id": "def-common.IconCircle.$1", + "type": "Object", + "tags": [], + "label": "{ title, titleId, ...props }", + "description": [], + "signature": [ + "Omit<", + "EuiIconProps", + ", \"type\">" + ], + "path": "packages/kbn-chart-icons/src/assets/annotation_icons/circle.tsx", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/chart-icons", + "id": "def-common.IconRegionMap", + "type": "Function", + "tags": [], + "label": "IconRegionMap", + "description": [], + "signature": [ + "({ title, titleId, ...props }: Omit<", + "EuiIconProps", + ", \"type\">) => JSX.Element" + ], + "path": "packages/kbn-chart-icons/src/assets/region_map.tsx", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/chart-icons", + "id": "def-common.IconRegionMap.$1", + "type": "Object", + "tags": [], + "label": "{\n title,\n titleId,\n ...props\n}", + "description": [], + "signature": [ + "Omit<", + "EuiIconProps", + ", \"type\">" + ], + "path": "packages/kbn-chart-icons/src/assets/region_map.tsx", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/chart-icons", + "id": "def-common.IconTriangle", + "type": "Function", + "tags": [], + "label": "IconTriangle", + "description": [], + "signature": [ + "({ title, titleId, ...props }: Omit<", + "EuiIconProps", + ", \"type\">) => JSX.Element" + ], + "path": "packages/kbn-chart-icons/src/assets/annotation_icons/triangle.tsx", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/chart-icons", + "id": "def-common.IconTriangle.$1", + "type": "Object", + "tags": [], + "label": "{ title, titleId, ...props }", + "description": [], + "signature": [ + "Omit<", + "EuiIconProps", + ", \"type\">" + ], + "path": "packages/kbn-chart-icons/src/assets/annotation_icons/triangle.tsx", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + } + ], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + } +} \ No newline at end of file diff --git a/api_docs/kbn_chart_icons.mdx b/api_docs/kbn_chart_icons.mdx new file mode 100644 index 00000000000000..a2aabe7e5d10ac --- /dev/null +++ b/api_docs/kbn_chart_icons.mdx @@ -0,0 +1,30 @@ +--- +#### +#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system. +#### Reach out in #docs-engineering for more info. +#### +id: kibKbnChartIconsPluginApi +slug: /kibana-dev-docs/api/kbn-chart-icons +title: "@kbn/chart-icons" +image: https://source.unsplash.com/400x175/?github +description: API docs for the @kbn/chart-icons plugin +date: 2022-08-24 +tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/chart-icons'] +--- +import kbnChartIconsObj from './kbn_chart_icons.devdocs.json'; + + + +Contact [Owner missing] for questions regarding this plugin. + +**Code health stats** + +| Public API count | Any count | Items lacking comments | Missing exports | +|-------------------|-----------|------------------------|-----------------| +| 76 | 0 | 76 | 0 | + +## Common + +### Functions + + diff --git a/api_docs/kbn_ci_stats_core.mdx b/api_docs/kbn_ci_stats_core.mdx index 57581f4ad7e19e..4657a21c17e495 100644 --- a/api_docs/kbn_ci_stats_core.mdx +++ b/api_docs/kbn_ci_stats_core.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ci-stats-core title: "@kbn/ci-stats-core" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ci-stats-core plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ci-stats-core'] --- import kbnCiStatsCoreObj from './kbn_ci_stats_core.devdocs.json'; diff --git a/api_docs/kbn_ci_stats_performance_metrics.mdx b/api_docs/kbn_ci_stats_performance_metrics.mdx index 4feaa09058e2c3..34b4fe2acb0d90 100644 --- a/api_docs/kbn_ci_stats_performance_metrics.mdx +++ b/api_docs/kbn_ci_stats_performance_metrics.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ci-stats-performance-metrics title: "@kbn/ci-stats-performance-metrics" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ci-stats-performance-metrics plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ci-stats-performance-metrics'] --- import kbnCiStatsPerformanceMetricsObj from './kbn_ci_stats_performance_metrics.devdocs.json'; diff --git a/api_docs/kbn_ci_stats_reporter.mdx b/api_docs/kbn_ci_stats_reporter.mdx index 111e1498896b43..e6bcc51c618939 100644 --- a/api_docs/kbn_ci_stats_reporter.mdx +++ b/api_docs/kbn_ci_stats_reporter.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ci-stats-reporter title: "@kbn/ci-stats-reporter" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ci-stats-reporter plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ci-stats-reporter'] --- import kbnCiStatsReporterObj from './kbn_ci_stats_reporter.devdocs.json'; diff --git a/api_docs/kbn_cli_dev_mode.mdx b/api_docs/kbn_cli_dev_mode.mdx index a8ea6c407c942e..0a2d349b32f5bb 100644 --- a/api_docs/kbn_cli_dev_mode.mdx +++ b/api_docs/kbn_cli_dev_mode.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cli-dev-mode title: "@kbn/cli-dev-mode" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cli-dev-mode plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cli-dev-mode'] --- import kbnCliDevModeObj from './kbn_cli_dev_mode.devdocs.json'; diff --git a/api_docs/kbn_coloring.devdocs.json b/api_docs/kbn_coloring.devdocs.json index d0a3a43de1bef5..3533691ae415d6 100644 --- a/api_docs/kbn_coloring.devdocs.json +++ b/api_docs/kbn_coloring.devdocs.json @@ -157,7 +157,7 @@ "signature": [ "React.ExoticComponent<", "CustomizablePaletteProps", - "> & { readonly _result: ({ palettes, activePalette, setPalette, dataBounds, showExtraActions, showRangeTypeSelector, disableSwitchingContinuity, }: ", + "> & { readonly _result: ({ palettes, activePalette, setPalette, dataBounds, showExtraActions, showRangeTypeSelector, disableSwitchingContinuity, displayInfinity, }: ", "CustomizablePaletteProps", ") => JSX.Element; }" ], diff --git a/api_docs/kbn_coloring.mdx b/api_docs/kbn_coloring.mdx index 04684b50db9142..f0cbbfe93a2a08 100644 --- a/api_docs/kbn_coloring.mdx +++ b/api_docs/kbn_coloring.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-coloring title: "@kbn/coloring" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/coloring plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/coloring'] --- import kbnColoringObj from './kbn_coloring.devdocs.json'; diff --git a/api_docs/kbn_config.mdx b/api_docs/kbn_config.mdx index d58944650acd0a..ed64d1de2fb80d 100644 --- a/api_docs/kbn_config.mdx +++ b/api_docs/kbn_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-config title: "@kbn/config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/config plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/config'] --- import kbnConfigObj from './kbn_config.devdocs.json'; diff --git a/api_docs/kbn_config_mocks.mdx b/api_docs/kbn_config_mocks.mdx index 48b6df92451938..edbfde29f6de06 100644 --- a/api_docs/kbn_config_mocks.mdx +++ b/api_docs/kbn_config_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-config-mocks title: "@kbn/config-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/config-mocks plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/config-mocks'] --- import kbnConfigMocksObj from './kbn_config_mocks.devdocs.json'; diff --git a/api_docs/kbn_config_schema.mdx b/api_docs/kbn_config_schema.mdx index 920e87e9116c6d..ae888efba28a12 100644 --- a/api_docs/kbn_config_schema.mdx +++ b/api_docs/kbn_config_schema.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-config-schema title: "@kbn/config-schema" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/config-schema plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/config-schema'] --- import kbnConfigSchemaObj from './kbn_config_schema.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_browser.mdx b/api_docs/kbn_core_analytics_browser.mdx index bb474c59b515d9..9b4f9a9352f984 100644 --- a/api_docs/kbn_core_analytics_browser.mdx +++ b/api_docs/kbn_core_analytics_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-browser title: "@kbn/core-analytics-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-browser plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-browser'] --- import kbnCoreAnalyticsBrowserObj from './kbn_core_analytics_browser.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_browser_internal.mdx b/api_docs/kbn_core_analytics_browser_internal.mdx index ac278057c28ca6..dc93a4d7bbfd69 100644 --- a/api_docs/kbn_core_analytics_browser_internal.mdx +++ b/api_docs/kbn_core_analytics_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-browser-internal title: "@kbn/core-analytics-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-browser-internal plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-browser-internal'] --- import kbnCoreAnalyticsBrowserInternalObj from './kbn_core_analytics_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_browser_mocks.mdx b/api_docs/kbn_core_analytics_browser_mocks.mdx index b8dc93e440e2a8..9b492574768227 100644 --- a/api_docs/kbn_core_analytics_browser_mocks.mdx +++ b/api_docs/kbn_core_analytics_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-browser-mocks title: "@kbn/core-analytics-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-browser-mocks plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-browser-mocks'] --- import kbnCoreAnalyticsBrowserMocksObj from './kbn_core_analytics_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_server.mdx b/api_docs/kbn_core_analytics_server.mdx index 2e617aeccea230..05dd177d62c6a7 100644 --- a/api_docs/kbn_core_analytics_server.mdx +++ b/api_docs/kbn_core_analytics_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-server title: "@kbn/core-analytics-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-server plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-server'] --- import kbnCoreAnalyticsServerObj from './kbn_core_analytics_server.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_server_internal.mdx b/api_docs/kbn_core_analytics_server_internal.mdx index ee8fcda31aff13..c91cf9634d033f 100644 --- a/api_docs/kbn_core_analytics_server_internal.mdx +++ b/api_docs/kbn_core_analytics_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-server-internal title: "@kbn/core-analytics-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-server-internal plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-server-internal'] --- import kbnCoreAnalyticsServerInternalObj from './kbn_core_analytics_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_server_mocks.mdx b/api_docs/kbn_core_analytics_server_mocks.mdx index 0ae005fab64d76..deb9721024d5c4 100644 --- a/api_docs/kbn_core_analytics_server_mocks.mdx +++ b/api_docs/kbn_core_analytics_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-server-mocks title: "@kbn/core-analytics-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-server-mocks plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-server-mocks'] --- import kbnCoreAnalyticsServerMocksObj from './kbn_core_analytics_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_base_browser_mocks.mdx b/api_docs/kbn_core_base_browser_mocks.mdx index 791ecb72606f42..bf3054fcbf81b5 100644 --- a/api_docs/kbn_core_base_browser_mocks.mdx +++ b/api_docs/kbn_core_base_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-browser-mocks title: "@kbn/core-base-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-browser-mocks plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-base-browser-mocks'] --- import kbnCoreBaseBrowserMocksObj from './kbn_core_base_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_base_common.mdx b/api_docs/kbn_core_base_common.mdx index 1428282575d0a8..60b834dcc4feda 100644 --- a/api_docs/kbn_core_base_common.mdx +++ b/api_docs/kbn_core_base_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-common title: "@kbn/core-base-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-common plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-base-common'] --- import kbnCoreBaseCommonObj from './kbn_core_base_common.devdocs.json'; diff --git a/api_docs/kbn_core_base_server_internal.mdx b/api_docs/kbn_core_base_server_internal.mdx index 4415a7f15f8b96..94ddc2727f2862 100644 --- a/api_docs/kbn_core_base_server_internal.mdx +++ b/api_docs/kbn_core_base_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-server-internal title: "@kbn/core-base-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-server-internal plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-base-server-internal'] --- import kbnCoreBaseServerInternalObj from './kbn_core_base_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_base_server_mocks.mdx b/api_docs/kbn_core_base_server_mocks.mdx index d502aa2f1bcae4..d9127ead7a78c4 100644 --- a/api_docs/kbn_core_base_server_mocks.mdx +++ b/api_docs/kbn_core_base_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-server-mocks title: "@kbn/core-base-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-server-mocks plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-base-server-mocks'] --- import kbnCoreBaseServerMocksObj from './kbn_core_base_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_capabilities_common.mdx b/api_docs/kbn_core_capabilities_common.mdx index 5c28c74d6df4cc..fea0ea5261cbf8 100644 --- a/api_docs/kbn_core_capabilities_common.mdx +++ b/api_docs/kbn_core_capabilities_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-common title: "@kbn/core-capabilities-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-common plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-capabilities-common'] --- import kbnCoreCapabilitiesCommonObj from './kbn_core_capabilities_common.devdocs.json'; diff --git a/api_docs/kbn_core_capabilities_server.mdx b/api_docs/kbn_core_capabilities_server.mdx index ef7c96f70fbc4a..55bc095d88f771 100644 --- a/api_docs/kbn_core_capabilities_server.mdx +++ b/api_docs/kbn_core_capabilities_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-server title: "@kbn/core-capabilities-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-server plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-capabilities-server'] --- import kbnCoreCapabilitiesServerObj from './kbn_core_capabilities_server.devdocs.json'; diff --git a/api_docs/kbn_core_capabilities_server_mocks.mdx b/api_docs/kbn_core_capabilities_server_mocks.mdx index c4313ed62d59b9..38715175b81955 100644 --- a/api_docs/kbn_core_capabilities_server_mocks.mdx +++ b/api_docs/kbn_core_capabilities_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-server-mocks title: "@kbn/core-capabilities-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-server-mocks plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-capabilities-server-mocks'] --- import kbnCoreCapabilitiesServerMocksObj from './kbn_core_capabilities_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_config_server_internal.mdx b/api_docs/kbn_core_config_server_internal.mdx index 205301da79a0b1..83c359ef584699 100644 --- a/api_docs/kbn_core_config_server_internal.mdx +++ b/api_docs/kbn_core_config_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-config-server-internal title: "@kbn/core-config-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-config-server-internal plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-config-server-internal'] --- import kbnCoreConfigServerInternalObj from './kbn_core_config_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_browser.mdx b/api_docs/kbn_core_deprecations_browser.mdx index af0c2588fa9363..b141bf6a2bf7f2 100644 --- a/api_docs/kbn_core_deprecations_browser.mdx +++ b/api_docs/kbn_core_deprecations_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-browser title: "@kbn/core-deprecations-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-browser plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-browser'] --- import kbnCoreDeprecationsBrowserObj from './kbn_core_deprecations_browser.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_browser_internal.mdx b/api_docs/kbn_core_deprecations_browser_internal.mdx index d9adc37d258199..e77954ed5952c8 100644 --- a/api_docs/kbn_core_deprecations_browser_internal.mdx +++ b/api_docs/kbn_core_deprecations_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-browser-internal title: "@kbn/core-deprecations-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-browser-internal plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-browser-internal'] --- import kbnCoreDeprecationsBrowserInternalObj from './kbn_core_deprecations_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_browser_mocks.mdx b/api_docs/kbn_core_deprecations_browser_mocks.mdx index f002d1041c6bad..eca59f9d48c1dc 100644 --- a/api_docs/kbn_core_deprecations_browser_mocks.mdx +++ b/api_docs/kbn_core_deprecations_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-browser-mocks title: "@kbn/core-deprecations-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-browser-mocks plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-browser-mocks'] --- import kbnCoreDeprecationsBrowserMocksObj from './kbn_core_deprecations_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_common.mdx b/api_docs/kbn_core_deprecations_common.mdx index d92843fbf8188b..4206abf386b94d 100644 --- a/api_docs/kbn_core_deprecations_common.mdx +++ b/api_docs/kbn_core_deprecations_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-common title: "@kbn/core-deprecations-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-common plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-common'] --- import kbnCoreDeprecationsCommonObj from './kbn_core_deprecations_common.devdocs.json'; diff --git a/api_docs/kbn_core_doc_links_browser.mdx b/api_docs/kbn_core_doc_links_browser.mdx index b7b989bd7b670c..ff8b2922a09479 100644 --- a/api_docs/kbn_core_doc_links_browser.mdx +++ b/api_docs/kbn_core_doc_links_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-browser title: "@kbn/core-doc-links-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-browser plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-doc-links-browser'] --- import kbnCoreDocLinksBrowserObj from './kbn_core_doc_links_browser.devdocs.json'; diff --git a/api_docs/kbn_core_doc_links_browser_mocks.mdx b/api_docs/kbn_core_doc_links_browser_mocks.mdx index f54ceea4f9597c..18ba61daab248d 100644 --- a/api_docs/kbn_core_doc_links_browser_mocks.mdx +++ b/api_docs/kbn_core_doc_links_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-browser-mocks title: "@kbn/core-doc-links-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-browser-mocks plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-doc-links-browser-mocks'] --- import kbnCoreDocLinksBrowserMocksObj from './kbn_core_doc_links_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_doc_links_server.mdx b/api_docs/kbn_core_doc_links_server.mdx index eefab5ea7deae2..1e1b93ec426510 100644 --- a/api_docs/kbn_core_doc_links_server.mdx +++ b/api_docs/kbn_core_doc_links_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-server title: "@kbn/core-doc-links-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-server plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-doc-links-server'] --- import kbnCoreDocLinksServerObj from './kbn_core_doc_links_server.devdocs.json'; diff --git a/api_docs/kbn_core_doc_links_server_mocks.mdx b/api_docs/kbn_core_doc_links_server_mocks.mdx index 2e07d82d6727da..515bcd4fd04683 100644 --- a/api_docs/kbn_core_doc_links_server_mocks.mdx +++ b/api_docs/kbn_core_doc_links_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-server-mocks title: "@kbn/core-doc-links-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-server-mocks plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-doc-links-server-mocks'] --- import kbnCoreDocLinksServerMocksObj from './kbn_core_doc_links_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_client_server_internal.mdx b/api_docs/kbn_core_elasticsearch_client_server_internal.mdx index d39d2cf375c53d..df20bc87d7b8e0 100644 --- a/api_docs/kbn_core_elasticsearch_client_server_internal.mdx +++ b/api_docs/kbn_core_elasticsearch_client_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-client-server-internal title: "@kbn/core-elasticsearch-client-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-client-server-internal plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-client-server-internal'] --- import kbnCoreElasticsearchClientServerInternalObj from './kbn_core_elasticsearch_client_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_client_server_mocks.devdocs.json b/api_docs/kbn_core_elasticsearch_client_server_mocks.devdocs.json index 16ccc36c7ac60f..ebe913276adcb6 100644 --- a/api_docs/kbn_core_elasticsearch_client_server_mocks.devdocs.json +++ b/api_docs/kbn_core_elasticsearch_client_server_mocks.devdocs.json @@ -257,7 +257,17 @@ "DeleteRequest", ", options?: ", "TransportRequestOptions", - " | undefined]>; name: string | symbol; transform: ", + " | undefined]>; cluster: ", + { + "pluginId": "@kbn/core-elasticsearch-client-server-mocks", + "scope": "server", + "docId": "kibKbnCoreElasticsearchClientServerMocksPluginApi", + "section": "def-server.DeeplyMockedApi", + "text": "DeeplyMockedApi" + }, + "<", + "default", + ">; eql: ", { "pluginId": "@kbn/core-elasticsearch-client-server-mocks", "scope": "server", @@ -283,27 +293,7 @@ "SearchRequest", " | undefined, options?: ", "TransportRequestOptions", - " | undefined]>; cluster: ", - { - "pluginId": "@kbn/core-elasticsearch-client-server-mocks", - "scope": "server", - "docId": "kibKbnCoreElasticsearchClientServerMocksPluginApi", - "section": "def-server.DeeplyMockedApi", - "text": "DeeplyMockedApi" - }, - "<", - "default", - ">; eql: ", - { - "pluginId": "@kbn/core-elasticsearch-client-server-mocks", - "scope": "server", - "docId": "kibKbnCoreElasticsearchClientServerMocksPluginApi", - "section": "def-server.DeeplyMockedApi", - "text": "DeeplyMockedApi" - }, - "<", - "default", - ">; create: ", + " | undefined]>; create: ", { "pluginId": "@kbn/core-elasticsearch-client-server-mocks", "scope": "server", @@ -339,7 +329,7 @@ }, "<", "default", - ">; index: ", + ">; name: string | symbol; index: ", { "pluginId": "@kbn/core-elasticsearch-client-server-mocks", "scope": "server", @@ -1223,6 +1213,16 @@ }, "<", "default", + ">; transform: ", + { + "pluginId": "@kbn/core-elasticsearch-client-server-mocks", + "scope": "server", + "docId": "kibKbnCoreElasticsearchClientServerMocksPluginApi", + "section": "def-server.DeeplyMockedApi", + "text": "DeeplyMockedApi" + }, + "<", + "default", ">; updateByQuery: ", { "pluginId": "@kbn/core-elasticsearch-client-server-mocks", @@ -1365,7 +1365,17 @@ "DeleteRequest", ", options?: ", "TransportRequestOptions", - " | undefined]>; name: string | symbol; transform: ", + " | undefined]>; cluster: ", + { + "pluginId": "@kbn/core-elasticsearch-client-server-mocks", + "scope": "server", + "docId": "kibKbnCoreElasticsearchClientServerMocksPluginApi", + "section": "def-server.DeeplyMockedApi", + "text": "DeeplyMockedApi" + }, + "<", + "default", + ">; eql: ", { "pluginId": "@kbn/core-elasticsearch-client-server-mocks", "scope": "server", @@ -1391,27 +1401,7 @@ "SearchRequest", " | undefined, options?: ", "TransportRequestOptions", - " | undefined]>; cluster: ", - { - "pluginId": "@kbn/core-elasticsearch-client-server-mocks", - "scope": "server", - "docId": "kibKbnCoreElasticsearchClientServerMocksPluginApi", - "section": "def-server.DeeplyMockedApi", - "text": "DeeplyMockedApi" - }, - "<", - "default", - ">; eql: ", - { - "pluginId": "@kbn/core-elasticsearch-client-server-mocks", - "scope": "server", - "docId": "kibKbnCoreElasticsearchClientServerMocksPluginApi", - "section": "def-server.DeeplyMockedApi", - "text": "DeeplyMockedApi" - }, - "<", - "default", - ">; create: ", + " | undefined]>; create: ", { "pluginId": "@kbn/core-elasticsearch-client-server-mocks", "scope": "server", @@ -1447,7 +1437,7 @@ }, "<", "default", - ">; index: ", + ">; name: string | symbol; index: ", { "pluginId": "@kbn/core-elasticsearch-client-server-mocks", "scope": "server", @@ -2331,6 +2321,16 @@ }, "<", "default", + ">; transform: ", + { + "pluginId": "@kbn/core-elasticsearch-client-server-mocks", + "scope": "server", + "docId": "kibKbnCoreElasticsearchClientServerMocksPluginApi", + "section": "def-server.DeeplyMockedApi", + "text": "DeeplyMockedApi" + }, + "<", + "default", ">; updateByQuery: ", { "pluginId": "@kbn/core-elasticsearch-client-server-mocks", @@ -2429,7 +2429,17 @@ "DeleteRequest", ", options?: ", "TransportRequestOptions", - " | undefined]>; name: string | symbol; transform: ", + " | undefined]>; cluster: ", + { + "pluginId": "@kbn/core-elasticsearch-client-server-mocks", + "scope": "server", + "docId": "kibKbnCoreElasticsearchClientServerMocksPluginApi", + "section": "def-server.DeeplyMockedApi", + "text": "DeeplyMockedApi" + }, + "<", + "default", + ">; eql: ", { "pluginId": "@kbn/core-elasticsearch-client-server-mocks", "scope": "server", @@ -2455,27 +2465,7 @@ "SearchRequest", " | undefined, options?: ", "TransportRequestOptions", - " | undefined]>; cluster: ", - { - "pluginId": "@kbn/core-elasticsearch-client-server-mocks", - "scope": "server", - "docId": "kibKbnCoreElasticsearchClientServerMocksPluginApi", - "section": "def-server.DeeplyMockedApi", - "text": "DeeplyMockedApi" - }, - "<", - "default", - ">; eql: ", - { - "pluginId": "@kbn/core-elasticsearch-client-server-mocks", - "scope": "server", - "docId": "kibKbnCoreElasticsearchClientServerMocksPluginApi", - "section": "def-server.DeeplyMockedApi", - "text": "DeeplyMockedApi" - }, - "<", - "default", - ">; create: ", + " | undefined]>; create: ", { "pluginId": "@kbn/core-elasticsearch-client-server-mocks", "scope": "server", @@ -2511,7 +2501,7 @@ }, "<", "default", - ">; index: ", + ">; name: string | symbol; index: ", { "pluginId": "@kbn/core-elasticsearch-client-server-mocks", "scope": "server", @@ -3395,6 +3385,16 @@ }, "<", "default", + ">; transform: ", + { + "pluginId": "@kbn/core-elasticsearch-client-server-mocks", + "scope": "server", + "docId": "kibKbnCoreElasticsearchClientServerMocksPluginApi", + "section": "def-server.DeeplyMockedApi", + "text": "DeeplyMockedApi" + }, + "<", + "default", ">; updateByQuery: ", { "pluginId": "@kbn/core-elasticsearch-client-server-mocks", @@ -3558,7 +3558,17 @@ "DeleteRequest", ", options?: ", "TransportRequestOptions", - " | undefined]>; name: string | symbol; transform: ", + " | undefined]>; cluster: ", + { + "pluginId": "@kbn/core-elasticsearch-client-server-mocks", + "scope": "server", + "docId": "kibKbnCoreElasticsearchClientServerMocksPluginApi", + "section": "def-server.DeeplyMockedApi", + "text": "DeeplyMockedApi" + }, + "<", + "default", + ">; eql: ", { "pluginId": "@kbn/core-elasticsearch-client-server-mocks", "scope": "server", @@ -3584,27 +3594,7 @@ "SearchRequest", " | undefined, options?: ", "TransportRequestOptions", - " | undefined]>; cluster: ", - { - "pluginId": "@kbn/core-elasticsearch-client-server-mocks", - "scope": "server", - "docId": "kibKbnCoreElasticsearchClientServerMocksPluginApi", - "section": "def-server.DeeplyMockedApi", - "text": "DeeplyMockedApi" - }, - "<", - "default", - ">; eql: ", - { - "pluginId": "@kbn/core-elasticsearch-client-server-mocks", - "scope": "server", - "docId": "kibKbnCoreElasticsearchClientServerMocksPluginApi", - "section": "def-server.DeeplyMockedApi", - "text": "DeeplyMockedApi" - }, - "<", - "default", - ">; create: ", + " | undefined]>; create: ", { "pluginId": "@kbn/core-elasticsearch-client-server-mocks", "scope": "server", @@ -3640,7 +3630,7 @@ }, "<", "default", - ">; index: ", + ">; name: string | symbol; index: ", { "pluginId": "@kbn/core-elasticsearch-client-server-mocks", "scope": "server", @@ -4524,6 +4514,16 @@ }, "<", "default", + ">; transform: ", + { + "pluginId": "@kbn/core-elasticsearch-client-server-mocks", + "scope": "server", + "docId": "kibKbnCoreElasticsearchClientServerMocksPluginApi", + "section": "def-server.DeeplyMockedApi", + "text": "DeeplyMockedApi" + }, + "<", + "default", ">; updateByQuery: ", { "pluginId": "@kbn/core-elasticsearch-client-server-mocks", diff --git a/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx b/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx index 0e15d43dab9687..58b434404f71d6 100644 --- a/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx +++ b/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-client-server-mocks title: "@kbn/core-elasticsearch-client-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-client-server-mocks plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-client-server-mocks'] --- import kbnCoreElasticsearchClientServerMocksObj from './kbn_core_elasticsearch_client_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_server.devdocs.json b/api_docs/kbn_core_elasticsearch_server.devdocs.json index ab17c1ee287ce5..71b802e242b1aa 100644 --- a/api_docs/kbn_core_elasticsearch_server.devdocs.json +++ b/api_docs/kbn_core_elasticsearch_server.devdocs.json @@ -882,7 +882,9 @@ "TransportRequestOptions", " | undefined): Promise<", "WriteResponseBase", - ">; }; name: string | symbol; transform: ", + ">; }; cluster: ", + "default", + "; eql: ", "default", "; search: { >; }; cluster: ", - "default", - "; eql: ", - "default", - "; create: { (this: That, params: ", + ">; }; create: { (this: That, params: ", "CreateRequest", " | ", "CreateRequest", @@ -950,7 +948,7 @@ "default", "; security: ", "default", - "; index: { (this: That, params: ", + "; name: string | symbol; index: { (this: That, params: ", "IndexRequest", " | ", "IndexRequest", @@ -1962,6 +1960,8 @@ "TermvectorsResponse", ">; }; textStructure: ", "default", + "; transform: ", + "default", "; updateByQuery: { (this: That, params: ", "UpdateByQueryRequest", " | ", @@ -2473,7 +2473,9 @@ "TransportRequestOptions", " | undefined): Promise<", "WriteResponseBase", - ">; }; name: string | symbol; transform: ", + ">; }; cluster: ", + "default", + "; eql: ", "default", "; search: { >; }; cluster: ", - "default", - "; eql: ", - "default", - "; create: { (this: That, params: ", + ">; }; create: { (this: That, params: ", "CreateRequest", " | ", "CreateRequest", @@ -2541,7 +2539,7 @@ "default", "; security: ", "default", - "; index: { (this: That, params: ", + "; name: string | symbol; index: { (this: That, params: ", "IndexRequest", " | ", "IndexRequest", @@ -3553,6 +3551,8 @@ "TermvectorsResponse", ">; }; textStructure: ", "default", + "; transform: ", + "default", "; updateByQuery: { (this: That, params: ", "UpdateByQueryRequest", " | ", @@ -3676,7 +3676,9 @@ "TransportRequestOptions", " | undefined): Promise<", "WriteResponseBase", - ">; }; name: string | symbol; transform: ", + ">; }; cluster: ", + "default", + "; eql: ", "default", "; search: { >; }; cluster: ", - "default", - "; eql: ", - "default", - "; create: { (this: That, params: ", + ">; }; create: { (this: That, params: ", "CreateRequest", " | ", "CreateRequest", @@ -3744,7 +3742,7 @@ "default", "; security: ", "default", - "; index: { (this: That, params: ", + "; name: string | symbol; index: { (this: That, params: ", "IndexRequest", " | ", "IndexRequest", @@ -4756,6 +4754,8 @@ "TermvectorsResponse", ">; }; textStructure: ", "default", + "; transform: ", + "default", "; updateByQuery: { (this: That, params: ", "UpdateByQueryRequest", " | ", @@ -5113,7 +5113,9 @@ "TransportRequestOptions", " | undefined): Promise<", "WriteResponseBase", - ">; }; name: string | symbol; transform: ", + ">; }; cluster: ", + "default", + "; eql: ", "default", "; search: { >; }; cluster: ", - "default", - "; eql: ", - "default", - "; create: { (this: That, params: ", + ">; }; create: { (this: That, params: ", "CreateRequest", " | ", "CreateRequest", @@ -5181,7 +5179,7 @@ "default", "; security: ", "default", - "; index: { (this: That, params: ", + "; name: string | symbol; index: { (this: That, params: ", "IndexRequest", " | ", "IndexRequest", @@ -6193,6 +6191,8 @@ "TermvectorsResponse", ">; }; textStructure: ", "default", + "; transform: ", + "default", "; updateByQuery: { (this: That, params: ", "UpdateByQueryRequest", " | ", diff --git a/api_docs/kbn_core_elasticsearch_server.mdx b/api_docs/kbn_core_elasticsearch_server.mdx index 9d5e7f264836c6..031bf4381d0daf 100644 --- a/api_docs/kbn_core_elasticsearch_server.mdx +++ b/api_docs/kbn_core_elasticsearch_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-server title: "@kbn/core-elasticsearch-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-server plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-server'] --- import kbnCoreElasticsearchServerObj from './kbn_core_elasticsearch_server.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_server_internal.devdocs.json b/api_docs/kbn_core_elasticsearch_server_internal.devdocs.json index b86ca4789ddaf1..d05f0fed589319 100644 --- a/api_docs/kbn_core_elasticsearch_server_internal.devdocs.json +++ b/api_docs/kbn_core_elasticsearch_server_internal.devdocs.json @@ -96,7 +96,9 @@ "TransportRequestOptions", " | undefined): Promise<", "WriteResponseBase", - ">; }; name: string | symbol; transform: ", + ">; }; cluster: ", + "default", + "; eql: ", "default", "; search: { >; }; cluster: ", - "default", - "; eql: ", - "default", - "; create: { (this: That, params: ", + ">; }; create: { (this: That, params: ", "CreateRequest", " | ", "CreateRequest", @@ -164,7 +162,7 @@ "default", "; security: ", "default", - "; index: { (this: That, params: ", + "; name: string | symbol; index: { (this: That, params: ", "IndexRequest", " | ", "IndexRequest", @@ -1176,6 +1174,8 @@ "TermvectorsResponse", ">; }; textStructure: ", "default", + "; transform: ", + "default", "; updateByQuery: { (this: That, params: ", "UpdateByQueryRequest", " | ", @@ -1655,7 +1655,9 @@ "TransportRequestOptions", " | undefined): Promise<", "WriteResponseBase", - ">; }; name: string | symbol; transform: ", + ">; }; cluster: ", + "default", + "; eql: ", "default", "; search: { >; }; cluster: ", - "default", - "; eql: ", - "default", - "; create: { (this: That, params: ", + ">; }; create: { (this: That, params: ", "CreateRequest", " | ", "CreateRequest", @@ -1723,7 +1721,7 @@ "default", "; security: ", "default", - "; index: { (this: That, params: ", + "; name: string | symbol; index: { (this: That, params: ", "IndexRequest", " | ", "IndexRequest", @@ -2735,6 +2733,8 @@ "TermvectorsResponse", ">; }; textStructure: ", "default", + "; transform: ", + "default", "; updateByQuery: { (this: That, params: ", "UpdateByQueryRequest", " | ", diff --git a/api_docs/kbn_core_elasticsearch_server_internal.mdx b/api_docs/kbn_core_elasticsearch_server_internal.mdx index 66029bf4e4d4e8..c1443c7c201bf9 100644 --- a/api_docs/kbn_core_elasticsearch_server_internal.mdx +++ b/api_docs/kbn_core_elasticsearch_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-server-internal title: "@kbn/core-elasticsearch-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-server-internal plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-server-internal'] --- import kbnCoreElasticsearchServerInternalObj from './kbn_core_elasticsearch_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_server_mocks.mdx b/api_docs/kbn_core_elasticsearch_server_mocks.mdx index 9c63a5fa094af2..1114e0a59aa060 100644 --- a/api_docs/kbn_core_elasticsearch_server_mocks.mdx +++ b/api_docs/kbn_core_elasticsearch_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-server-mocks title: "@kbn/core-elasticsearch-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-server-mocks plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-server-mocks'] --- import kbnCoreElasticsearchServerMocksObj from './kbn_core_elasticsearch_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_environment_server_internal.mdx b/api_docs/kbn_core_environment_server_internal.mdx index 681e83d0d95290..e62ab54b81c925 100644 --- a/api_docs/kbn_core_environment_server_internal.mdx +++ b/api_docs/kbn_core_environment_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-environment-server-internal title: "@kbn/core-environment-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-environment-server-internal plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-environment-server-internal'] --- import kbnCoreEnvironmentServerInternalObj from './kbn_core_environment_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_environment_server_mocks.mdx b/api_docs/kbn_core_environment_server_mocks.mdx index 6557c9b759eb6a..05dd6fed5b0682 100644 --- a/api_docs/kbn_core_environment_server_mocks.mdx +++ b/api_docs/kbn_core_environment_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-environment-server-mocks title: "@kbn/core-environment-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-environment-server-mocks plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-environment-server-mocks'] --- import kbnCoreEnvironmentServerMocksObj from './kbn_core_environment_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_browser.mdx b/api_docs/kbn_core_execution_context_browser.mdx index 9d1e8d7b963124..45c161c271a1fb 100644 --- a/api_docs/kbn_core_execution_context_browser.mdx +++ b/api_docs/kbn_core_execution_context_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-browser title: "@kbn/core-execution-context-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-browser plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-browser'] --- import kbnCoreExecutionContextBrowserObj from './kbn_core_execution_context_browser.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_browser_internal.mdx b/api_docs/kbn_core_execution_context_browser_internal.mdx index 2463a26e1c59f7..d11314b91d9c7b 100644 --- a/api_docs/kbn_core_execution_context_browser_internal.mdx +++ b/api_docs/kbn_core_execution_context_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-browser-internal title: "@kbn/core-execution-context-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-browser-internal plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-browser-internal'] --- import kbnCoreExecutionContextBrowserInternalObj from './kbn_core_execution_context_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_browser_mocks.mdx b/api_docs/kbn_core_execution_context_browser_mocks.mdx index 2d85a4cbb358c7..94305c732e3e4c 100644 --- a/api_docs/kbn_core_execution_context_browser_mocks.mdx +++ b/api_docs/kbn_core_execution_context_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-browser-mocks title: "@kbn/core-execution-context-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-browser-mocks plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-browser-mocks'] --- import kbnCoreExecutionContextBrowserMocksObj from './kbn_core_execution_context_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_common.mdx b/api_docs/kbn_core_execution_context_common.mdx index 6fd67d80bc09f7..ae9bd5f1dc65b7 100644 --- a/api_docs/kbn_core_execution_context_common.mdx +++ b/api_docs/kbn_core_execution_context_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-common title: "@kbn/core-execution-context-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-common plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-common'] --- import kbnCoreExecutionContextCommonObj from './kbn_core_execution_context_common.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_server.mdx b/api_docs/kbn_core_execution_context_server.mdx index 411dc8197c5965..7150975d0f1232 100644 --- a/api_docs/kbn_core_execution_context_server.mdx +++ b/api_docs/kbn_core_execution_context_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-server title: "@kbn/core-execution-context-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-server plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-server'] --- import kbnCoreExecutionContextServerObj from './kbn_core_execution_context_server.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_server_internal.mdx b/api_docs/kbn_core_execution_context_server_internal.mdx index c83f4692645604..eb29d0365af2ef 100644 --- a/api_docs/kbn_core_execution_context_server_internal.mdx +++ b/api_docs/kbn_core_execution_context_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-server-internal title: "@kbn/core-execution-context-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-server-internal plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-server-internal'] --- import kbnCoreExecutionContextServerInternalObj from './kbn_core_execution_context_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_server_mocks.mdx b/api_docs/kbn_core_execution_context_server_mocks.mdx index 3a31287659594c..9122a4137001c6 100644 --- a/api_docs/kbn_core_execution_context_server_mocks.mdx +++ b/api_docs/kbn_core_execution_context_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-server-mocks title: "@kbn/core-execution-context-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-server-mocks plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-server-mocks'] --- import kbnCoreExecutionContextServerMocksObj from './kbn_core_execution_context_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_fatal_errors_browser.mdx b/api_docs/kbn_core_fatal_errors_browser.mdx index e75857d5dc4a87..278bb7ee12e814 100644 --- a/api_docs/kbn_core_fatal_errors_browser.mdx +++ b/api_docs/kbn_core_fatal_errors_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-fatal-errors-browser title: "@kbn/core-fatal-errors-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-fatal-errors-browser plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-fatal-errors-browser'] --- import kbnCoreFatalErrorsBrowserObj from './kbn_core_fatal_errors_browser.devdocs.json'; diff --git a/api_docs/kbn_core_fatal_errors_browser_mocks.mdx b/api_docs/kbn_core_fatal_errors_browser_mocks.mdx index fcf8c1fc46215c..83b28a0f9a4aa8 100644 --- a/api_docs/kbn_core_fatal_errors_browser_mocks.mdx +++ b/api_docs/kbn_core_fatal_errors_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-fatal-errors-browser-mocks title: "@kbn/core-fatal-errors-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-fatal-errors-browser-mocks plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-fatal-errors-browser-mocks'] --- import kbnCoreFatalErrorsBrowserMocksObj from './kbn_core_fatal_errors_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_browser.mdx b/api_docs/kbn_core_http_browser.mdx index d0d8e3750c6186..622a23b8d6e5b9 100644 --- a/api_docs/kbn_core_http_browser.mdx +++ b/api_docs/kbn_core_http_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-browser title: "@kbn/core-http-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-browser plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-browser'] --- import kbnCoreHttpBrowserObj from './kbn_core_http_browser.devdocs.json'; diff --git a/api_docs/kbn_core_http_browser_internal.mdx b/api_docs/kbn_core_http_browser_internal.mdx index eacce541e92a60..b25dc4f833181e 100644 --- a/api_docs/kbn_core_http_browser_internal.mdx +++ b/api_docs/kbn_core_http_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-browser-internal title: "@kbn/core-http-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-browser-internal plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-browser-internal'] --- import kbnCoreHttpBrowserInternalObj from './kbn_core_http_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_http_browser_mocks.mdx b/api_docs/kbn_core_http_browser_mocks.mdx index bc3b9bd38c6c68..447a409b1212a3 100644 --- a/api_docs/kbn_core_http_browser_mocks.mdx +++ b/api_docs/kbn_core_http_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-browser-mocks title: "@kbn/core-http-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-browser-mocks plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-browser-mocks'] --- import kbnCoreHttpBrowserMocksObj from './kbn_core_http_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_common.mdx b/api_docs/kbn_core_http_common.mdx index adb8d82f3bac0a..2edca7485f2dec 100644 --- a/api_docs/kbn_core_http_common.mdx +++ b/api_docs/kbn_core_http_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-common title: "@kbn/core-http-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-common plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-common'] --- import kbnCoreHttpCommonObj from './kbn_core_http_common.devdocs.json'; diff --git a/api_docs/kbn_core_http_context_server_mocks.mdx b/api_docs/kbn_core_http_context_server_mocks.mdx index f77a881bfd6bd7..3b23f35cc6d6e9 100644 --- a/api_docs/kbn_core_http_context_server_mocks.mdx +++ b/api_docs/kbn_core_http_context_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-context-server-mocks title: "@kbn/core-http-context-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-context-server-mocks plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-context-server-mocks'] --- import kbnCoreHttpContextServerMocksObj from './kbn_core_http_context_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_router_server_internal.mdx b/api_docs/kbn_core_http_router_server_internal.mdx index 7907f138b01fb9..13488f60e8cc77 100644 --- a/api_docs/kbn_core_http_router_server_internal.mdx +++ b/api_docs/kbn_core_http_router_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-router-server-internal title: "@kbn/core-http-router-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-router-server-internal plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-router-server-internal'] --- import kbnCoreHttpRouterServerInternalObj from './kbn_core_http_router_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_http_router_server_mocks.mdx b/api_docs/kbn_core_http_router_server_mocks.mdx index 58f16161819cbd..5751ffe0c75023 100644 --- a/api_docs/kbn_core_http_router_server_mocks.mdx +++ b/api_docs/kbn_core_http_router_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-router-server-mocks title: "@kbn/core-http-router-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-router-server-mocks plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-router-server-mocks'] --- import kbnCoreHttpRouterServerMocksObj from './kbn_core_http_router_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_server.mdx b/api_docs/kbn_core_http_server.mdx index 5bbec45d662815..6cdcee4810cb52 100644 --- a/api_docs/kbn_core_http_server.mdx +++ b/api_docs/kbn_core_http_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-server title: "@kbn/core-http-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-server plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-server'] --- import kbnCoreHttpServerObj from './kbn_core_http_server.devdocs.json'; diff --git a/api_docs/kbn_core_http_server_internal.mdx b/api_docs/kbn_core_http_server_internal.mdx index 23c0abbe12991d..9dba93d1f973c0 100644 --- a/api_docs/kbn_core_http_server_internal.mdx +++ b/api_docs/kbn_core_http_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-server-internal title: "@kbn/core-http-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-server-internal plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-server-internal'] --- import kbnCoreHttpServerInternalObj from './kbn_core_http_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_http_server_mocks.mdx b/api_docs/kbn_core_http_server_mocks.mdx index 5cc8f27e26cc8b..4ed10d755bc06e 100644 --- a/api_docs/kbn_core_http_server_mocks.mdx +++ b/api_docs/kbn_core_http_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-server-mocks title: "@kbn/core-http-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-server-mocks plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-server-mocks'] --- import kbnCoreHttpServerMocksObj from './kbn_core_http_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_i18n_browser.mdx b/api_docs/kbn_core_i18n_browser.mdx index 825364640aed36..0c19e944e79431 100644 --- a/api_docs/kbn_core_i18n_browser.mdx +++ b/api_docs/kbn_core_i18n_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-browser title: "@kbn/core-i18n-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-browser plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-i18n-browser'] --- import kbnCoreI18nBrowserObj from './kbn_core_i18n_browser.devdocs.json'; diff --git a/api_docs/kbn_core_i18n_browser_mocks.mdx b/api_docs/kbn_core_i18n_browser_mocks.mdx index f9945f3f419b04..52ac72285a78e0 100644 --- a/api_docs/kbn_core_i18n_browser_mocks.mdx +++ b/api_docs/kbn_core_i18n_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-browser-mocks title: "@kbn/core-i18n-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-browser-mocks plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-i18n-browser-mocks'] --- import kbnCoreI18nBrowserMocksObj from './kbn_core_i18n_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_injected_metadata_browser.mdx b/api_docs/kbn_core_injected_metadata_browser.mdx index 6e200ae30b46d7..d27aa6bf74e927 100644 --- a/api_docs/kbn_core_injected_metadata_browser.mdx +++ b/api_docs/kbn_core_injected_metadata_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-injected-metadata-browser title: "@kbn/core-injected-metadata-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-injected-metadata-browser plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-injected-metadata-browser'] --- import kbnCoreInjectedMetadataBrowserObj from './kbn_core_injected_metadata_browser.devdocs.json'; diff --git a/api_docs/kbn_core_injected_metadata_browser_mocks.mdx b/api_docs/kbn_core_injected_metadata_browser_mocks.mdx index 168fc1373d7649..555223b5d4b58b 100644 --- a/api_docs/kbn_core_injected_metadata_browser_mocks.mdx +++ b/api_docs/kbn_core_injected_metadata_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-injected-metadata-browser-mocks title: "@kbn/core-injected-metadata-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-injected-metadata-browser-mocks plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-injected-metadata-browser-mocks'] --- import kbnCoreInjectedMetadataBrowserMocksObj from './kbn_core_injected_metadata_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_integrations_browser_internal.mdx b/api_docs/kbn_core_integrations_browser_internal.mdx index fdb6ec167e18a5..a4e7013cf632b1 100644 --- a/api_docs/kbn_core_integrations_browser_internal.mdx +++ b/api_docs/kbn_core_integrations_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-integrations-browser-internal title: "@kbn/core-integrations-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-integrations-browser-internal plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-integrations-browser-internal'] --- import kbnCoreIntegrationsBrowserInternalObj from './kbn_core_integrations_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_integrations_browser_mocks.mdx b/api_docs/kbn_core_integrations_browser_mocks.mdx index 56b1d7bff52fd3..c3ab38e7bc8ba8 100644 --- a/api_docs/kbn_core_integrations_browser_mocks.mdx +++ b/api_docs/kbn_core_integrations_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-integrations-browser-mocks title: "@kbn/core-integrations-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-integrations-browser-mocks plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-integrations-browser-mocks'] --- import kbnCoreIntegrationsBrowserMocksObj from './kbn_core_integrations_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_logging_server.devdocs.json b/api_docs/kbn_core_logging_server.devdocs.json index 1c62152f792f85..0e4ef7660c429a 100644 --- a/api_docs/kbn_core_logging_server.devdocs.json +++ b/api_docs/kbn_core_logging_server.devdocs.json @@ -203,7 +203,7 @@ "label": "level", "description": [], "signature": [ - "\"error\" | \"all\" | \"off\" | \"info\" | \"debug\" | \"trace\" | \"warn\" | \"fatal\"" + "\"error\" | \"all\" | \"info\" | \"debug\" | \"off\" | \"trace\" | \"warn\" | \"fatal\"" ], "path": "packages/core/logging/core-logging-server/src/logger.ts", "deprecated": false diff --git a/api_docs/kbn_core_logging_server.mdx b/api_docs/kbn_core_logging_server.mdx index 7665984946b96c..41fe1b4523dd9b 100644 --- a/api_docs/kbn_core_logging_server.mdx +++ b/api_docs/kbn_core_logging_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-server title: "@kbn/core-logging-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-server plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-logging-server'] --- import kbnCoreLoggingServerObj from './kbn_core_logging_server.devdocs.json'; diff --git a/api_docs/kbn_core_logging_server_internal.devdocs.json b/api_docs/kbn_core_logging_server_internal.devdocs.json index 7b04157c02296a..dbef8abb628d96 100644 --- a/api_docs/kbn_core_logging_server_internal.devdocs.json +++ b/api_docs/kbn_core_logging_server_internal.devdocs.json @@ -142,7 +142,7 @@ "AppenderConfigType", ">>; loggers: ", "Type", - "[]>; }>" + "[]>; }>" ], "path": "packages/core/logging/core-logging-server-internal/src/logging_config.ts", "deprecated": false, @@ -165,7 +165,7 @@ "Type", "; level: ", "Type", - "<\"error\" | \"all\" | \"off\" | \"info\" | \"debug\" | \"trace\" | \"warn\" | \"fatal\">; }>" + "<\"error\" | \"all\" | \"info\" | \"debug\" | \"off\" | \"trace\" | \"warn\" | \"fatal\">; }>" ], "path": "packages/core/logging/core-logging-server-internal/src/logging_config.ts", "deprecated": false, diff --git a/api_docs/kbn_core_logging_server_internal.mdx b/api_docs/kbn_core_logging_server_internal.mdx index 0c48c9ab717d44..f941b6f3fcfc37 100644 --- a/api_docs/kbn_core_logging_server_internal.mdx +++ b/api_docs/kbn_core_logging_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-server-internal title: "@kbn/core-logging-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-server-internal plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-logging-server-internal'] --- import kbnCoreLoggingServerInternalObj from './kbn_core_logging_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_logging_server_mocks.mdx b/api_docs/kbn_core_logging_server_mocks.mdx index 1a744de7d95722..39827481401fa2 100644 --- a/api_docs/kbn_core_logging_server_mocks.mdx +++ b/api_docs/kbn_core_logging_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-server-mocks title: "@kbn/core-logging-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-server-mocks plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-logging-server-mocks'] --- import kbnCoreLoggingServerMocksObj from './kbn_core_logging_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_metrics_collectors_server_internal.mdx b/api_docs/kbn_core_metrics_collectors_server_internal.mdx index 610b3becbb84cb..b8cbe27460ce6b 100644 --- a/api_docs/kbn_core_metrics_collectors_server_internal.mdx +++ b/api_docs/kbn_core_metrics_collectors_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-collectors-server-internal title: "@kbn/core-metrics-collectors-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-collectors-server-internal plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-metrics-collectors-server-internal'] --- import kbnCoreMetricsCollectorsServerInternalObj from './kbn_core_metrics_collectors_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_metrics_collectors_server_mocks.mdx b/api_docs/kbn_core_metrics_collectors_server_mocks.mdx index 1a63b8e7d38f12..560b3732797f0e 100644 --- a/api_docs/kbn_core_metrics_collectors_server_mocks.mdx +++ b/api_docs/kbn_core_metrics_collectors_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-collectors-server-mocks title: "@kbn/core-metrics-collectors-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-collectors-server-mocks plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-metrics-collectors-server-mocks'] --- import kbnCoreMetricsCollectorsServerMocksObj from './kbn_core_metrics_collectors_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_metrics_server.mdx b/api_docs/kbn_core_metrics_server.mdx index 84fd6cae26cc55..573da4a63b435a 100644 --- a/api_docs/kbn_core_metrics_server.mdx +++ b/api_docs/kbn_core_metrics_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-server title: "@kbn/core-metrics-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-server plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-metrics-server'] --- import kbnCoreMetricsServerObj from './kbn_core_metrics_server.devdocs.json'; diff --git a/api_docs/kbn_core_metrics_server_internal.mdx b/api_docs/kbn_core_metrics_server_internal.mdx index f29377c1d01cfe..e65e8690eaa094 100644 --- a/api_docs/kbn_core_metrics_server_internal.mdx +++ b/api_docs/kbn_core_metrics_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-server-internal title: "@kbn/core-metrics-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-server-internal plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-metrics-server-internal'] --- import kbnCoreMetricsServerInternalObj from './kbn_core_metrics_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_metrics_server_mocks.mdx b/api_docs/kbn_core_metrics_server_mocks.mdx index b78f9f8783e4d6..1d9531f20eb084 100644 --- a/api_docs/kbn_core_metrics_server_mocks.mdx +++ b/api_docs/kbn_core_metrics_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-server-mocks title: "@kbn/core-metrics-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-server-mocks plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-metrics-server-mocks'] --- import kbnCoreMetricsServerMocksObj from './kbn_core_metrics_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_mount_utils_browser.mdx b/api_docs/kbn_core_mount_utils_browser.mdx index 11da7eee5c039b..6d9592e2caf095 100644 --- a/api_docs/kbn_core_mount_utils_browser.mdx +++ b/api_docs/kbn_core_mount_utils_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-mount-utils-browser title: "@kbn/core-mount-utils-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-mount-utils-browser plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-mount-utils-browser'] --- import kbnCoreMountUtilsBrowserObj from './kbn_core_mount_utils_browser.devdocs.json'; diff --git a/api_docs/kbn_core_mount_utils_browser_internal.mdx b/api_docs/kbn_core_mount_utils_browser_internal.mdx index 7c3fc2469e5906..169db781229e5b 100644 --- a/api_docs/kbn_core_mount_utils_browser_internal.mdx +++ b/api_docs/kbn_core_mount_utils_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-mount-utils-browser-internal title: "@kbn/core-mount-utils-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-mount-utils-browser-internal plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-mount-utils-browser-internal'] --- import kbnCoreMountUtilsBrowserInternalObj from './kbn_core_mount_utils_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_node_server.mdx b/api_docs/kbn_core_node_server.mdx index faefa51ba72ee2..34cc7b47a1fec0 100644 --- a/api_docs/kbn_core_node_server.mdx +++ b/api_docs/kbn_core_node_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-node-server title: "@kbn/core-node-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-node-server plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-node-server'] --- import kbnCoreNodeServerObj from './kbn_core_node_server.devdocs.json'; diff --git a/api_docs/kbn_core_node_server_internal.mdx b/api_docs/kbn_core_node_server_internal.mdx index 6f868b5f053f3c..bff17f62bf3fee 100644 --- a/api_docs/kbn_core_node_server_internal.mdx +++ b/api_docs/kbn_core_node_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-node-server-internal title: "@kbn/core-node-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-node-server-internal plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-node-server-internal'] --- import kbnCoreNodeServerInternalObj from './kbn_core_node_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_node_server_mocks.mdx b/api_docs/kbn_core_node_server_mocks.mdx index 755ac8ccab9dd5..c7fdb3fe35c2fe 100644 --- a/api_docs/kbn_core_node_server_mocks.mdx +++ b/api_docs/kbn_core_node_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-node-server-mocks title: "@kbn/core-node-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-node-server-mocks plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-node-server-mocks'] --- import kbnCoreNodeServerMocksObj from './kbn_core_node_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_notifications_browser.devdocs.json b/api_docs/kbn_core_notifications_browser.devdocs.json index 6ca21edf2dd67a..bab2a6417b824f 100644 --- a/api_docs/kbn_core_notifications_browser.devdocs.json +++ b/api_docs/kbn_core_notifications_browser.devdocs.json @@ -651,7 +651,7 @@ "signature": [ "Pick<", "Toast", - ", \"children\" | \"onError\" | \"color\" | \"className\" | \"lang\" | \"style\" | \"role\" | \"tabIndex\" | \"aria-activedescendant\" | \"aria-atomic\" | \"aria-autocomplete\" | \"aria-busy\" | \"aria-checked\" | \"aria-colcount\" | \"aria-colindex\" | \"aria-colspan\" | \"aria-controls\" | \"aria-current\" | \"aria-describedby\" | \"aria-details\" | \"aria-disabled\" | \"aria-dropeffect\" | \"aria-errormessage\" | \"aria-expanded\" | \"aria-flowto\" | \"aria-grabbed\" | \"aria-haspopup\" | \"aria-hidden\" | \"aria-invalid\" | \"aria-keyshortcuts\" | \"aria-label\" | \"aria-labelledby\" | \"aria-level\" | \"aria-live\" | \"aria-modal\" | \"aria-multiline\" | \"aria-multiselectable\" | \"aria-orientation\" | \"aria-owns\" | \"aria-placeholder\" | \"aria-posinset\" | \"aria-pressed\" | \"aria-readonly\" | \"aria-relevant\" | \"aria-required\" | \"aria-roledescription\" | \"aria-rowcount\" | \"aria-rowindex\" | \"aria-rowspan\" | \"aria-selected\" | \"aria-setsize\" | \"aria-sort\" | \"aria-valuemax\" | \"aria-valuemin\" | \"aria-valuenow\" | \"aria-valuetext\" | \"dangerouslySetInnerHTML\" | \"onCopy\" | \"onCopyCapture\" | \"onCut\" | \"onCutCapture\" | \"onPaste\" | \"onPasteCapture\" | \"onCompositionEnd\" | \"onCompositionEndCapture\" | \"onCompositionStart\" | \"onCompositionStartCapture\" | \"onCompositionUpdate\" | \"onCompositionUpdateCapture\" | \"onFocus\" | \"onFocusCapture\" | \"onBlur\" | \"onBlurCapture\" | \"onChange\" | \"onChangeCapture\" | \"onBeforeInput\" | \"onBeforeInputCapture\" | \"onInput\" | \"onInputCapture\" | \"onReset\" | \"onResetCapture\" | \"onSubmit\" | \"onSubmitCapture\" | \"onInvalid\" | \"onInvalidCapture\" | \"onLoad\" | \"onLoadCapture\" | \"onErrorCapture\" | \"onKeyDown\" | \"onKeyDownCapture\" | \"onKeyPress\" | \"onKeyPressCapture\" | \"onKeyUp\" | \"onKeyUpCapture\" | \"onAbort\" | \"onAbortCapture\" | \"onCanPlay\" | \"onCanPlayCapture\" | \"onCanPlayThrough\" | \"onCanPlayThroughCapture\" | \"onDurationChange\" | \"onDurationChangeCapture\" | \"onEmptied\" | \"onEmptiedCapture\" | \"onEncrypted\" | \"onEncryptedCapture\" | \"onEnded\" | \"onEndedCapture\" | \"onLoadedData\" | \"onLoadedDataCapture\" | \"onLoadedMetadata\" | \"onLoadedMetadataCapture\" | \"onLoadStart\" | \"onLoadStartCapture\" | \"onPause\" | \"onPauseCapture\" | \"onPlay\" | \"onPlayCapture\" | \"onPlaying\" | \"onPlayingCapture\" | \"onProgress\" | \"onProgressCapture\" | \"onRateChange\" | \"onRateChangeCapture\" | \"onSeeked\" | \"onSeekedCapture\" | \"onSeeking\" | \"onSeekingCapture\" | \"onStalled\" | \"onStalledCapture\" | \"onSuspend\" | \"onSuspendCapture\" | \"onTimeUpdate\" | \"onTimeUpdateCapture\" | \"onVolumeChange\" | \"onVolumeChangeCapture\" | \"onWaiting\" | \"onWaitingCapture\" | \"onAuxClick\" | \"onAuxClickCapture\" | \"onClick\" | \"onClickCapture\" | \"onContextMenu\" | \"onContextMenuCapture\" | \"onDoubleClick\" | \"onDoubleClickCapture\" | \"onDrag\" | \"onDragCapture\" | \"onDragEnd\" | \"onDragEndCapture\" | \"onDragEnter\" | \"onDragEnterCapture\" | \"onDragExit\" | \"onDragExitCapture\" | \"onDragLeave\" | \"onDragLeaveCapture\" | \"onDragOver\" | \"onDragOverCapture\" | \"onDragStart\" | \"onDragStartCapture\" | \"onDrop\" | \"onDropCapture\" | \"onMouseDown\" | \"onMouseDownCapture\" | \"onMouseEnter\" | \"onMouseLeave\" | \"onMouseMove\" | \"onMouseMoveCapture\" | \"onMouseOut\" | \"onMouseOutCapture\" | \"onMouseOver\" | \"onMouseOverCapture\" | \"onMouseUp\" | \"onMouseUpCapture\" | \"onSelect\" | \"onSelectCapture\" | \"onTouchCancel\" | \"onTouchCancelCapture\" | \"onTouchEnd\" | \"onTouchEndCapture\" | \"onTouchMove\" | \"onTouchMoveCapture\" | \"onTouchStart\" | \"onTouchStartCapture\" | \"onPointerDown\" | \"onPointerDownCapture\" | \"onPointerMove\" | \"onPointerMoveCapture\" | \"onPointerUp\" | \"onPointerUpCapture\" | \"onPointerCancel\" | \"onPointerCancelCapture\" | \"onPointerEnter\" | \"onPointerEnterCapture\" | \"onPointerLeave\" | \"onPointerLeaveCapture\" | \"onPointerOver\" | \"onPointerOverCapture\" | \"onPointerOut\" | \"onPointerOutCapture\" | \"onGotPointerCapture\" | \"onGotPointerCaptureCapture\" | \"onLostPointerCapture\" | \"onLostPointerCaptureCapture\" | \"onScroll\" | \"onScrollCapture\" | \"onWheel\" | \"onWheelCapture\" | \"onAnimationStart\" | \"onAnimationStartCapture\" | \"onAnimationEnd\" | \"onAnimationEndCapture\" | \"onAnimationIteration\" | \"onAnimationIterationCapture\" | \"onTransitionEnd\" | \"onTransitionEndCapture\" | \"data-test-subj\" | \"hidden\" | \"security\" | \"defaultValue\" | \"defaultChecked\" | \"suppressContentEditableWarning\" | \"suppressHydrationWarning\" | \"accessKey\" | \"contentEditable\" | \"contextMenu\" | \"dir\" | \"draggable\" | \"placeholder\" | \"slot\" | \"spellCheck\" | \"translate\" | \"radioGroup\" | \"about\" | \"datatype\" | \"inlist\" | \"prefix\" | \"property\" | \"resource\" | \"typeof\" | \"vocab\" | \"autoCapitalize\" | \"autoCorrect\" | \"autoSave\" | \"itemProp\" | \"itemScope\" | \"itemType\" | \"itemID\" | \"itemRef\" | \"results\" | \"unselectable\" | \"inputMode\" | \"is\" | \"toastLifeTimeMs\" | \"iconType\" | \"onClose\"> & { title?: string | ", + ", \"children\" | \"onError\" | \"hidden\" | \"color\" | \"className\" | \"onChange\" | \"onKeyDown\" | \"onClick\" | \"security\" | \"defaultValue\" | \"lang\" | \"defaultChecked\" | \"suppressContentEditableWarning\" | \"suppressHydrationWarning\" | \"accessKey\" | \"contentEditable\" | \"contextMenu\" | \"dir\" | \"draggable\" | \"placeholder\" | \"slot\" | \"spellCheck\" | \"style\" | \"tabIndex\" | \"translate\" | \"radioGroup\" | \"role\" | \"about\" | \"datatype\" | \"inlist\" | \"prefix\" | \"property\" | \"resource\" | \"typeof\" | \"vocab\" | \"autoCapitalize\" | \"autoCorrect\" | \"autoSave\" | \"itemProp\" | \"itemScope\" | \"itemType\" | \"itemID\" | \"itemRef\" | \"results\" | \"unselectable\" | \"inputMode\" | \"is\" | \"aria-activedescendant\" | \"aria-atomic\" | \"aria-autocomplete\" | \"aria-busy\" | \"aria-checked\" | \"aria-colcount\" | \"aria-colindex\" | \"aria-colspan\" | \"aria-controls\" | \"aria-current\" | \"aria-describedby\" | \"aria-details\" | \"aria-disabled\" | \"aria-dropeffect\" | \"aria-errormessage\" | \"aria-expanded\" | \"aria-flowto\" | \"aria-grabbed\" | \"aria-haspopup\" | \"aria-hidden\" | \"aria-invalid\" | \"aria-keyshortcuts\" | \"aria-label\" | \"aria-labelledby\" | \"aria-level\" | \"aria-live\" | \"aria-modal\" | \"aria-multiline\" | \"aria-multiselectable\" | \"aria-orientation\" | \"aria-owns\" | \"aria-placeholder\" | \"aria-posinset\" | \"aria-pressed\" | \"aria-readonly\" | \"aria-relevant\" | \"aria-required\" | \"aria-roledescription\" | \"aria-rowcount\" | \"aria-rowindex\" | \"aria-rowspan\" | \"aria-selected\" | \"aria-setsize\" | \"aria-sort\" | \"aria-valuemax\" | \"aria-valuemin\" | \"aria-valuenow\" | \"aria-valuetext\" | \"dangerouslySetInnerHTML\" | \"onCopy\" | \"onCopyCapture\" | \"onCut\" | \"onCutCapture\" | \"onPaste\" | \"onPasteCapture\" | \"onCompositionEnd\" | \"onCompositionEndCapture\" | \"onCompositionStart\" | \"onCompositionStartCapture\" | \"onCompositionUpdate\" | \"onCompositionUpdateCapture\" | \"onFocus\" | \"onFocusCapture\" | \"onBlur\" | \"onBlurCapture\" | \"onChangeCapture\" | \"onBeforeInput\" | \"onBeforeInputCapture\" | \"onInput\" | \"onInputCapture\" | \"onReset\" | \"onResetCapture\" | \"onSubmit\" | \"onSubmitCapture\" | \"onInvalid\" | \"onInvalidCapture\" | \"onLoad\" | \"onLoadCapture\" | \"onErrorCapture\" | \"onKeyDownCapture\" | \"onKeyPress\" | \"onKeyPressCapture\" | \"onKeyUp\" | \"onKeyUpCapture\" | \"onAbort\" | \"onAbortCapture\" | \"onCanPlay\" | \"onCanPlayCapture\" | \"onCanPlayThrough\" | \"onCanPlayThroughCapture\" | \"onDurationChange\" | \"onDurationChangeCapture\" | \"onEmptied\" | \"onEmptiedCapture\" | \"onEncrypted\" | \"onEncryptedCapture\" | \"onEnded\" | \"onEndedCapture\" | \"onLoadedData\" | \"onLoadedDataCapture\" | \"onLoadedMetadata\" | \"onLoadedMetadataCapture\" | \"onLoadStart\" | \"onLoadStartCapture\" | \"onPause\" | \"onPauseCapture\" | \"onPlay\" | \"onPlayCapture\" | \"onPlaying\" | \"onPlayingCapture\" | \"onProgress\" | \"onProgressCapture\" | \"onRateChange\" | \"onRateChangeCapture\" | \"onSeeked\" | \"onSeekedCapture\" | \"onSeeking\" | \"onSeekingCapture\" | \"onStalled\" | \"onStalledCapture\" | \"onSuspend\" | \"onSuspendCapture\" | \"onTimeUpdate\" | \"onTimeUpdateCapture\" | \"onVolumeChange\" | \"onVolumeChangeCapture\" | \"onWaiting\" | \"onWaitingCapture\" | \"onAuxClick\" | \"onAuxClickCapture\" | \"onClickCapture\" | \"onContextMenu\" | \"onContextMenuCapture\" | \"onDoubleClick\" | \"onDoubleClickCapture\" | \"onDrag\" | \"onDragCapture\" | \"onDragEnd\" | \"onDragEndCapture\" | \"onDragEnter\" | \"onDragEnterCapture\" | \"onDragExit\" | \"onDragExitCapture\" | \"onDragLeave\" | \"onDragLeaveCapture\" | \"onDragOver\" | \"onDragOverCapture\" | \"onDragStart\" | \"onDragStartCapture\" | \"onDrop\" | \"onDropCapture\" | \"onMouseDown\" | \"onMouseDownCapture\" | \"onMouseEnter\" | \"onMouseLeave\" | \"onMouseMove\" | \"onMouseMoveCapture\" | \"onMouseOut\" | \"onMouseOutCapture\" | \"onMouseOver\" | \"onMouseOverCapture\" | \"onMouseUp\" | \"onMouseUpCapture\" | \"onSelect\" | \"onSelectCapture\" | \"onTouchCancel\" | \"onTouchCancelCapture\" | \"onTouchEnd\" | \"onTouchEndCapture\" | \"onTouchMove\" | \"onTouchMoveCapture\" | \"onTouchStart\" | \"onTouchStartCapture\" | \"onPointerDown\" | \"onPointerDownCapture\" | \"onPointerMove\" | \"onPointerMoveCapture\" | \"onPointerUp\" | \"onPointerUpCapture\" | \"onPointerCancel\" | \"onPointerCancelCapture\" | \"onPointerEnter\" | \"onPointerEnterCapture\" | \"onPointerLeave\" | \"onPointerLeaveCapture\" | \"onPointerOver\" | \"onPointerOverCapture\" | \"onPointerOut\" | \"onPointerOutCapture\" | \"onGotPointerCapture\" | \"onGotPointerCaptureCapture\" | \"onLostPointerCapture\" | \"onLostPointerCaptureCapture\" | \"onScroll\" | \"onScrollCapture\" | \"onWheel\" | \"onWheelCapture\" | \"onAnimationStart\" | \"onAnimationStartCapture\" | \"onAnimationEnd\" | \"onAnimationEndCapture\" | \"onAnimationIteration\" | \"onAnimationIterationCapture\" | \"onTransitionEnd\" | \"onTransitionEndCapture\" | \"toastLifeTimeMs\" | \"iconType\" | \"onClose\" | \"data-test-subj\"> & { title?: string | ", "MountPoint", " | undefined; text?: string | ", "MountPoint", @@ -696,7 +696,7 @@ "signature": [ "Pick<", "Toast", - ", \"children\" | \"onError\" | \"color\" | \"className\" | \"lang\" | \"style\" | \"role\" | \"tabIndex\" | \"aria-activedescendant\" | \"aria-atomic\" | \"aria-autocomplete\" | \"aria-busy\" | \"aria-checked\" | \"aria-colcount\" | \"aria-colindex\" | \"aria-colspan\" | \"aria-controls\" | \"aria-current\" | \"aria-describedby\" | \"aria-details\" | \"aria-disabled\" | \"aria-dropeffect\" | \"aria-errormessage\" | \"aria-expanded\" | \"aria-flowto\" | \"aria-grabbed\" | \"aria-haspopup\" | \"aria-hidden\" | \"aria-invalid\" | \"aria-keyshortcuts\" | \"aria-label\" | \"aria-labelledby\" | \"aria-level\" | \"aria-live\" | \"aria-modal\" | \"aria-multiline\" | \"aria-multiselectable\" | \"aria-orientation\" | \"aria-owns\" | \"aria-placeholder\" | \"aria-posinset\" | \"aria-pressed\" | \"aria-readonly\" | \"aria-relevant\" | \"aria-required\" | \"aria-roledescription\" | \"aria-rowcount\" | \"aria-rowindex\" | \"aria-rowspan\" | \"aria-selected\" | \"aria-setsize\" | \"aria-sort\" | \"aria-valuemax\" | \"aria-valuemin\" | \"aria-valuenow\" | \"aria-valuetext\" | \"dangerouslySetInnerHTML\" | \"onCopy\" | \"onCopyCapture\" | \"onCut\" | \"onCutCapture\" | \"onPaste\" | \"onPasteCapture\" | \"onCompositionEnd\" | \"onCompositionEndCapture\" | \"onCompositionStart\" | \"onCompositionStartCapture\" | \"onCompositionUpdate\" | \"onCompositionUpdateCapture\" | \"onFocus\" | \"onFocusCapture\" | \"onBlur\" | \"onBlurCapture\" | \"onChange\" | \"onChangeCapture\" | \"onBeforeInput\" | \"onBeforeInputCapture\" | \"onInput\" | \"onInputCapture\" | \"onReset\" | \"onResetCapture\" | \"onSubmit\" | \"onSubmitCapture\" | \"onInvalid\" | \"onInvalidCapture\" | \"onLoad\" | \"onLoadCapture\" | \"onErrorCapture\" | \"onKeyDown\" | \"onKeyDownCapture\" | \"onKeyPress\" | \"onKeyPressCapture\" | \"onKeyUp\" | \"onKeyUpCapture\" | \"onAbort\" | \"onAbortCapture\" | \"onCanPlay\" | \"onCanPlayCapture\" | \"onCanPlayThrough\" | \"onCanPlayThroughCapture\" | \"onDurationChange\" | \"onDurationChangeCapture\" | \"onEmptied\" | \"onEmptiedCapture\" | \"onEncrypted\" | \"onEncryptedCapture\" | \"onEnded\" | \"onEndedCapture\" | \"onLoadedData\" | \"onLoadedDataCapture\" | \"onLoadedMetadata\" | \"onLoadedMetadataCapture\" | \"onLoadStart\" | \"onLoadStartCapture\" | \"onPause\" | \"onPauseCapture\" | \"onPlay\" | \"onPlayCapture\" | \"onPlaying\" | \"onPlayingCapture\" | \"onProgress\" | \"onProgressCapture\" | \"onRateChange\" | \"onRateChangeCapture\" | \"onSeeked\" | \"onSeekedCapture\" | \"onSeeking\" | \"onSeekingCapture\" | \"onStalled\" | \"onStalledCapture\" | \"onSuspend\" | \"onSuspendCapture\" | \"onTimeUpdate\" | \"onTimeUpdateCapture\" | \"onVolumeChange\" | \"onVolumeChangeCapture\" | \"onWaiting\" | \"onWaitingCapture\" | \"onAuxClick\" | \"onAuxClickCapture\" | \"onClick\" | \"onClickCapture\" | \"onContextMenu\" | \"onContextMenuCapture\" | \"onDoubleClick\" | \"onDoubleClickCapture\" | \"onDrag\" | \"onDragCapture\" | \"onDragEnd\" | \"onDragEndCapture\" | \"onDragEnter\" | \"onDragEnterCapture\" | \"onDragExit\" | \"onDragExitCapture\" | \"onDragLeave\" | \"onDragLeaveCapture\" | \"onDragOver\" | \"onDragOverCapture\" | \"onDragStart\" | \"onDragStartCapture\" | \"onDrop\" | \"onDropCapture\" | \"onMouseDown\" | \"onMouseDownCapture\" | \"onMouseEnter\" | \"onMouseLeave\" | \"onMouseMove\" | \"onMouseMoveCapture\" | \"onMouseOut\" | \"onMouseOutCapture\" | \"onMouseOver\" | \"onMouseOverCapture\" | \"onMouseUp\" | \"onMouseUpCapture\" | \"onSelect\" | \"onSelectCapture\" | \"onTouchCancel\" | \"onTouchCancelCapture\" | \"onTouchEnd\" | \"onTouchEndCapture\" | \"onTouchMove\" | \"onTouchMoveCapture\" | \"onTouchStart\" | \"onTouchStartCapture\" | \"onPointerDown\" | \"onPointerDownCapture\" | \"onPointerMove\" | \"onPointerMoveCapture\" | \"onPointerUp\" | \"onPointerUpCapture\" | \"onPointerCancel\" | \"onPointerCancelCapture\" | \"onPointerEnter\" | \"onPointerEnterCapture\" | \"onPointerLeave\" | \"onPointerLeaveCapture\" | \"onPointerOver\" | \"onPointerOverCapture\" | \"onPointerOut\" | \"onPointerOutCapture\" | \"onGotPointerCapture\" | \"onGotPointerCaptureCapture\" | \"onLostPointerCapture\" | \"onLostPointerCaptureCapture\" | \"onScroll\" | \"onScrollCapture\" | \"onWheel\" | \"onWheelCapture\" | \"onAnimationStart\" | \"onAnimationStartCapture\" | \"onAnimationEnd\" | \"onAnimationEndCapture\" | \"onAnimationIteration\" | \"onAnimationIterationCapture\" | \"onTransitionEnd\" | \"onTransitionEndCapture\" | \"data-test-subj\" | \"hidden\" | \"security\" | \"defaultValue\" | \"defaultChecked\" | \"suppressContentEditableWarning\" | \"suppressHydrationWarning\" | \"accessKey\" | \"contentEditable\" | \"contextMenu\" | \"dir\" | \"draggable\" | \"placeholder\" | \"slot\" | \"spellCheck\" | \"translate\" | \"radioGroup\" | \"about\" | \"datatype\" | \"inlist\" | \"prefix\" | \"property\" | \"resource\" | \"typeof\" | \"vocab\" | \"autoCapitalize\" | \"autoCorrect\" | \"autoSave\" | \"itemProp\" | \"itemScope\" | \"itemType\" | \"itemID\" | \"itemRef\" | \"results\" | \"unselectable\" | \"inputMode\" | \"is\" | \"toastLifeTimeMs\" | \"iconType\" | \"onClose\"> & { title?: string | ", + ", \"children\" | \"onError\" | \"hidden\" | \"color\" | \"className\" | \"onChange\" | \"onKeyDown\" | \"onClick\" | \"security\" | \"defaultValue\" | \"lang\" | \"defaultChecked\" | \"suppressContentEditableWarning\" | \"suppressHydrationWarning\" | \"accessKey\" | \"contentEditable\" | \"contextMenu\" | \"dir\" | \"draggable\" | \"placeholder\" | \"slot\" | \"spellCheck\" | \"style\" | \"tabIndex\" | \"translate\" | \"radioGroup\" | \"role\" | \"about\" | \"datatype\" | \"inlist\" | \"prefix\" | \"property\" | \"resource\" | \"typeof\" | \"vocab\" | \"autoCapitalize\" | \"autoCorrect\" | \"autoSave\" | \"itemProp\" | \"itemScope\" | \"itemType\" | \"itemID\" | \"itemRef\" | \"results\" | \"unselectable\" | \"inputMode\" | \"is\" | \"aria-activedescendant\" | \"aria-atomic\" | \"aria-autocomplete\" | \"aria-busy\" | \"aria-checked\" | \"aria-colcount\" | \"aria-colindex\" | \"aria-colspan\" | \"aria-controls\" | \"aria-current\" | \"aria-describedby\" | \"aria-details\" | \"aria-disabled\" | \"aria-dropeffect\" | \"aria-errormessage\" | \"aria-expanded\" | \"aria-flowto\" | \"aria-grabbed\" | \"aria-haspopup\" | \"aria-hidden\" | \"aria-invalid\" | \"aria-keyshortcuts\" | \"aria-label\" | \"aria-labelledby\" | \"aria-level\" | \"aria-live\" | \"aria-modal\" | \"aria-multiline\" | \"aria-multiselectable\" | \"aria-orientation\" | \"aria-owns\" | \"aria-placeholder\" | \"aria-posinset\" | \"aria-pressed\" | \"aria-readonly\" | \"aria-relevant\" | \"aria-required\" | \"aria-roledescription\" | \"aria-rowcount\" | \"aria-rowindex\" | \"aria-rowspan\" | \"aria-selected\" | \"aria-setsize\" | \"aria-sort\" | \"aria-valuemax\" | \"aria-valuemin\" | \"aria-valuenow\" | \"aria-valuetext\" | \"dangerouslySetInnerHTML\" | \"onCopy\" | \"onCopyCapture\" | \"onCut\" | \"onCutCapture\" | \"onPaste\" | \"onPasteCapture\" | \"onCompositionEnd\" | \"onCompositionEndCapture\" | \"onCompositionStart\" | \"onCompositionStartCapture\" | \"onCompositionUpdate\" | \"onCompositionUpdateCapture\" | \"onFocus\" | \"onFocusCapture\" | \"onBlur\" | \"onBlurCapture\" | \"onChangeCapture\" | \"onBeforeInput\" | \"onBeforeInputCapture\" | \"onInput\" | \"onInputCapture\" | \"onReset\" | \"onResetCapture\" | \"onSubmit\" | \"onSubmitCapture\" | \"onInvalid\" | \"onInvalidCapture\" | \"onLoad\" | \"onLoadCapture\" | \"onErrorCapture\" | \"onKeyDownCapture\" | \"onKeyPress\" | \"onKeyPressCapture\" | \"onKeyUp\" | \"onKeyUpCapture\" | \"onAbort\" | \"onAbortCapture\" | \"onCanPlay\" | \"onCanPlayCapture\" | \"onCanPlayThrough\" | \"onCanPlayThroughCapture\" | \"onDurationChange\" | \"onDurationChangeCapture\" | \"onEmptied\" | \"onEmptiedCapture\" | \"onEncrypted\" | \"onEncryptedCapture\" | \"onEnded\" | \"onEndedCapture\" | \"onLoadedData\" | \"onLoadedDataCapture\" | \"onLoadedMetadata\" | \"onLoadedMetadataCapture\" | \"onLoadStart\" | \"onLoadStartCapture\" | \"onPause\" | \"onPauseCapture\" | \"onPlay\" | \"onPlayCapture\" | \"onPlaying\" | \"onPlayingCapture\" | \"onProgress\" | \"onProgressCapture\" | \"onRateChange\" | \"onRateChangeCapture\" | \"onSeeked\" | \"onSeekedCapture\" | \"onSeeking\" | \"onSeekingCapture\" | \"onStalled\" | \"onStalledCapture\" | \"onSuspend\" | \"onSuspendCapture\" | \"onTimeUpdate\" | \"onTimeUpdateCapture\" | \"onVolumeChange\" | \"onVolumeChangeCapture\" | \"onWaiting\" | \"onWaitingCapture\" | \"onAuxClick\" | \"onAuxClickCapture\" | \"onClickCapture\" | \"onContextMenu\" | \"onContextMenuCapture\" | \"onDoubleClick\" | \"onDoubleClickCapture\" | \"onDrag\" | \"onDragCapture\" | \"onDragEnd\" | \"onDragEndCapture\" | \"onDragEnter\" | \"onDragEnterCapture\" | \"onDragExit\" | \"onDragExitCapture\" | \"onDragLeave\" | \"onDragLeaveCapture\" | \"onDragOver\" | \"onDragOverCapture\" | \"onDragStart\" | \"onDragStartCapture\" | \"onDrop\" | \"onDropCapture\" | \"onMouseDown\" | \"onMouseDownCapture\" | \"onMouseEnter\" | \"onMouseLeave\" | \"onMouseMove\" | \"onMouseMoveCapture\" | \"onMouseOut\" | \"onMouseOutCapture\" | \"onMouseOver\" | \"onMouseOverCapture\" | \"onMouseUp\" | \"onMouseUpCapture\" | \"onSelect\" | \"onSelectCapture\" | \"onTouchCancel\" | \"onTouchCancelCapture\" | \"onTouchEnd\" | \"onTouchEndCapture\" | \"onTouchMove\" | \"onTouchMoveCapture\" | \"onTouchStart\" | \"onTouchStartCapture\" | \"onPointerDown\" | \"onPointerDownCapture\" | \"onPointerMove\" | \"onPointerMoveCapture\" | \"onPointerUp\" | \"onPointerUpCapture\" | \"onPointerCancel\" | \"onPointerCancelCapture\" | \"onPointerEnter\" | \"onPointerEnterCapture\" | \"onPointerLeave\" | \"onPointerLeaveCapture\" | \"onPointerOver\" | \"onPointerOverCapture\" | \"onPointerOut\" | \"onPointerOutCapture\" | \"onGotPointerCapture\" | \"onGotPointerCaptureCapture\" | \"onLostPointerCapture\" | \"onLostPointerCaptureCapture\" | \"onScroll\" | \"onScrollCapture\" | \"onWheel\" | \"onWheelCapture\" | \"onAnimationStart\" | \"onAnimationStartCapture\" | \"onAnimationEnd\" | \"onAnimationEndCapture\" | \"onAnimationIteration\" | \"onAnimationIterationCapture\" | \"onTransitionEnd\" | \"onTransitionEndCapture\" | \"toastLifeTimeMs\" | \"iconType\" | \"onClose\" | \"data-test-subj\"> & { title?: string | ", "MountPoint", " | undefined; text?: string | ", "MountPoint", diff --git a/api_docs/kbn_core_notifications_browser.mdx b/api_docs/kbn_core_notifications_browser.mdx index 8b6da66d279421..32cc9434669875 100644 --- a/api_docs/kbn_core_notifications_browser.mdx +++ b/api_docs/kbn_core_notifications_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-notifications-browser title: "@kbn/core-notifications-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-notifications-browser plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-notifications-browser'] --- import kbnCoreNotificationsBrowserObj from './kbn_core_notifications_browser.devdocs.json'; diff --git a/api_docs/kbn_core_notifications_browser_internal.mdx b/api_docs/kbn_core_notifications_browser_internal.mdx index d963b113ac90e3..7121bb9bbebd59 100644 --- a/api_docs/kbn_core_notifications_browser_internal.mdx +++ b/api_docs/kbn_core_notifications_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-notifications-browser-internal title: "@kbn/core-notifications-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-notifications-browser-internal plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-notifications-browser-internal'] --- import kbnCoreNotificationsBrowserInternalObj from './kbn_core_notifications_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_notifications_browser_mocks.mdx b/api_docs/kbn_core_notifications_browser_mocks.mdx index 0c20364e19577c..0e3a77f39f7988 100644 --- a/api_docs/kbn_core_notifications_browser_mocks.mdx +++ b/api_docs/kbn_core_notifications_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-notifications-browser-mocks title: "@kbn/core-notifications-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-notifications-browser-mocks plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-notifications-browser-mocks'] --- import kbnCoreNotificationsBrowserMocksObj from './kbn_core_notifications_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_overlays_browser.devdocs.json b/api_docs/kbn_core_overlays_browser.devdocs.json index 37ccf6337584b1..dc76f84740ba1b 100644 --- a/api_docs/kbn_core_overlays_browser.devdocs.json +++ b/api_docs/kbn_core_overlays_browser.devdocs.json @@ -293,7 +293,7 @@ "label": "size", "description": [], "signature": [ - "\"s\" | \"m\" | \"l\" | undefined" + "\"m\" | \"s\" | \"l\" | undefined" ], "path": "packages/core/overlays/core-overlays-browser/src/flyout.ts", "deprecated": false diff --git a/api_docs/kbn_core_overlays_browser.mdx b/api_docs/kbn_core_overlays_browser.mdx index 2d962c8a0540d2..250c60ef100008 100644 --- a/api_docs/kbn_core_overlays_browser.mdx +++ b/api_docs/kbn_core_overlays_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-overlays-browser title: "@kbn/core-overlays-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-overlays-browser plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-overlays-browser'] --- import kbnCoreOverlaysBrowserObj from './kbn_core_overlays_browser.devdocs.json'; diff --git a/api_docs/kbn_core_overlays_browser_internal.mdx b/api_docs/kbn_core_overlays_browser_internal.mdx index 508548d945d604..70eceda4340f47 100644 --- a/api_docs/kbn_core_overlays_browser_internal.mdx +++ b/api_docs/kbn_core_overlays_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-overlays-browser-internal title: "@kbn/core-overlays-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-overlays-browser-internal plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-overlays-browser-internal'] --- import kbnCoreOverlaysBrowserInternalObj from './kbn_core_overlays_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_overlays_browser_mocks.mdx b/api_docs/kbn_core_overlays_browser_mocks.mdx index ff1af6f35cc379..76bd3cfcd28b06 100644 --- a/api_docs/kbn_core_overlays_browser_mocks.mdx +++ b/api_docs/kbn_core_overlays_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-overlays-browser-mocks title: "@kbn/core-overlays-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-overlays-browser-mocks plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-overlays-browser-mocks'] --- import kbnCoreOverlaysBrowserMocksObj from './kbn_core_overlays_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_preboot_server.mdx b/api_docs/kbn_core_preboot_server.mdx index 10bc1553d364a5..45190a54804cc8 100644 --- a/api_docs/kbn_core_preboot_server.mdx +++ b/api_docs/kbn_core_preboot_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-preboot-server title: "@kbn/core-preboot-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-preboot-server plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-preboot-server'] --- import kbnCorePrebootServerObj from './kbn_core_preboot_server.devdocs.json'; diff --git a/api_docs/kbn_core_preboot_server_mocks.mdx b/api_docs/kbn_core_preboot_server_mocks.mdx index c4b4603fae1dff..3184ec2a3e44fb 100644 --- a/api_docs/kbn_core_preboot_server_mocks.mdx +++ b/api_docs/kbn_core_preboot_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-preboot-server-mocks title: "@kbn/core-preboot-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-preboot-server-mocks plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-preboot-server-mocks'] --- import kbnCorePrebootServerMocksObj from './kbn_core_preboot_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_api_browser.devdocs.json b/api_docs/kbn_core_saved_objects_api_browser.devdocs.json index 84e904ed0d0aad..82b771de6f5132 100644 --- a/api_docs/kbn_core_saved_objects_api_browser.devdocs.json +++ b/api_docs/kbn_core_saved_objects_api_browser.devdocs.json @@ -1675,9 +1675,9 @@ "label": "SavedObjectsFindOptions", "description": [], "signature": [ - "{ type: string | string[]; filter?: any; search?: string | undefined; page?: number | undefined; aggs?: Record | undefined; fields?: string[] | undefined; perPage?: number | undefined; sortField?: string | undefined; searchFields?: string[] | undefined; hasReference?: ", + "> | undefined; fields?: string[] | undefined; page?: number | undefined; perPage?: number | undefined; sortField?: string | undefined; searchFields?: string[] | undefined; hasReference?: ", "SavedObjectsFindOptionsReference", " | ", "SavedObjectsFindOptionsReference", diff --git a/api_docs/kbn_core_saved_objects_api_browser.mdx b/api_docs/kbn_core_saved_objects_api_browser.mdx index d6fa6984839883..d095cc583b1c03 100644 --- a/api_docs/kbn_core_saved_objects_api_browser.mdx +++ b/api_docs/kbn_core_saved_objects_api_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-api-browser title: "@kbn/core-saved-objects-api-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-api-browser plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-api-browser'] --- import kbnCoreSavedObjectsApiBrowserObj from './kbn_core_saved_objects_api_browser.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_api_server.mdx b/api_docs/kbn_core_saved_objects_api_server.mdx index bb03fb51e0380a..e28404cb72ea7d 100644 --- a/api_docs/kbn_core_saved_objects_api_server.mdx +++ b/api_docs/kbn_core_saved_objects_api_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-api-server title: "@kbn/core-saved-objects-api-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-api-server plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-api-server'] --- import kbnCoreSavedObjectsApiServerObj from './kbn_core_saved_objects_api_server.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_base_server_internal.devdocs.json b/api_docs/kbn_core_saved_objects_base_server_internal.devdocs.json new file mode 100644 index 00000000000000..b30cc8fc4006f0 --- /dev/null +++ b/api_docs/kbn_core_saved_objects_base_server_internal.devdocs.json @@ -0,0 +1,585 @@ +{ + "id": "@kbn/core-saved-objects-base-server-internal", + "client": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "server": { + "classes": [ + { + "parentPluginId": "@kbn/core-saved-objects-base-server-internal", + "id": "def-server.SavedObjectConfig", + "type": "Class", + "tags": [], + "label": "SavedObjectConfig", + "description": [], + "path": "packages/core/saved-objects/core-saved-objects-base-server-internal/src/saved_objects_config.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/core-saved-objects-base-server-internal", + "id": "def-server.SavedObjectConfig.maxImportPayloadBytes", + "type": "number", + "tags": [], + "label": "maxImportPayloadBytes", + "description": [], + "path": "packages/core/saved-objects/core-saved-objects-base-server-internal/src/saved_objects_config.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/core-saved-objects-base-server-internal", + "id": "def-server.SavedObjectConfig.maxImportExportSize", + "type": "number", + "tags": [], + "label": "maxImportExportSize", + "description": [], + "path": "packages/core/saved-objects/core-saved-objects-base-server-internal/src/saved_objects_config.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/core-saved-objects-base-server-internal", + "id": "def-server.SavedObjectConfig.migration", + "type": "Object", + "tags": [], + "label": "migration", + "description": [], + "signature": [ + "{ readonly discardUnknownObjects?: string | undefined; readonly discardCorruptObjects?: string | undefined; readonly pollInterval: number; readonly skip: boolean; readonly batchSize: number; readonly maxBatchSizeBytes: ", + "ByteSizeValue", + "; readonly scrollDuration: string; readonly retryAttempts: number; }" + ], + "path": "packages/core/saved-objects/core-saved-objects-base-server-internal/src/saved_objects_config.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/core-saved-objects-base-server-internal", + "id": "def-server.SavedObjectConfig.Unnamed", + "type": "Function", + "tags": [], + "label": "Constructor", + "description": [], + "signature": [ + "any" + ], + "path": "packages/core/saved-objects/core-saved-objects-base-server-internal/src/saved_objects_config.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/core-saved-objects-base-server-internal", + "id": "def-server.SavedObjectConfig.Unnamed.$1", + "type": "Object", + "tags": [], + "label": "rawConfig", + "description": [], + "signature": [ + "Readonly<{} & { maxImportPayloadBytes: ", + "ByteSizeValue", + "; maxImportExportSize: number; }>" + ], + "path": "packages/core/saved-objects/core-saved-objects-base-server-internal/src/saved_objects_config.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/core-saved-objects-base-server-internal", + "id": "def-server.SavedObjectConfig.Unnamed.$2", + "type": "Object", + "tags": [], + "label": "rawMigrationConfig", + "description": [], + "signature": [ + "Readonly<{ discardUnknownObjects?: string | undefined; discardCorruptObjects?: string | undefined; } & { pollInterval: number; skip: boolean; batchSize: number; maxBatchSizeBytes: ", + "ByteSizeValue", + "; scrollDuration: string; retryAttempts: number; }>" + ], + "path": "packages/core/saved-objects/core-saved-objects-base-server-internal/src/saved_objects_config.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + } + ], + "initialIsOpen": false + } + ], + "functions": [ + { + "parentPluginId": "@kbn/core-saved-objects-base-server-internal", + "id": "def-server.decodeRequestVersion", + "type": "Function", + "tags": [], + "label": "decodeRequestVersion", + "description": [ + "\nHelper for decoding version to request params that are driven\nby the version info" + ], + "signature": [ + "(version: string | undefined) => { if_seq_no: number; if_primary_term: number; }" + ], + "path": "packages/core/saved-objects/core-saved-objects-base-server-internal/src/version/decode_request_version.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/core-saved-objects-base-server-internal", + "id": "def-server.decodeRequestVersion.$1", + "type": "string", + "tags": [], + "label": "version", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "packages/core/saved-objects/core-saved-objects-base-server-internal/src/version/decode_request_version.ts", + "deprecated": false, + "isRequired": false + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/core-saved-objects-base-server-internal", + "id": "def-server.decodeVersion", + "type": "Function", + "tags": [], + "label": "decodeVersion", + "description": [ + "\nDecode the \"opaque\" version string to the sequence params we\ncan use to activate optimistic concurrency in Elasticsearch" + ], + "signature": [ + "(version: string | undefined) => { _seq_no: number; _primary_term: number; }" + ], + "path": "packages/core/saved-objects/core-saved-objects-base-server-internal/src/version/decode_version.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/core-saved-objects-base-server-internal", + "id": "def-server.decodeVersion.$1", + "type": "string", + "tags": [], + "label": "version", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "packages/core/saved-objects/core-saved-objects-base-server-internal/src/version/decode_version.ts", + "deprecated": false, + "isRequired": false + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/core-saved-objects-base-server-internal", + "id": "def-server.encodeHitVersion", + "type": "Function", + "tags": [], + "label": "encodeHitVersion", + "description": [ + "\nHelper for encoding a version from a \"hit\" (hits.hits[#] from _search) or\n\"doc\" (body from GET, update, etc) object" + ], + "signature": [ + "(response: { _seq_no?: number | undefined; _primary_term?: number | undefined; }) => string" + ], + "path": "packages/core/saved-objects/core-saved-objects-base-server-internal/src/version/encode_hit_version.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/core-saved-objects-base-server-internal", + "id": "def-server.encodeHitVersion.$1", + "type": "Object", + "tags": [], + "label": "response", + "description": [], + "path": "packages/core/saved-objects/core-saved-objects-base-server-internal/src/version/encode_hit_version.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/core-saved-objects-base-server-internal", + "id": "def-server.encodeHitVersion.$1._seq_no", + "type": "number", + "tags": [], + "label": "_seq_no", + "description": [], + "signature": [ + "number | undefined" + ], + "path": "packages/core/saved-objects/core-saved-objects-base-server-internal/src/version/encode_hit_version.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/core-saved-objects-base-server-internal", + "id": "def-server.encodeHitVersion.$1._primary_term", + "type": "number", + "tags": [], + "label": "_primary_term", + "description": [], + "signature": [ + "number | undefined" + ], + "path": "packages/core/saved-objects/core-saved-objects-base-server-internal/src/version/encode_hit_version.ts", + "deprecated": false + } + ] + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/core-saved-objects-base-server-internal", + "id": "def-server.encodeVersion", + "type": "Function", + "tags": [], + "label": "encodeVersion", + "description": [ + "\nEncode the sequence params into an \"opaque\" version string\nthat can be used in the saved object API in place of numeric\nversion numbers" + ], + "signature": [ + "(seqNo: number | undefined, primaryTerm: number | undefined) => string" + ], + "path": "packages/core/saved-objects/core-saved-objects-base-server-internal/src/version/encode_version.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/core-saved-objects-base-server-internal", + "id": "def-server.encodeVersion.$1", + "type": "number", + "tags": [], + "label": "seqNo", + "description": [], + "signature": [ + "number | undefined" + ], + "path": "packages/core/saved-objects/core-saved-objects-base-server-internal/src/version/encode_version.ts", + "deprecated": false, + "isRequired": false + }, + { + "parentPluginId": "@kbn/core-saved-objects-base-server-internal", + "id": "def-server.encodeVersion.$2", + "type": "number", + "tags": [], + "label": "primaryTerm", + "description": [], + "signature": [ + "number | undefined" + ], + "path": "packages/core/saved-objects/core-saved-objects-base-server-internal/src/version/encode_version.ts", + "deprecated": false, + "isRequired": false + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/core-saved-objects-base-server-internal", + "id": "def-server.getProperty", + "type": "Function", + "tags": [], + "label": "getProperty", + "description": [], + "signature": [ + "(mappings: ", + "SavedObjectsFieldMapping", + " | ", + "IndexMapping", + ", path: string | string[]) => ", + "SavedObjectsFieldMapping", + " | undefined" + ], + "path": "packages/core/saved-objects/core-saved-objects-base-server-internal/src/mappings/lib/get_property.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/core-saved-objects-base-server-internal", + "id": "def-server.getProperty.$1", + "type": "CompoundType", + "tags": [], + "label": "mappings", + "description": [], + "signature": [ + "SavedObjectsFieldMapping", + " | ", + "IndexMapping" + ], + "path": "packages/core/saved-objects/core-saved-objects-base-server-internal/src/mappings/lib/get_property.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/core-saved-objects-base-server-internal", + "id": "def-server.getProperty.$2", + "type": "CompoundType", + "tags": [], + "label": "path", + "description": [], + "signature": [ + "string | string[]" + ], + "path": "packages/core/saved-objects/core-saved-objects-base-server-internal/src/mappings/lib/get_property.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/core-saved-objects-base-server-internal", + "id": "def-server.getRootProperties", + "type": "Function", + "tags": [], + "label": "getRootProperties", + "description": [ + "\n Get the property mappings for the root type in the EsMappingsDsl\n\n If the mappings don't have a root type, or the root type is not\n an object type (it's a keyword or something) this function will\n throw an error.\n\n EsPropertyMappings objects have the root property names as their\n first level keys which map to the mappings object for each property.\n If the property is of type object it too could have a `properties`\n key whose value follows the same format.\n\n This data can be found at `{indexName}.mappings.{typeName}.properties`\n in the es indices.get() response." + ], + "signature": [ + "(mapping: ", + "IndexMapping", + ") => ", + "SavedObjectsMappingProperties" + ], + "path": "packages/core/saved-objects/core-saved-objects-base-server-internal/src/mappings/lib/get_root_properties.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/core-saved-objects-base-server-internal", + "id": "def-server.getRootProperties.$1", + "type": "Object", + "tags": [], + "label": "mapping", + "description": [], + "signature": [ + "IndexMapping" + ], + "path": "packages/core/saved-objects/core-saved-objects-base-server-internal/src/mappings/lib/get_root_properties.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/core-saved-objects-base-server-internal", + "id": "def-server.getRootPropertiesObjects", + "type": "Function", + "tags": [], + "label": "getRootPropertiesObjects", + "description": [], + "signature": [ + "(mappings: ", + "IndexMapping", + ") => ", + "SavedObjectsMappingProperties" + ], + "path": "packages/core/saved-objects/core-saved-objects-base-server-internal/src/mappings/lib/get_root_properties_objects.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/core-saved-objects-base-server-internal", + "id": "def-server.getRootPropertiesObjects.$1", + "type": "Object", + "tags": [], + "label": "mappings", + "description": [], + "signature": [ + "IndexMapping" + ], + "path": "packages/core/saved-objects/core-saved-objects-base-server-internal/src/mappings/lib/get_root_properties_objects.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/core-saved-objects-base-server-internal", + "id": "def-server.getTypes", + "type": "Function", + "tags": [], + "label": "getTypes", + "description": [ + "\n Get the names of the types defined in the EsMappingsDsl" + ], + "signature": [ + "(mappings: ", + "IndexMapping", + ") => string[]" + ], + "path": "packages/core/saved-objects/core-saved-objects-base-server-internal/src/mappings/lib/get_types.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/core-saved-objects-base-server-internal", + "id": "def-server.getTypes.$1", + "type": "Object", + "tags": [], + "label": "mappings", + "description": [], + "signature": [ + "IndexMapping" + ], + "path": "packages/core/saved-objects/core-saved-objects-base-server-internal/src/mappings/lib/get_types.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + } + ], + "interfaces": [], + "enums": [], + "misc": [ + { + "parentPluginId": "@kbn/core-saved-objects-base-server-internal", + "id": "def-server.SavedObjectsConfigType", + "type": "Type", + "tags": [], + "label": "SavedObjectsConfigType", + "description": [], + "signature": [ + "{ readonly maxImportPayloadBytes: ", + "ByteSizeValue", + "; readonly maxImportExportSize: number; }" + ], + "path": "packages/core/saved-objects/core-saved-objects-base-server-internal/src/saved_objects_config.ts", + "deprecated": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/core-saved-objects-base-server-internal", + "id": "def-server.SavedObjectsMigrationConfigType", + "type": "Type", + "tags": [], + "label": "SavedObjectsMigrationConfigType", + "description": [], + "signature": [ + "{ readonly discardUnknownObjects?: string | undefined; readonly discardCorruptObjects?: string | undefined; readonly pollInterval: number; readonly skip: boolean; readonly batchSize: number; readonly maxBatchSizeBytes: ", + "ByteSizeValue", + "; readonly scrollDuration: string; readonly retryAttempts: number; }" + ], + "path": "packages/core/saved-objects/core-saved-objects-base-server-internal/src/saved_objects_config.ts", + "deprecated": false, + "initialIsOpen": false + } + ], + "objects": [ + { + "parentPluginId": "@kbn/core-saved-objects-base-server-internal", + "id": "def-server.savedObjectsConfig", + "type": "Object", + "tags": [], + "label": "savedObjectsConfig", + "description": [], + "path": "packages/core/saved-objects/core-saved-objects-base-server-internal/src/saved_objects_config.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/core-saved-objects-base-server-internal", + "id": "def-server.savedObjectsConfig.path", + "type": "string", + "tags": [], + "label": "path", + "description": [], + "path": "packages/core/saved-objects/core-saved-objects-base-server-internal/src/saved_objects_config.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/core-saved-objects-base-server-internal", + "id": "def-server.savedObjectsConfig.schema", + "type": "Object", + "tags": [], + "label": "schema", + "description": [], + "signature": [ + "ObjectType", + "<{ maxImportPayloadBytes: ", + "Type", + "<", + "ByteSizeValue", + ">; maxImportExportSize: ", + "Type", + "; }>" + ], + "path": "packages/core/saved-objects/core-saved-objects-base-server-internal/src/saved_objects_config.ts", + "deprecated": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/core-saved-objects-base-server-internal", + "id": "def-server.savedObjectsMigrationConfig", + "type": "Object", + "tags": [], + "label": "savedObjectsMigrationConfig", + "description": [], + "path": "packages/core/saved-objects/core-saved-objects-base-server-internal/src/saved_objects_config.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/core-saved-objects-base-server-internal", + "id": "def-server.savedObjectsMigrationConfig.path", + "type": "string", + "tags": [], + "label": "path", + "description": [], + "path": "packages/core/saved-objects/core-saved-objects-base-server-internal/src/saved_objects_config.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/core-saved-objects-base-server-internal", + "id": "def-server.savedObjectsMigrationConfig.schema", + "type": "Object", + "tags": [], + "label": "schema", + "description": [], + "signature": [ + "ObjectType", + "<{ batchSize: ", + "Type", + "; maxBatchSizeBytes: ", + "Type", + "<", + "ByteSizeValue", + ">; discardUnknownObjects: ", + "Type", + "; discardCorruptObjects: ", + "Type", + "; scrollDuration: ", + "Type", + "; pollInterval: ", + "Type", + "; skip: ", + "Type", + "; retryAttempts: ", + "Type", + "; }>" + ], + "path": "packages/core/saved-objects/core-saved-objects-base-server-internal/src/saved_objects_config.ts", + "deprecated": false + } + ], + "initialIsOpen": false + } + ] + }, + "common": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + } +} \ No newline at end of file diff --git a/api_docs/kbn_core_saved_objects_base_server_internal.mdx b/api_docs/kbn_core_saved_objects_base_server_internal.mdx new file mode 100644 index 00000000000000..61ab94f857fcbd --- /dev/null +++ b/api_docs/kbn_core_saved_objects_base_server_internal.mdx @@ -0,0 +1,39 @@ +--- +#### +#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system. +#### Reach out in #docs-engineering for more info. +#### +id: kibKbnCoreSavedObjectsBaseServerInternalPluginApi +slug: /kibana-dev-docs/api/kbn-core-saved-objects-base-server-internal +title: "@kbn/core-saved-objects-base-server-internal" +image: https://source.unsplash.com/400x175/?github +description: API docs for the @kbn/core-saved-objects-base-server-internal plugin +date: 2022-08-24 +tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-base-server-internal'] +--- +import kbnCoreSavedObjectsBaseServerInternalObj from './kbn_core_saved_objects_base_server_internal.devdocs.json'; + + + +Contact [Owner missing] for questions regarding this plugin. + +**Code health stats** + +| Public API count | Any count | Items lacking comments | Missing exports | +|-------------------|-----------|------------------------|-----------------| +| 35 | 0 | 29 | 1 | + +## Server + +### Objects + + +### Functions + + +### Classes + + +### Consts, variables and types + + diff --git a/api_docs/kbn_core_saved_objects_base_server_mocks.devdocs.json b/api_docs/kbn_core_saved_objects_base_server_mocks.devdocs.json new file mode 100644 index 00000000000000..cab8d6394bd147 --- /dev/null +++ b/api_docs/kbn_core_saved_objects_base_server_mocks.devdocs.json @@ -0,0 +1,90 @@ +{ + "id": "@kbn/core-saved-objects-base-server-mocks", + "client": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "server": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [ + { + "parentPluginId": "@kbn/core-saved-objects-base-server-mocks", + "id": "def-server.serializerMock", + "type": "Object", + "tags": [], + "label": "serializerMock", + "description": [], + "path": "packages/core/saved-objects/core-saved-objects-base-server-mocks/src/serializer.mock.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/core-saved-objects-base-server-mocks", + "id": "def-server.serializerMock.create", + "type": "Function", + "tags": [], + "label": "create", + "description": [], + "signature": [ + "() => jest.Mocked<", + "ISavedObjectsSerializer", + ">" + ], + "path": "packages/core/saved-objects/core-saved-objects-base-server-mocks/src/serializer.mock.ts", + "deprecated": false, + "returnComment": [], + "children": [] + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/core-saved-objects-base-server-mocks", + "id": "def-server.typeRegistryMock", + "type": "Object", + "tags": [], + "label": "typeRegistryMock", + "description": [], + "path": "packages/core/saved-objects/core-saved-objects-base-server-mocks/src/saved_objects_type_registry.mock.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/core-saved-objects-base-server-mocks", + "id": "def-server.typeRegistryMock.create", + "type": "Function", + "tags": [], + "label": "create", + "description": [], + "signature": [ + "() => jest.Mocked<", + "ISavedObjectTypeRegistry", + " & Pick<", + "SavedObjectTypeRegistry", + ", \"registerType\">>" + ], + "path": "packages/core/saved-objects/core-saved-objects-base-server-mocks/src/saved_objects_type_registry.mock.ts", + "deprecated": false, + "returnComment": [], + "children": [] + } + ], + "initialIsOpen": false + } + ] + }, + "common": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + } +} \ No newline at end of file diff --git a/api_docs/kbn_core_saved_objects_base_server_mocks.mdx b/api_docs/kbn_core_saved_objects_base_server_mocks.mdx new file mode 100644 index 00000000000000..bc2c33235e3110 --- /dev/null +++ b/api_docs/kbn_core_saved_objects_base_server_mocks.mdx @@ -0,0 +1,30 @@ +--- +#### +#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system. +#### Reach out in #docs-engineering for more info. +#### +id: kibKbnCoreSavedObjectsBaseServerMocksPluginApi +slug: /kibana-dev-docs/api/kbn-core-saved-objects-base-server-mocks +title: "@kbn/core-saved-objects-base-server-mocks" +image: https://source.unsplash.com/400x175/?github +description: API docs for the @kbn/core-saved-objects-base-server-mocks plugin +date: 2022-08-24 +tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-base-server-mocks'] +--- +import kbnCoreSavedObjectsBaseServerMocksObj from './kbn_core_saved_objects_base_server_mocks.devdocs.json'; + + + +Contact [Owner missing] for questions regarding this plugin. + +**Code health stats** + +| Public API count | Any count | Items lacking comments | Missing exports | +|-------------------|-----------|------------------------|-----------------| +| 4 | 0 | 4 | 0 | + +## Server + +### Objects + + diff --git a/api_docs/kbn_core_saved_objects_browser.mdx b/api_docs/kbn_core_saved_objects_browser.mdx index af23bb53bd90d0..c8a5933963b8cd 100644 --- a/api_docs/kbn_core_saved_objects_browser.mdx +++ b/api_docs/kbn_core_saved_objects_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-browser title: "@kbn/core-saved-objects-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-browser plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-browser'] --- import kbnCoreSavedObjectsBrowserObj from './kbn_core_saved_objects_browser.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_browser_internal.mdx b/api_docs/kbn_core_saved_objects_browser_internal.mdx index 6d406b1607e899..2ef0048b44fd66 100644 --- a/api_docs/kbn_core_saved_objects_browser_internal.mdx +++ b/api_docs/kbn_core_saved_objects_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-browser-internal title: "@kbn/core-saved-objects-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-browser-internal plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-browser-internal'] --- import kbnCoreSavedObjectsBrowserInternalObj from './kbn_core_saved_objects_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_browser_mocks.mdx b/api_docs/kbn_core_saved_objects_browser_mocks.mdx index deeb45c18a0154..c83067ee96d5e3 100644 --- a/api_docs/kbn_core_saved_objects_browser_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-browser-mocks title: "@kbn/core-saved-objects-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-browser-mocks plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-browser-mocks'] --- import kbnCoreSavedObjectsBrowserMocksObj from './kbn_core_saved_objects_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_common.mdx b/api_docs/kbn_core_saved_objects_common.mdx index 60570c982c73c5..29fe762ac86729 100644 --- a/api_docs/kbn_core_saved_objects_common.mdx +++ b/api_docs/kbn_core_saved_objects_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-common title: "@kbn/core-saved-objects-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-common plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-common'] --- import kbnCoreSavedObjectsCommonObj from './kbn_core_saved_objects_common.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_server.mdx b/api_docs/kbn_core_saved_objects_server.mdx index 9371a372e3760a..cfe16ff8e113e4 100644 --- a/api_docs/kbn_core_saved_objects_server.mdx +++ b/api_docs/kbn_core_saved_objects_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-server title: "@kbn/core-saved-objects-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-server plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-server'] --- import kbnCoreSavedObjectsServerObj from './kbn_core_saved_objects_server.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_utils_server.devdocs.json b/api_docs/kbn_core_saved_objects_utils_server.devdocs.json new file mode 100644 index 00000000000000..c8f93a8055235a --- /dev/null +++ b/api_docs/kbn_core_saved_objects_utils_server.devdocs.json @@ -0,0 +1,1836 @@ +{ + "id": "@kbn/core-saved-objects-utils-server", + "client": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "server": { + "classes": [ + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsErrorHelpers", + "type": "Class", + "tags": [], + "label": "SavedObjectsErrorHelpers", + "description": [], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsErrorHelpers.isSavedObjectsClientError", + "type": "Function", + "tags": [], + "label": "isSavedObjectsClientError", + "description": [], + "signature": [ + "(error: any) => error is ", + { + "pluginId": "@kbn/core-saved-objects-utils-server", + "scope": "server", + "docId": "kibKbnCoreSavedObjectsUtilsServerPluginApi", + "section": "def-server.DecoratedError", + "text": "DecoratedError" + } + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsErrorHelpers.isSavedObjectsClientError.$1", + "type": "Any", + "tags": [], + "label": "error", + "description": [], + "signature": [ + "any" + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsErrorHelpers.decorateBadRequestError", + "type": "Function", + "tags": [], + "label": "decorateBadRequestError", + "description": [], + "signature": [ + "(error: Error, reason?: string | undefined) => ", + { + "pluginId": "@kbn/core-saved-objects-utils-server", + "scope": "server", + "docId": "kibKbnCoreSavedObjectsUtilsServerPluginApi", + "section": "def-server.DecoratedError", + "text": "DecoratedError" + } + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsErrorHelpers.decorateBadRequestError.$1", + "type": "Object", + "tags": [], + "label": "error", + "description": [], + "signature": [ + "Error" + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsErrorHelpers.decorateBadRequestError.$2", + "type": "string", + "tags": [], + "label": "reason", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.ts", + "deprecated": false, + "isRequired": false + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsErrorHelpers.createBadRequestError", + "type": "Function", + "tags": [], + "label": "createBadRequestError", + "description": [], + "signature": [ + "(reason?: string | undefined) => ", + { + "pluginId": "@kbn/core-saved-objects-utils-server", + "scope": "server", + "docId": "kibKbnCoreSavedObjectsUtilsServerPluginApi", + "section": "def-server.DecoratedError", + "text": "DecoratedError" + } + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsErrorHelpers.createBadRequestError.$1", + "type": "string", + "tags": [], + "label": "reason", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.ts", + "deprecated": false, + "isRequired": false + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsErrorHelpers.createUnsupportedTypeError", + "type": "Function", + "tags": [], + "label": "createUnsupportedTypeError", + "description": [], + "signature": [ + "(type: string) => ", + { + "pluginId": "@kbn/core-saved-objects-utils-server", + "scope": "server", + "docId": "kibKbnCoreSavedObjectsUtilsServerPluginApi", + "section": "def-server.DecoratedError", + "text": "DecoratedError" + } + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsErrorHelpers.createUnsupportedTypeError.$1", + "type": "string", + "tags": [], + "label": "type", + "description": [], + "signature": [ + "string" + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsErrorHelpers.isBadRequestError", + "type": "Function", + "tags": [], + "label": "isBadRequestError", + "description": [], + "signature": [ + "(error: Error | ", + { + "pluginId": "@kbn/core-saved-objects-utils-server", + "scope": "server", + "docId": "kibKbnCoreSavedObjectsUtilsServerPluginApi", + "section": "def-server.DecoratedError", + "text": "DecoratedError" + }, + ") => boolean" + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsErrorHelpers.isBadRequestError.$1", + "type": "CompoundType", + "tags": [], + "label": "error", + "description": [], + "signature": [ + "Error | ", + { + "pluginId": "@kbn/core-saved-objects-utils-server", + "scope": "server", + "docId": "kibKbnCoreSavedObjectsUtilsServerPluginApi", + "section": "def-server.DecoratedError", + "text": "DecoratedError" + } + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsErrorHelpers.createInvalidVersionError", + "type": "Function", + "tags": [], + "label": "createInvalidVersionError", + "description": [], + "signature": [ + "(versionInput?: string | undefined) => ", + { + "pluginId": "@kbn/core-saved-objects-utils-server", + "scope": "server", + "docId": "kibKbnCoreSavedObjectsUtilsServerPluginApi", + "section": "def-server.DecoratedError", + "text": "DecoratedError" + } + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsErrorHelpers.createInvalidVersionError.$1", + "type": "string", + "tags": [], + "label": "versionInput", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.ts", + "deprecated": false, + "isRequired": false + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsErrorHelpers.isInvalidVersionError", + "type": "Function", + "tags": [], + "label": "isInvalidVersionError", + "description": [], + "signature": [ + "(error: Error | ", + { + "pluginId": "@kbn/core-saved-objects-utils-server", + "scope": "server", + "docId": "kibKbnCoreSavedObjectsUtilsServerPluginApi", + "section": "def-server.DecoratedError", + "text": "DecoratedError" + }, + ") => boolean" + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsErrorHelpers.isInvalidVersionError.$1", + "type": "CompoundType", + "tags": [], + "label": "error", + "description": [], + "signature": [ + "Error | ", + { + "pluginId": "@kbn/core-saved-objects-utils-server", + "scope": "server", + "docId": "kibKbnCoreSavedObjectsUtilsServerPluginApi", + "section": "def-server.DecoratedError", + "text": "DecoratedError" + } + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsErrorHelpers.decorateNotAuthorizedError", + "type": "Function", + "tags": [], + "label": "decorateNotAuthorizedError", + "description": [], + "signature": [ + "(error: Error, reason?: string | undefined) => ", + { + "pluginId": "@kbn/core-saved-objects-utils-server", + "scope": "server", + "docId": "kibKbnCoreSavedObjectsUtilsServerPluginApi", + "section": "def-server.DecoratedError", + "text": "DecoratedError" + } + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsErrorHelpers.decorateNotAuthorizedError.$1", + "type": "Object", + "tags": [], + "label": "error", + "description": [], + "signature": [ + "Error" + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsErrorHelpers.decorateNotAuthorizedError.$2", + "type": "string", + "tags": [], + "label": "reason", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.ts", + "deprecated": false, + "isRequired": false + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsErrorHelpers.isNotAuthorizedError", + "type": "Function", + "tags": [], + "label": "isNotAuthorizedError", + "description": [], + "signature": [ + "(error: Error | ", + { + "pluginId": "@kbn/core-saved-objects-utils-server", + "scope": "server", + "docId": "kibKbnCoreSavedObjectsUtilsServerPluginApi", + "section": "def-server.DecoratedError", + "text": "DecoratedError" + }, + ") => boolean" + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsErrorHelpers.isNotAuthorizedError.$1", + "type": "CompoundType", + "tags": [], + "label": "error", + "description": [], + "signature": [ + "Error | ", + { + "pluginId": "@kbn/core-saved-objects-utils-server", + "scope": "server", + "docId": "kibKbnCoreSavedObjectsUtilsServerPluginApi", + "section": "def-server.DecoratedError", + "text": "DecoratedError" + } + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsErrorHelpers.decorateForbiddenError", + "type": "Function", + "tags": [], + "label": "decorateForbiddenError", + "description": [], + "signature": [ + "(error: Error, reason?: string | undefined) => ", + { + "pluginId": "@kbn/core-saved-objects-utils-server", + "scope": "server", + "docId": "kibKbnCoreSavedObjectsUtilsServerPluginApi", + "section": "def-server.DecoratedError", + "text": "DecoratedError" + } + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsErrorHelpers.decorateForbiddenError.$1", + "type": "Object", + "tags": [], + "label": "error", + "description": [], + "signature": [ + "Error" + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsErrorHelpers.decorateForbiddenError.$2", + "type": "string", + "tags": [], + "label": "reason", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.ts", + "deprecated": false, + "isRequired": false + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsErrorHelpers.isForbiddenError", + "type": "Function", + "tags": [], + "label": "isForbiddenError", + "description": [], + "signature": [ + "(error: Error | ", + { + "pluginId": "@kbn/core-saved-objects-utils-server", + "scope": "server", + "docId": "kibKbnCoreSavedObjectsUtilsServerPluginApi", + "section": "def-server.DecoratedError", + "text": "DecoratedError" + }, + ") => boolean" + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsErrorHelpers.isForbiddenError.$1", + "type": "CompoundType", + "tags": [], + "label": "error", + "description": [], + "signature": [ + "Error | ", + { + "pluginId": "@kbn/core-saved-objects-utils-server", + "scope": "server", + "docId": "kibKbnCoreSavedObjectsUtilsServerPluginApi", + "section": "def-server.DecoratedError", + "text": "DecoratedError" + } + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsErrorHelpers.decorateRequestEntityTooLargeError", + "type": "Function", + "tags": [], + "label": "decorateRequestEntityTooLargeError", + "description": [], + "signature": [ + "(error: Error, reason?: string | undefined) => ", + { + "pluginId": "@kbn/core-saved-objects-utils-server", + "scope": "server", + "docId": "kibKbnCoreSavedObjectsUtilsServerPluginApi", + "section": "def-server.DecoratedError", + "text": "DecoratedError" + } + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsErrorHelpers.decorateRequestEntityTooLargeError.$1", + "type": "Object", + "tags": [], + "label": "error", + "description": [], + "signature": [ + "Error" + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsErrorHelpers.decorateRequestEntityTooLargeError.$2", + "type": "string", + "tags": [], + "label": "reason", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.ts", + "deprecated": false, + "isRequired": false + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsErrorHelpers.isRequestEntityTooLargeError", + "type": "Function", + "tags": [], + "label": "isRequestEntityTooLargeError", + "description": [], + "signature": [ + "(error: Error | ", + { + "pluginId": "@kbn/core-saved-objects-utils-server", + "scope": "server", + "docId": "kibKbnCoreSavedObjectsUtilsServerPluginApi", + "section": "def-server.DecoratedError", + "text": "DecoratedError" + }, + ") => boolean" + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsErrorHelpers.isRequestEntityTooLargeError.$1", + "type": "CompoundType", + "tags": [], + "label": "error", + "description": [], + "signature": [ + "Error | ", + { + "pluginId": "@kbn/core-saved-objects-utils-server", + "scope": "server", + "docId": "kibKbnCoreSavedObjectsUtilsServerPluginApi", + "section": "def-server.DecoratedError", + "text": "DecoratedError" + } + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsErrorHelpers.createGenericNotFoundError", + "type": "Function", + "tags": [], + "label": "createGenericNotFoundError", + "description": [], + "signature": [ + "(type?: string | null, id?: string | null) => ", + { + "pluginId": "@kbn/core-saved-objects-utils-server", + "scope": "server", + "docId": "kibKbnCoreSavedObjectsUtilsServerPluginApi", + "section": "def-server.DecoratedError", + "text": "DecoratedError" + } + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsErrorHelpers.createGenericNotFoundError.$1", + "type": "CompoundType", + "tags": [], + "label": "type", + "description": [], + "signature": [ + "string | null" + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.ts", + "deprecated": false, + "isRequired": false + }, + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsErrorHelpers.createGenericNotFoundError.$2", + "type": "CompoundType", + "tags": [], + "label": "id", + "description": [], + "signature": [ + "string | null" + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.ts", + "deprecated": false, + "isRequired": false + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsErrorHelpers.createIndexAliasNotFoundError", + "type": "Function", + "tags": [], + "label": "createIndexAliasNotFoundError", + "description": [], + "signature": [ + "(alias: string) => ", + { + "pluginId": "@kbn/core-saved-objects-utils-server", + "scope": "server", + "docId": "kibKbnCoreSavedObjectsUtilsServerPluginApi", + "section": "def-server.DecoratedError", + "text": "DecoratedError" + } + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsErrorHelpers.createIndexAliasNotFoundError.$1", + "type": "string", + "tags": [], + "label": "alias", + "description": [], + "signature": [ + "string" + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsErrorHelpers.decorateIndexAliasNotFoundError", + "type": "Function", + "tags": [], + "label": "decorateIndexAliasNotFoundError", + "description": [], + "signature": [ + "(error: Error, alias: string) => ", + { + "pluginId": "@kbn/core-saved-objects-utils-server", + "scope": "server", + "docId": "kibKbnCoreSavedObjectsUtilsServerPluginApi", + "section": "def-server.DecoratedError", + "text": "DecoratedError" + } + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsErrorHelpers.decorateIndexAliasNotFoundError.$1", + "type": "Object", + "tags": [], + "label": "error", + "description": [], + "signature": [ + "Error" + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsErrorHelpers.decorateIndexAliasNotFoundError.$2", + "type": "string", + "tags": [], + "label": "alias", + "description": [], + "signature": [ + "string" + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsErrorHelpers.isNotFoundError", + "type": "Function", + "tags": [], + "label": "isNotFoundError", + "description": [], + "signature": [ + "(error: Error | ", + { + "pluginId": "@kbn/core-saved-objects-utils-server", + "scope": "server", + "docId": "kibKbnCoreSavedObjectsUtilsServerPluginApi", + "section": "def-server.DecoratedError", + "text": "DecoratedError" + }, + ") => boolean" + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsErrorHelpers.isNotFoundError.$1", + "type": "CompoundType", + "tags": [], + "label": "error", + "description": [], + "signature": [ + "Error | ", + { + "pluginId": "@kbn/core-saved-objects-utils-server", + "scope": "server", + "docId": "kibKbnCoreSavedObjectsUtilsServerPluginApi", + "section": "def-server.DecoratedError", + "text": "DecoratedError" + } + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsErrorHelpers.decorateConflictError", + "type": "Function", + "tags": [], + "label": "decorateConflictError", + "description": [], + "signature": [ + "(error: Error, reason?: string | undefined) => ", + { + "pluginId": "@kbn/core-saved-objects-utils-server", + "scope": "server", + "docId": "kibKbnCoreSavedObjectsUtilsServerPluginApi", + "section": "def-server.DecoratedError", + "text": "DecoratedError" + } + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsErrorHelpers.decorateConflictError.$1", + "type": "Object", + "tags": [], + "label": "error", + "description": [], + "signature": [ + "Error" + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsErrorHelpers.decorateConflictError.$2", + "type": "string", + "tags": [], + "label": "reason", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.ts", + "deprecated": false, + "isRequired": false + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsErrorHelpers.createConflictError", + "type": "Function", + "tags": [], + "label": "createConflictError", + "description": [], + "signature": [ + "(type: string, id: string, reason?: string | undefined) => ", + { + "pluginId": "@kbn/core-saved-objects-utils-server", + "scope": "server", + "docId": "kibKbnCoreSavedObjectsUtilsServerPluginApi", + "section": "def-server.DecoratedError", + "text": "DecoratedError" + } + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsErrorHelpers.createConflictError.$1", + "type": "string", + "tags": [], + "label": "type", + "description": [], + "signature": [ + "string" + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsErrorHelpers.createConflictError.$2", + "type": "string", + "tags": [], + "label": "id", + "description": [], + "signature": [ + "string" + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsErrorHelpers.createConflictError.$3", + "type": "string", + "tags": [], + "label": "reason", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.ts", + "deprecated": false, + "isRequired": false + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsErrorHelpers.isConflictError", + "type": "Function", + "tags": [], + "label": "isConflictError", + "description": [], + "signature": [ + "(error: Error | ", + { + "pluginId": "@kbn/core-saved-objects-utils-server", + "scope": "server", + "docId": "kibKbnCoreSavedObjectsUtilsServerPluginApi", + "section": "def-server.DecoratedError", + "text": "DecoratedError" + }, + ") => boolean" + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsErrorHelpers.isConflictError.$1", + "type": "CompoundType", + "tags": [], + "label": "error", + "description": [], + "signature": [ + "Error | ", + { + "pluginId": "@kbn/core-saved-objects-utils-server", + "scope": "server", + "docId": "kibKbnCoreSavedObjectsUtilsServerPluginApi", + "section": "def-server.DecoratedError", + "text": "DecoratedError" + } + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsErrorHelpers.decorateTooManyRequestsError", + "type": "Function", + "tags": [], + "label": "decorateTooManyRequestsError", + "description": [], + "signature": [ + "(error: Error, reason?: string | undefined) => ", + { + "pluginId": "@kbn/core-saved-objects-utils-server", + "scope": "server", + "docId": "kibKbnCoreSavedObjectsUtilsServerPluginApi", + "section": "def-server.DecoratedError", + "text": "DecoratedError" + } + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsErrorHelpers.decorateTooManyRequestsError.$1", + "type": "Object", + "tags": [], + "label": "error", + "description": [], + "signature": [ + "Error" + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsErrorHelpers.decorateTooManyRequestsError.$2", + "type": "string", + "tags": [], + "label": "reason", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.ts", + "deprecated": false, + "isRequired": false + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsErrorHelpers.createTooManyRequestsError", + "type": "Function", + "tags": [], + "label": "createTooManyRequestsError", + "description": [], + "signature": [ + "(type: string, id: string) => ", + { + "pluginId": "@kbn/core-saved-objects-utils-server", + "scope": "server", + "docId": "kibKbnCoreSavedObjectsUtilsServerPluginApi", + "section": "def-server.DecoratedError", + "text": "DecoratedError" + } + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsErrorHelpers.createTooManyRequestsError.$1", + "type": "string", + "tags": [], + "label": "type", + "description": [], + "signature": [ + "string" + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsErrorHelpers.createTooManyRequestsError.$2", + "type": "string", + "tags": [], + "label": "id", + "description": [], + "signature": [ + "string" + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsErrorHelpers.isTooManyRequestsError", + "type": "Function", + "tags": [], + "label": "isTooManyRequestsError", + "description": [], + "signature": [ + "(error: Error | ", + { + "pluginId": "@kbn/core-saved-objects-utils-server", + "scope": "server", + "docId": "kibKbnCoreSavedObjectsUtilsServerPluginApi", + "section": "def-server.DecoratedError", + "text": "DecoratedError" + }, + ") => boolean" + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsErrorHelpers.isTooManyRequestsError.$1", + "type": "CompoundType", + "tags": [], + "label": "error", + "description": [], + "signature": [ + "Error | ", + { + "pluginId": "@kbn/core-saved-objects-utils-server", + "scope": "server", + "docId": "kibKbnCoreSavedObjectsUtilsServerPluginApi", + "section": "def-server.DecoratedError", + "text": "DecoratedError" + } + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsErrorHelpers.decorateEsCannotExecuteScriptError", + "type": "Function", + "tags": [], + "label": "decorateEsCannotExecuteScriptError", + "description": [], + "signature": [ + "(error: Error, reason?: string | undefined) => ", + { + "pluginId": "@kbn/core-saved-objects-utils-server", + "scope": "server", + "docId": "kibKbnCoreSavedObjectsUtilsServerPluginApi", + "section": "def-server.DecoratedError", + "text": "DecoratedError" + } + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsErrorHelpers.decorateEsCannotExecuteScriptError.$1", + "type": "Object", + "tags": [], + "label": "error", + "description": [], + "signature": [ + "Error" + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsErrorHelpers.decorateEsCannotExecuteScriptError.$2", + "type": "string", + "tags": [], + "label": "reason", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.ts", + "deprecated": false, + "isRequired": false + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsErrorHelpers.isEsCannotExecuteScriptError", + "type": "Function", + "tags": [], + "label": "isEsCannotExecuteScriptError", + "description": [], + "signature": [ + "(error: Error | ", + { + "pluginId": "@kbn/core-saved-objects-utils-server", + "scope": "server", + "docId": "kibKbnCoreSavedObjectsUtilsServerPluginApi", + "section": "def-server.DecoratedError", + "text": "DecoratedError" + }, + ") => boolean" + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsErrorHelpers.isEsCannotExecuteScriptError.$1", + "type": "CompoundType", + "tags": [], + "label": "error", + "description": [], + "signature": [ + "Error | ", + { + "pluginId": "@kbn/core-saved-objects-utils-server", + "scope": "server", + "docId": "kibKbnCoreSavedObjectsUtilsServerPluginApi", + "section": "def-server.DecoratedError", + "text": "DecoratedError" + } + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsErrorHelpers.decorateEsUnavailableError", + "type": "Function", + "tags": [], + "label": "decorateEsUnavailableError", + "description": [], + "signature": [ + "(error: Error, reason?: string | undefined) => ", + { + "pluginId": "@kbn/core-saved-objects-utils-server", + "scope": "server", + "docId": "kibKbnCoreSavedObjectsUtilsServerPluginApi", + "section": "def-server.DecoratedError", + "text": "DecoratedError" + } + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsErrorHelpers.decorateEsUnavailableError.$1", + "type": "Object", + "tags": [], + "label": "error", + "description": [], + "signature": [ + "Error" + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsErrorHelpers.decorateEsUnavailableError.$2", + "type": "string", + "tags": [], + "label": "reason", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.ts", + "deprecated": false, + "isRequired": false + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsErrorHelpers.isEsUnavailableError", + "type": "Function", + "tags": [], + "label": "isEsUnavailableError", + "description": [], + "signature": [ + "(error: Error | ", + { + "pluginId": "@kbn/core-saved-objects-utils-server", + "scope": "server", + "docId": "kibKbnCoreSavedObjectsUtilsServerPluginApi", + "section": "def-server.DecoratedError", + "text": "DecoratedError" + }, + ") => boolean" + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsErrorHelpers.isEsUnavailableError.$1", + "type": "CompoundType", + "tags": [], + "label": "error", + "description": [], + "signature": [ + "Error | ", + { + "pluginId": "@kbn/core-saved-objects-utils-server", + "scope": "server", + "docId": "kibKbnCoreSavedObjectsUtilsServerPluginApi", + "section": "def-server.DecoratedError", + "text": "DecoratedError" + } + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsErrorHelpers.decorateGeneralError", + "type": "Function", + "tags": [], + "label": "decorateGeneralError", + "description": [], + "signature": [ + "(error: Error, reason?: string | undefined) => ", + { + "pluginId": "@kbn/core-saved-objects-utils-server", + "scope": "server", + "docId": "kibKbnCoreSavedObjectsUtilsServerPluginApi", + "section": "def-server.DecoratedError", + "text": "DecoratedError" + } + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsErrorHelpers.decorateGeneralError.$1", + "type": "Object", + "tags": [], + "label": "error", + "description": [], + "signature": [ + "Error" + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsErrorHelpers.decorateGeneralError.$2", + "type": "string", + "tags": [], + "label": "reason", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.ts", + "deprecated": false, + "isRequired": false + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsErrorHelpers.isGeneralError", + "type": "Function", + "tags": [], + "label": "isGeneralError", + "description": [], + "signature": [ + "(error: Error | ", + { + "pluginId": "@kbn/core-saved-objects-utils-server", + "scope": "server", + "docId": "kibKbnCoreSavedObjectsUtilsServerPluginApi", + "section": "def-server.DecoratedError", + "text": "DecoratedError" + }, + ") => boolean" + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsErrorHelpers.isGeneralError.$1", + "type": "CompoundType", + "tags": [], + "label": "error", + "description": [], + "signature": [ + "Error | ", + { + "pluginId": "@kbn/core-saved-objects-utils-server", + "scope": "server", + "docId": "kibKbnCoreSavedObjectsUtilsServerPluginApi", + "section": "def-server.DecoratedError", + "text": "DecoratedError" + } + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsErrorHelpers.createGenericNotFoundEsUnavailableError", + "type": "Function", + "tags": [], + "label": "createGenericNotFoundEsUnavailableError", + "description": [], + "signature": [ + "(type?: string | null, id?: string | null) => ", + { + "pluginId": "@kbn/core-saved-objects-utils-server", + "scope": "server", + "docId": "kibKbnCoreSavedObjectsUtilsServerPluginApi", + "section": "def-server.DecoratedError", + "text": "DecoratedError" + } + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsErrorHelpers.createGenericNotFoundEsUnavailableError.$1", + "type": "CompoundType", + "tags": [], + "label": "type", + "description": [], + "signature": [ + "string | null" + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.ts", + "deprecated": false, + "isRequired": false + }, + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsErrorHelpers.createGenericNotFoundEsUnavailableError.$2", + "type": "CompoundType", + "tags": [], + "label": "id", + "description": [], + "signature": [ + "string | null" + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.ts", + "deprecated": false, + "isRequired": false + } + ], + "returnComment": [] + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsUtils", + "type": "Class", + "tags": [], + "label": "SavedObjectsUtils", + "description": [], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_utils.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsUtils.namespaceIdToString", + "type": "Function", + "tags": [], + "label": "namespaceIdToString", + "description": [ + "\nConverts a given saved object namespace ID to its string representation. All namespace IDs have an identical string representation, with\nthe exception of the `undefined` namespace ID (which has a namespace string of `'default'`).\n" + ], + "signature": [ + "(namespace?: string | undefined) => string" + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_utils.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsUtils.namespaceIdToString.$1", + "type": "string", + "tags": [], + "label": "namespace", + "description": [ + "The namespace ID, which must be either a non-empty string or `undefined`." + ], + "signature": [ + "string | undefined" + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_utils.ts", + "deprecated": false, + "isRequired": false + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsUtils.namespaceStringToId", + "type": "Function", + "tags": [], + "label": "namespaceStringToId", + "description": [ + "\nConverts a given saved object namespace string to its ID representation. All namespace strings have an identical ID representation, with\nthe exception of the `'default'` namespace string (which has a namespace ID of `undefined`).\n" + ], + "signature": [ + "(namespace: string) => string | undefined" + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_utils.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsUtils.namespaceStringToId.$1", + "type": "string", + "tags": [], + "label": "namespace", + "description": [ + "The namespace string, which must be non-empty." + ], + "signature": [ + "string" + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_utils.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsUtils.createEmptyFindResponse", + "type": "Function", + "tags": [], + "label": "createEmptyFindResponse", + "description": [ + "\nCreates an empty response for a find operation. This is only intended to be used by saved objects client wrappers." + ], + "signature": [ + "({ page, perPage, }: ", + "SavedObjectsFindOptions", + ") => ", + "SavedObjectsFindResponse", + "" + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_utils.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsUtils.createEmptyFindResponse.$1", + "type": "Object", + "tags": [], + "label": "{\n page = FIND_DEFAULT_PAGE,\n perPage = FIND_DEFAULT_PER_PAGE,\n }", + "description": [], + "signature": [ + "SavedObjectsFindOptions" + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_utils.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsUtils.generateId", + "type": "Function", + "tags": [], + "label": "generateId", + "description": [ + "\nGenerates a random ID for a saved objects." + ], + "signature": [ + "() => string" + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_utils.ts", + "deprecated": false, + "children": [], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsUtils.isRandomId", + "type": "Function", + "tags": [ + "todo" + ], + "label": "isRandomId", + "description": [ + "\nValidates that a saved object ID has been randomly generated.\n" + ], + "signature": [ + "(id: string | undefined) => boolean" + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_utils.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsUtils.isRandomId.$1", + "type": "string", + "tags": [], + "label": "id", + "description": [ + "The ID of a saved object." + ], + "signature": [ + "string | undefined" + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_utils.ts", + "deprecated": false, + "isRequired": false + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsUtils.getConvertedObjectId", + "type": "Function", + "tags": [], + "label": "getConvertedObjectId", + "description": [ + "\nUses a single-namespace object's \"legacy ID\" to determine what its new ID will be after it is converted to a multi-namespace type.\n" + ], + "signature": [ + "(namespace: string | undefined, type: string, id: string) => string" + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_utils.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsUtils.getConvertedObjectId.$1", + "type": "string", + "tags": [], + "label": "namespace", + "description": [ + "The namespace of the saved object before it is converted." + ], + "signature": [ + "string | undefined" + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_utils.ts", + "deprecated": false, + "isRequired": false + }, + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsUtils.getConvertedObjectId.$2", + "type": "string", + "tags": [], + "label": "type", + "description": [ + "The type of the saved object before it is converted." + ], + "signature": [ + "string" + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_utils.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.SavedObjectsUtils.getConvertedObjectId.$3", + "type": "string", + "tags": [], + "label": "id", + "description": [ + "The ID of the saved object before it is converted." + ], + "signature": [ + "string" + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_utils.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [ + "The ID of the saved object after it is converted." + ] + } + ], + "initialIsOpen": false + } + ], + "functions": [ + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.mergeSavedObjectMigrationMaps", + "type": "Function", + "tags": [], + "label": "mergeSavedObjectMigrationMaps", + "description": [ + "\nMerges two saved object migration maps.\n\nIf there is a migration for a given version on only one of the maps,\nthat migration function will be used:\n\nmergeSavedObjectMigrationMaps({ '1.2.3': f }, { '4.5.6': g }) -> { '1.2.3': f, '4.5.6': g }\n\nIf there is a migration for a given version on both maps, the migrations will be composed:\n\nmergeSavedObjectMigrationMaps({ '1.2.3': f }, { '1.2.3': g }) -> { '1.2.3': (doc, context) => f(g(doc, context), context) }\n" + ], + "signature": [ + "(map1: ", + "SavedObjectMigrationMap", + ", map2: ", + "SavedObjectMigrationMap", + ") => ", + "SavedObjectMigrationMap" + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/merge_migration_maps.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.mergeSavedObjectMigrationMaps.$1", + "type": "Object", + "tags": [], + "label": "map1", + "description": [], + "signature": [ + "SavedObjectMigrationMap" + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/merge_migration_maps.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.mergeSavedObjectMigrationMaps.$2", + "type": "Object", + "tags": [], + "label": "map2", + "description": [], + "signature": [ + "SavedObjectMigrationMap" + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/merge_migration_maps.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + } + ], + "interfaces": [ + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.DecoratedError", + "type": "Interface", + "tags": [], + "label": "DecoratedError", + "description": [], + "signature": [ + { + "pluginId": "@kbn/core-saved-objects-utils-server", + "scope": "server", + "docId": "kibKbnCoreSavedObjectsUtilsServerPluginApi", + "section": "def-server.DecoratedError", + "text": "DecoratedError" + }, + " extends ", + "Boom", + "" + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.DecoratedError.code", + "type": "string", + "tags": [], + "label": "[code]", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.ts", + "deprecated": false + } + ], + "initialIsOpen": false + } + ], + "enums": [], + "misc": [ + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.ALL_NAMESPACES_STRING", + "type": "string", + "tags": [], + "label": "ALL_NAMESPACES_STRING", + "description": [], + "signature": [ + "\"*\"" + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_utils.ts", + "deprecated": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.DEFAULT_NAMESPACE_STRING", + "type": "string", + "tags": [], + "label": "DEFAULT_NAMESPACE_STRING", + "description": [], + "signature": [ + "\"default\"" + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_utils.ts", + "deprecated": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.FIND_DEFAULT_PAGE", + "type": "number", + "tags": [], + "label": "FIND_DEFAULT_PAGE", + "description": [], + "signature": [ + "1" + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_utils.ts", + "deprecated": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/core-saved-objects-utils-server", + "id": "def-server.FIND_DEFAULT_PER_PAGE", + "type": "number", + "tags": [], + "label": "FIND_DEFAULT_PER_PAGE", + "description": [], + "signature": [ + "20" + ], + "path": "packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_utils.ts", + "deprecated": false, + "initialIsOpen": false + } + ], + "objects": [] + }, + "common": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + } +} \ No newline at end of file diff --git a/api_docs/kbn_core_saved_objects_utils_server.mdx b/api_docs/kbn_core_saved_objects_utils_server.mdx new file mode 100644 index 00000000000000..0839f87a4f322d --- /dev/null +++ b/api_docs/kbn_core_saved_objects_utils_server.mdx @@ -0,0 +1,39 @@ +--- +#### +#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system. +#### Reach out in #docs-engineering for more info. +#### +id: kibKbnCoreSavedObjectsUtilsServerPluginApi +slug: /kibana-dev-docs/api/kbn-core-saved-objects-utils-server +title: "@kbn/core-saved-objects-utils-server" +image: https://source.unsplash.com/400x175/?github +description: API docs for the @kbn/core-saved-objects-utils-server plugin +date: 2022-08-24 +tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-utils-server'] +--- +import kbnCoreSavedObjectsUtilsServerObj from './kbn_core_saved_objects_utils_server.devdocs.json'; + + + +Contact [Owner missing] for questions regarding this plugin. + +**Code health stats** + +| Public API count | Any count | Items lacking comments | Missing exports | +|-------------------|-----------|------------------------|-----------------| +| 99 | 1 | 86 | 0 | + +## Server + +### Functions + + +### Classes + + +### Interfaces + + +### Consts, variables and types + + diff --git a/api_docs/kbn_core_test_helpers_deprecations_getters.mdx b/api_docs/kbn_core_test_helpers_deprecations_getters.mdx index 1ebc6e6fee9b25..dc6057e28b79d6 100644 --- a/api_docs/kbn_core_test_helpers_deprecations_getters.mdx +++ b/api_docs/kbn_core_test_helpers_deprecations_getters.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-deprecations-getters title: "@kbn/core-test-helpers-deprecations-getters" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-deprecations-getters plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-test-helpers-deprecations-getters'] --- import kbnCoreTestHelpersDeprecationsGettersObj from './kbn_core_test_helpers_deprecations_getters.devdocs.json'; diff --git a/api_docs/kbn_core_test_helpers_http_setup_browser.mdx b/api_docs/kbn_core_test_helpers_http_setup_browser.mdx index 18e87ee0aad4fb..7fdbcb3ee63027 100644 --- a/api_docs/kbn_core_test_helpers_http_setup_browser.mdx +++ b/api_docs/kbn_core_test_helpers_http_setup_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-http-setup-browser title: "@kbn/core-test-helpers-http-setup-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-http-setup-browser plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-test-helpers-http-setup-browser'] --- import kbnCoreTestHelpersHttpSetupBrowserObj from './kbn_core_test_helpers_http_setup_browser.devdocs.json'; diff --git a/api_docs/kbn_core_theme_browser.mdx b/api_docs/kbn_core_theme_browser.mdx index 28028a70a94e6c..6af996a336d15d 100644 --- a/api_docs/kbn_core_theme_browser.mdx +++ b/api_docs/kbn_core_theme_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-theme-browser title: "@kbn/core-theme-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-theme-browser plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-theme-browser'] --- import kbnCoreThemeBrowserObj from './kbn_core_theme_browser.devdocs.json'; diff --git a/api_docs/kbn_core_theme_browser_internal.mdx b/api_docs/kbn_core_theme_browser_internal.mdx index 2d38df8122e8a0..d01bd931850e0e 100644 --- a/api_docs/kbn_core_theme_browser_internal.mdx +++ b/api_docs/kbn_core_theme_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-theme-browser-internal title: "@kbn/core-theme-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-theme-browser-internal plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-theme-browser-internal'] --- import kbnCoreThemeBrowserInternalObj from './kbn_core_theme_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_theme_browser_mocks.mdx b/api_docs/kbn_core_theme_browser_mocks.mdx index d253dd0bbe1e8e..893e47dea02f97 100644 --- a/api_docs/kbn_core_theme_browser_mocks.mdx +++ b/api_docs/kbn_core_theme_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-theme-browser-mocks title: "@kbn/core-theme-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-theme-browser-mocks plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-theme-browser-mocks'] --- import kbnCoreThemeBrowserMocksObj from './kbn_core_theme_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_browser.mdx b/api_docs/kbn_core_ui_settings_browser.mdx index dd271499137b04..6ec17cc36607bd 100644 --- a/api_docs/kbn_core_ui_settings_browser.mdx +++ b/api_docs/kbn_core_ui_settings_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-browser title: "@kbn/core-ui-settings-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-browser plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-browser'] --- import kbnCoreUiSettingsBrowserObj from './kbn_core_ui_settings_browser.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_browser_internal.mdx b/api_docs/kbn_core_ui_settings_browser_internal.mdx index 2902ebfc11be78..36f8e85eaa7129 100644 --- a/api_docs/kbn_core_ui_settings_browser_internal.mdx +++ b/api_docs/kbn_core_ui_settings_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-browser-internal title: "@kbn/core-ui-settings-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-browser-internal plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-browser-internal'] --- import kbnCoreUiSettingsBrowserInternalObj from './kbn_core_ui_settings_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_browser_mocks.mdx b/api_docs/kbn_core_ui_settings_browser_mocks.mdx index 124a9bc7f4122a..bb5bdca4f5ae4c 100644 --- a/api_docs/kbn_core_ui_settings_browser_mocks.mdx +++ b/api_docs/kbn_core_ui_settings_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-browser-mocks title: "@kbn/core-ui-settings-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-browser-mocks plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-browser-mocks'] --- import kbnCoreUiSettingsBrowserMocksObj from './kbn_core_ui_settings_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_common.devdocs.json b/api_docs/kbn_core_ui_settings_common.devdocs.json index 79bf435bbcb51f..f74eb886117214 100644 --- a/api_docs/kbn_core_ui_settings_common.devdocs.json +++ b/api_docs/kbn_core_ui_settings_common.devdocs.json @@ -382,7 +382,7 @@ "section": "def-common.UiSettingsType", "text": "UiSettingsType" }, - " | undefined; metric?: { type: string; name: string; } | undefined; name?: string | undefined; order?: number | undefined; value?: unknown; description?: string | undefined; category?: string[] | undefined; optionLabels?: Record | undefined; requiresPageReload?: boolean | undefined; readonly?: boolean | undefined; sensitive?: boolean | undefined; deprecation?: ", + " | undefined; metric?: { type: string; name: string; } | undefined; value?: unknown; description?: string | undefined; name?: string | undefined; order?: number | undefined; category?: string[] | undefined; optionLabels?: Record | undefined; requiresPageReload?: boolean | undefined; readonly?: boolean | undefined; sensitive?: boolean | undefined; deprecation?: ", { "pluginId": "@kbn/core-ui-settings-common", "scope": "common", diff --git a/api_docs/kbn_core_ui_settings_common.mdx b/api_docs/kbn_core_ui_settings_common.mdx index 72c7def97d3aff..17cfdb7f365390 100644 --- a/api_docs/kbn_core_ui_settings_common.mdx +++ b/api_docs/kbn_core_ui_settings_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-common title: "@kbn/core-ui-settings-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-common plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-common'] --- import kbnCoreUiSettingsCommonObj from './kbn_core_ui_settings_common.devdocs.json'; diff --git a/api_docs/kbn_crypto.mdx b/api_docs/kbn_crypto.mdx index 85e3f03c796583..54a9c499aa78a2 100644 --- a/api_docs/kbn_crypto.mdx +++ b/api_docs/kbn_crypto.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-crypto title: "@kbn/crypto" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/crypto plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/crypto'] --- import kbnCryptoObj from './kbn_crypto.devdocs.json'; diff --git a/api_docs/kbn_crypto_browser.mdx b/api_docs/kbn_crypto_browser.mdx index 5db1b7ba0335a0..38a22196f9edae 100644 --- a/api_docs/kbn_crypto_browser.mdx +++ b/api_docs/kbn_crypto_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-crypto-browser title: "@kbn/crypto-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/crypto-browser plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/crypto-browser'] --- import kbnCryptoBrowserObj from './kbn_crypto_browser.devdocs.json'; diff --git a/api_docs/kbn_datemath.devdocs.json b/api_docs/kbn_datemath.devdocs.json index fc0a5027ecb5ba..d3d0d4282c0537 100644 --- a/api_docs/kbn_datemath.devdocs.json +++ b/api_docs/kbn_datemath.devdocs.json @@ -105,7 +105,7 @@ "label": "Unit", "description": [], "signature": [ - "\"d\" | \"y\" | \"s\" | \"m\" | \"M\" | \"w\" | \"h\" | \"ms\"" + "\"y\" | \"M\" | \"w\" | \"d\" | \"h\" | \"m\" | \"s\" | \"ms\"" ], "path": "packages/kbn-datemath/src/index.ts", "deprecated": false, @@ -182,7 +182,7 @@ "label": "UnitsMap", "description": [], "signature": [ - "{ d: { weight: number; type: \"fixed\" | \"mixed\" | \"calendar\"; base: number; }; y: { weight: number; type: \"fixed\" | \"mixed\" | \"calendar\"; base: number; }; s: { weight: number; type: \"fixed\" | \"mixed\" | \"calendar\"; base: number; }; m: { weight: number; type: \"fixed\" | \"mixed\" | \"calendar\"; base: number; }; M: { weight: number; type: \"fixed\" | \"mixed\" | \"calendar\"; base: number; }; w: { weight: number; type: \"fixed\" | \"mixed\" | \"calendar\"; base: number; }; h: { weight: number; type: \"fixed\" | \"mixed\" | \"calendar\"; base: number; }; ms: { weight: number; type: \"fixed\" | \"mixed\" | \"calendar\"; base: number; }; }" + "{ y: { weight: number; type: \"fixed\" | \"calendar\" | \"mixed\"; base: number; }; M: { weight: number; type: \"fixed\" | \"calendar\" | \"mixed\"; base: number; }; w: { weight: number; type: \"fixed\" | \"calendar\" | \"mixed\"; base: number; }; d: { weight: number; type: \"fixed\" | \"calendar\" | \"mixed\"; base: number; }; h: { weight: number; type: \"fixed\" | \"calendar\" | \"mixed\"; base: number; }; m: { weight: number; type: \"fixed\" | \"calendar\" | \"mixed\"; base: number; }; s: { weight: number; type: \"fixed\" | \"calendar\" | \"mixed\"; base: number; }; ms: { weight: number; type: \"fixed\" | \"calendar\" | \"mixed\"; base: number; }; }" ], "path": "packages/kbn-datemath/src/index.ts", "deprecated": false, diff --git a/api_docs/kbn_datemath.mdx b/api_docs/kbn_datemath.mdx index 94624e8ebd6dab..0f97ca0b11aad2 100644 --- a/api_docs/kbn_datemath.mdx +++ b/api_docs/kbn_datemath.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-datemath title: "@kbn/datemath" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/datemath plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/datemath'] --- import kbnDatemathObj from './kbn_datemath.devdocs.json'; diff --git a/api_docs/kbn_dev_cli_errors.mdx b/api_docs/kbn_dev_cli_errors.mdx index 252779b3639834..65f3c36fc10660 100644 --- a/api_docs/kbn_dev_cli_errors.mdx +++ b/api_docs/kbn_dev_cli_errors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-cli-errors title: "@kbn/dev-cli-errors" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-cli-errors plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dev-cli-errors'] --- import kbnDevCliErrorsObj from './kbn_dev_cli_errors.devdocs.json'; diff --git a/api_docs/kbn_dev_cli_runner.mdx b/api_docs/kbn_dev_cli_runner.mdx index 3601130105cafe..e4db20765cfe3a 100644 --- a/api_docs/kbn_dev_cli_runner.mdx +++ b/api_docs/kbn_dev_cli_runner.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-cli-runner title: "@kbn/dev-cli-runner" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-cli-runner plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dev-cli-runner'] --- import kbnDevCliRunnerObj from './kbn_dev_cli_runner.devdocs.json'; diff --git a/api_docs/kbn_dev_proc_runner.mdx b/api_docs/kbn_dev_proc_runner.mdx index 64385be6fc5fc9..653b2d3f4aa852 100644 --- a/api_docs/kbn_dev_proc_runner.mdx +++ b/api_docs/kbn_dev_proc_runner.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-proc-runner title: "@kbn/dev-proc-runner" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-proc-runner plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dev-proc-runner'] --- import kbnDevProcRunnerObj from './kbn_dev_proc_runner.devdocs.json'; diff --git a/api_docs/kbn_dev_utils.mdx b/api_docs/kbn_dev_utils.mdx index 7b783cb34c5875..0608a26812d0c4 100644 --- a/api_docs/kbn_dev_utils.mdx +++ b/api_docs/kbn_dev_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-utils title: "@kbn/dev-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-utils plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dev-utils'] --- import kbnDevUtilsObj from './kbn_dev_utils.devdocs.json'; diff --git a/api_docs/kbn_doc_links.mdx b/api_docs/kbn_doc_links.mdx index 591cff6c297735..2f47798cde225e 100644 --- a/api_docs/kbn_doc_links.mdx +++ b/api_docs/kbn_doc_links.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-doc-links title: "@kbn/doc-links" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/doc-links plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/doc-links'] --- import kbnDocLinksObj from './kbn_doc_links.devdocs.json'; diff --git a/api_docs/kbn_docs_utils.mdx b/api_docs/kbn_docs_utils.mdx index f7f8fb43765935..8471893fb4de87 100644 --- a/api_docs/kbn_docs_utils.mdx +++ b/api_docs/kbn_docs_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-docs-utils title: "@kbn/docs-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/docs-utils plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/docs-utils'] --- import kbnDocsUtilsObj from './kbn_docs_utils.devdocs.json'; diff --git a/api_docs/kbn_ebt_tools.mdx b/api_docs/kbn_ebt_tools.mdx index 63174ebea86e8c..6cc5e6aaa74b34 100644 --- a/api_docs/kbn_ebt_tools.mdx +++ b/api_docs/kbn_ebt_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ebt-tools title: "@kbn/ebt-tools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ebt-tools plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ebt-tools'] --- import kbnEbtToolsObj from './kbn_ebt_tools.devdocs.json'; diff --git a/api_docs/kbn_es_archiver.mdx b/api_docs/kbn_es_archiver.mdx index e7969de5914ce6..73c7a493f5719d 100644 --- a/api_docs/kbn_es_archiver.mdx +++ b/api_docs/kbn_es_archiver.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-archiver title: "@kbn/es-archiver" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-archiver plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es-archiver'] --- import kbnEsArchiverObj from './kbn_es_archiver.devdocs.json'; diff --git a/api_docs/kbn_es_errors.mdx b/api_docs/kbn_es_errors.mdx index 974b8007014e87..018363a6eb40f8 100644 --- a/api_docs/kbn_es_errors.mdx +++ b/api_docs/kbn_es_errors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-errors title: "@kbn/es-errors" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-errors plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es-errors'] --- import kbnEsErrorsObj from './kbn_es_errors.devdocs.json'; diff --git a/api_docs/kbn_es_query.mdx b/api_docs/kbn_es_query.mdx index bcada9b1af6a3c..9399b6019c28dc 100644 --- a/api_docs/kbn_es_query.mdx +++ b/api_docs/kbn_es_query.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-query title: "@kbn/es-query" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-query plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es-query'] --- import kbnEsQueryObj from './kbn_es_query.devdocs.json'; diff --git a/api_docs/kbn_eslint_plugin_imports.mdx b/api_docs/kbn_eslint_plugin_imports.mdx index 7e5397de981b2f..da936edfa1bf41 100644 --- a/api_docs/kbn_eslint_plugin_imports.mdx +++ b/api_docs/kbn_eslint_plugin_imports.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-eslint-plugin-imports title: "@kbn/eslint-plugin-imports" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/eslint-plugin-imports plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/eslint-plugin-imports'] --- import kbnEslintPluginImportsObj from './kbn_eslint_plugin_imports.devdocs.json'; diff --git a/api_docs/kbn_field_types.mdx b/api_docs/kbn_field_types.mdx index 4f627c855720c3..4f1237760cdd42 100644 --- a/api_docs/kbn_field_types.mdx +++ b/api_docs/kbn_field_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-field-types title: "@kbn/field-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/field-types plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/field-types'] --- import kbnFieldTypesObj from './kbn_field_types.devdocs.json'; diff --git a/api_docs/kbn_find_used_node_modules.mdx b/api_docs/kbn_find_used_node_modules.mdx index eb10c3549b8bee..82ba9c6b973458 100644 --- a/api_docs/kbn_find_used_node_modules.mdx +++ b/api_docs/kbn_find_used_node_modules.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-find-used-node-modules title: "@kbn/find-used-node-modules" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/find-used-node-modules plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/find-used-node-modules'] --- import kbnFindUsedNodeModulesObj from './kbn_find_used_node_modules.devdocs.json'; diff --git a/api_docs/kbn_generate.mdx b/api_docs/kbn_generate.mdx index 7126946a67fcb5..a01c65f660eb3b 100644 --- a/api_docs/kbn_generate.mdx +++ b/api_docs/kbn_generate.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-generate title: "@kbn/generate" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/generate plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/generate'] --- import kbnGenerateObj from './kbn_generate.devdocs.json'; diff --git a/api_docs/kbn_get_repo_files.mdx b/api_docs/kbn_get_repo_files.mdx index 94aa961b03673b..932f9e78d33e35 100644 --- a/api_docs/kbn_get_repo_files.mdx +++ b/api_docs/kbn_get_repo_files.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-get-repo-files title: "@kbn/get-repo-files" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/get-repo-files plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/get-repo-files'] --- import kbnGetRepoFilesObj from './kbn_get_repo_files.devdocs.json'; diff --git a/api_docs/kbn_handlebars.mdx b/api_docs/kbn_handlebars.mdx index 672f139d60e299..0a4c9157c2ac69 100644 --- a/api_docs/kbn_handlebars.mdx +++ b/api_docs/kbn_handlebars.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-handlebars title: "@kbn/handlebars" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/handlebars plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/handlebars'] --- import kbnHandlebarsObj from './kbn_handlebars.devdocs.json'; diff --git a/api_docs/kbn_hapi_mocks.mdx b/api_docs/kbn_hapi_mocks.mdx index 3bc062b83a7304..1e7e8445c12124 100644 --- a/api_docs/kbn_hapi_mocks.mdx +++ b/api_docs/kbn_hapi_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-hapi-mocks title: "@kbn/hapi-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/hapi-mocks plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/hapi-mocks'] --- import kbnHapiMocksObj from './kbn_hapi_mocks.devdocs.json'; diff --git a/api_docs/kbn_home_sample_data_card.devdocs.json b/api_docs/kbn_home_sample_data_card.devdocs.json index 4297b7ded9eb51..1806b7c0a813f1 100644 --- a/api_docs/kbn_home_sample_data_card.devdocs.json +++ b/api_docs/kbn_home_sample_data_card.devdocs.json @@ -602,7 +602,7 @@ "\nParameters drawn from the Storybook arguments collection that customize a component story." ], "signature": [ - "{ status: any; name: any; description: any; includeAppLinks: any; simulateErrors: any; }" + "{ status: any; description: any; name: any; includeAppLinks: any; simulateErrors: any; }" ], "path": "packages/home/sample_data_card/src/mocks/index.ts", "deprecated": false, diff --git a/api_docs/kbn_home_sample_data_card.mdx b/api_docs/kbn_home_sample_data_card.mdx index 9c9cbe692ba0f5..ebdaa5dca1029c 100644 --- a/api_docs/kbn_home_sample_data_card.mdx +++ b/api_docs/kbn_home_sample_data_card.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-home-sample-data-card title: "@kbn/home-sample-data-card" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/home-sample-data-card plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/home-sample-data-card'] --- import kbnHomeSampleDataCardObj from './kbn_home_sample_data_card.devdocs.json'; diff --git a/api_docs/kbn_home_sample_data_tab.mdx b/api_docs/kbn_home_sample_data_tab.mdx index ec2cebbc6e17c3..9a5a4b18df4485 100644 --- a/api_docs/kbn_home_sample_data_tab.mdx +++ b/api_docs/kbn_home_sample_data_tab.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-home-sample-data-tab title: "@kbn/home-sample-data-tab" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/home-sample-data-tab plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/home-sample-data-tab'] --- import kbnHomeSampleDataTabObj from './kbn_home_sample_data_tab.devdocs.json'; diff --git a/api_docs/kbn_i18n.mdx b/api_docs/kbn_i18n.mdx index aabf627c9ab829..d75a40c2c12454 100644 --- a/api_docs/kbn_i18n.mdx +++ b/api_docs/kbn_i18n.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-i18n title: "@kbn/i18n" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/i18n plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/i18n'] --- import kbnI18nObj from './kbn_i18n.devdocs.json'; diff --git a/api_docs/kbn_import_resolver.mdx b/api_docs/kbn_import_resolver.mdx index 3a3505e167865d..d9115627c0b53e 100644 --- a/api_docs/kbn_import_resolver.mdx +++ b/api_docs/kbn_import_resolver.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-import-resolver title: "@kbn/import-resolver" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/import-resolver plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/import-resolver'] --- import kbnImportResolverObj from './kbn_import_resolver.devdocs.json'; diff --git a/api_docs/kbn_interpreter.mdx b/api_docs/kbn_interpreter.mdx index de0ec872e491ed..0ac3998ea25479 100644 --- a/api_docs/kbn_interpreter.mdx +++ b/api_docs/kbn_interpreter.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-interpreter title: "@kbn/interpreter" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/interpreter plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/interpreter'] --- import kbnInterpreterObj from './kbn_interpreter.devdocs.json'; diff --git a/api_docs/kbn_io_ts_utils.mdx b/api_docs/kbn_io_ts_utils.mdx index 36b3e9e3604024..d06e5e5f136f75 100644 --- a/api_docs/kbn_io_ts_utils.mdx +++ b/api_docs/kbn_io_ts_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-io-ts-utils title: "@kbn/io-ts-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/io-ts-utils plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/io-ts-utils'] --- import kbnIoTsUtilsObj from './kbn_io_ts_utils.devdocs.json'; diff --git a/api_docs/kbn_jest_serializers.mdx b/api_docs/kbn_jest_serializers.mdx index ca7f65953b8516..c3156b4041b0cd 100644 --- a/api_docs/kbn_jest_serializers.mdx +++ b/api_docs/kbn_jest_serializers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-jest-serializers title: "@kbn/jest-serializers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/jest-serializers plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/jest-serializers'] --- import kbnJestSerializersObj from './kbn_jest_serializers.devdocs.json'; diff --git a/api_docs/kbn_kibana_manifest_parser.mdx b/api_docs/kbn_kibana_manifest_parser.mdx index ffb402de4394c6..2b7b1cf5521152 100644 --- a/api_docs/kbn_kibana_manifest_parser.mdx +++ b/api_docs/kbn_kibana_manifest_parser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-kibana-manifest-parser title: "@kbn/kibana-manifest-parser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/kibana-manifest-parser plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/kibana-manifest-parser'] --- import kbnKibanaManifestParserObj from './kbn_kibana_manifest_parser.devdocs.json'; diff --git a/api_docs/kbn_kibana_manifest_schema.mdx b/api_docs/kbn_kibana_manifest_schema.mdx index 693e2926796271..5b4775a04a25c4 100644 --- a/api_docs/kbn_kibana_manifest_schema.mdx +++ b/api_docs/kbn_kibana_manifest_schema.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-kibana-manifest-schema title: "@kbn/kibana-manifest-schema" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/kibana-manifest-schema plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/kibana-manifest-schema'] --- import kbnKibanaManifestSchemaObj from './kbn_kibana_manifest_schema.devdocs.json'; diff --git a/api_docs/kbn_logging.devdocs.json b/api_docs/kbn_logging.devdocs.json index fbd76bba91bab8..33bcbcb329f082 100644 --- a/api_docs/kbn_logging.devdocs.json +++ b/api_docs/kbn_logging.devdocs.json @@ -660,7 +660,7 @@ "label": "EcsEventType", "description": [], "signature": [ - "\"start\" | \"error\" | \"connection\" | \"end\" | \"group\" | \"user\" | \"info\" | \"admin\" | \"protocol\" | \"access\" | \"allowed\" | \"change\" | \"creation\" | \"deletion\" | \"denied\" | \"installation\"" + "\"start\" | \"error\" | \"connection\" | \"user\" | \"info\" | \"group\" | \"end\" | \"admin\" | \"protocol\" | \"access\" | \"allowed\" | \"change\" | \"creation\" | \"deletion\" | \"denied\" | \"installation\"" ], "path": "packages/kbn-logging/src/ecs/event.ts", "deprecated": false, diff --git a/api_docs/kbn_logging.mdx b/api_docs/kbn_logging.mdx index 520142343ce121..a59fb7f6bfab98 100644 --- a/api_docs/kbn_logging.mdx +++ b/api_docs/kbn_logging.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-logging title: "@kbn/logging" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/logging plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/logging'] --- import kbnLoggingObj from './kbn_logging.devdocs.json'; diff --git a/api_docs/kbn_logging_mocks.mdx b/api_docs/kbn_logging_mocks.mdx index 8476efa285738a..c27c67df0498fe 100644 --- a/api_docs/kbn_logging_mocks.mdx +++ b/api_docs/kbn_logging_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-logging-mocks title: "@kbn/logging-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/logging-mocks plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/logging-mocks'] --- import kbnLoggingMocksObj from './kbn_logging_mocks.devdocs.json'; diff --git a/api_docs/kbn_managed_vscode_config.mdx b/api_docs/kbn_managed_vscode_config.mdx index 4f98d82bf814ab..29abb917d954d3 100644 --- a/api_docs/kbn_managed_vscode_config.mdx +++ b/api_docs/kbn_managed_vscode_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-managed-vscode-config title: "@kbn/managed-vscode-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/managed-vscode-config plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/managed-vscode-config'] --- import kbnManagedVscodeConfigObj from './kbn_managed_vscode_config.devdocs.json'; diff --git a/api_docs/kbn_mapbox_gl.devdocs.json b/api_docs/kbn_mapbox_gl.devdocs.json index be7808b1047d2f..c620f401dd1fed 100644 --- a/api_docs/kbn_mapbox_gl.devdocs.json +++ b/api_docs/kbn_mapbox_gl.devdocs.json @@ -8105,7 +8105,7 @@ "label": "MapEvent", "description": [], "signature": [ - "\"error\" | \"rotate\" | \"move\" | \"render\" | \"data\" | \"remove\" | \"idle\" | \"resize\" | \"zoom\" | \"mousedown\" | \"mouseup\" | \"mouseover\" | \"mousemove\" | \"click\" | \"dblclick\" | \"mouseenter\" | \"mouseleave\" | \"mouseout\" | \"contextmenu\" | \"wheel\" | \"touchstart\" | \"touchend\" | \"touchmove\" | \"touchcancel\" | \"movestart\" | \"moveend\" | \"dragstart\" | \"drag\" | \"dragend\" | \"zoomstart\" | \"zoomend\" | \"rotatestart\" | \"rotateend\" | \"pitchstart\" | \"pitch\" | \"pitchend\" | \"boxzoomstart\" | \"boxzoomend\" | \"boxzoomcancel\" | \"webglcontextlost\" | \"webglcontextrestored\" | \"load\" | \"styledata\" | \"sourcedata\" | \"dataloading\" | \"styledataloading\" | \"sourcedataloading\" | \"styleimagemissing\" | \"style.load\" | \"dataabort\" | \"sourcedataabort\"" + "\"error\" | \"render\" | \"data\" | \"remove\" | \"rotate\" | \"move\" | \"idle\" | \"resize\" | \"zoom\" | \"mousedown\" | \"mouseup\" | \"mouseover\" | \"mousemove\" | \"click\" | \"dblclick\" | \"mouseenter\" | \"mouseleave\" | \"mouseout\" | \"contextmenu\" | \"wheel\" | \"touchstart\" | \"touchend\" | \"touchmove\" | \"touchcancel\" | \"movestart\" | \"moveend\" | \"dragstart\" | \"drag\" | \"dragend\" | \"zoomstart\" | \"zoomend\" | \"rotatestart\" | \"rotateend\" | \"pitchstart\" | \"pitch\" | \"pitchend\" | \"boxzoomstart\" | \"boxzoomend\" | \"boxzoomcancel\" | \"webglcontextlost\" | \"webglcontextrestored\" | \"load\" | \"styledata\" | \"sourcedata\" | \"dataloading\" | \"styledataloading\" | \"sourcedataloading\" | \"styleimagemissing\" | \"style.load\" | \"dataabort\" | \"sourcedataabort\"" ], "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, diff --git a/api_docs/kbn_mapbox_gl.mdx b/api_docs/kbn_mapbox_gl.mdx index 1f4a982f191af5..0ff7c437c34517 100644 --- a/api_docs/kbn_mapbox_gl.mdx +++ b/api_docs/kbn_mapbox_gl.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-mapbox-gl title: "@kbn/mapbox-gl" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/mapbox-gl plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/mapbox-gl'] --- import kbnMapboxGlObj from './kbn_mapbox_gl.devdocs.json'; diff --git a/api_docs/kbn_ml_agg_utils.mdx b/api_docs/kbn_ml_agg_utils.mdx index 1af27a73fe6810..24e786f45ed258 100644 --- a/api_docs/kbn_ml_agg_utils.mdx +++ b/api_docs/kbn_ml_agg_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-agg-utils title: "@kbn/ml-agg-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-agg-utils plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-agg-utils'] --- import kbnMlAggUtilsObj from './kbn_ml_agg_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_is_populated_object.mdx b/api_docs/kbn_ml_is_populated_object.mdx index 2ae29544e36894..58ba4bfbb5a969 100644 --- a/api_docs/kbn_ml_is_populated_object.mdx +++ b/api_docs/kbn_ml_is_populated_object.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-is-populated-object title: "@kbn/ml-is-populated-object" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-is-populated-object plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-is-populated-object'] --- import kbnMlIsPopulatedObjectObj from './kbn_ml_is_populated_object.devdocs.json'; diff --git a/api_docs/kbn_ml_string_hash.mdx b/api_docs/kbn_ml_string_hash.mdx index b9d965ef03600c..826cba74538d6a 100644 --- a/api_docs/kbn_ml_string_hash.mdx +++ b/api_docs/kbn_ml_string_hash.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-string-hash title: "@kbn/ml-string-hash" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-string-hash plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-string-hash'] --- import kbnMlStringHashObj from './kbn_ml_string_hash.devdocs.json'; diff --git a/api_docs/kbn_monaco.mdx b/api_docs/kbn_monaco.mdx index b35a00702e6877..b62c54239c901a 100644 --- a/api_docs/kbn_monaco.mdx +++ b/api_docs/kbn_monaco.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-monaco title: "@kbn/monaco" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/monaco plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/monaco'] --- import kbnMonacoObj from './kbn_monaco.devdocs.json'; diff --git a/api_docs/kbn_optimizer.mdx b/api_docs/kbn_optimizer.mdx index cdb355b25e89c3..277224be271d98 100644 --- a/api_docs/kbn_optimizer.mdx +++ b/api_docs/kbn_optimizer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-optimizer title: "@kbn/optimizer" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/optimizer plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/optimizer'] --- import kbnOptimizerObj from './kbn_optimizer.devdocs.json'; diff --git a/api_docs/kbn_optimizer_webpack_helpers.mdx b/api_docs/kbn_optimizer_webpack_helpers.mdx index 555c223448914e..abcf32373e2939 100644 --- a/api_docs/kbn_optimizer_webpack_helpers.mdx +++ b/api_docs/kbn_optimizer_webpack_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-optimizer-webpack-helpers title: "@kbn/optimizer-webpack-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/optimizer-webpack-helpers plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/optimizer-webpack-helpers'] --- import kbnOptimizerWebpackHelpersObj from './kbn_optimizer_webpack_helpers.devdocs.json'; diff --git a/api_docs/kbn_performance_testing_dataset_extractor.mdx b/api_docs/kbn_performance_testing_dataset_extractor.mdx index 3dbbb7d8b87cb5..59663310ab553f 100644 --- a/api_docs/kbn_performance_testing_dataset_extractor.mdx +++ b/api_docs/kbn_performance_testing_dataset_extractor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-performance-testing-dataset-extractor title: "@kbn/performance-testing-dataset-extractor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/performance-testing-dataset-extractor plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/performance-testing-dataset-extractor'] --- import kbnPerformanceTestingDatasetExtractorObj from './kbn_performance_testing_dataset_extractor.devdocs.json'; diff --git a/api_docs/kbn_plugin_generator.mdx b/api_docs/kbn_plugin_generator.mdx index 01c83e98a7ebce..c87510c9f37571 100644 --- a/api_docs/kbn_plugin_generator.mdx +++ b/api_docs/kbn_plugin_generator.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-plugin-generator title: "@kbn/plugin-generator" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/plugin-generator plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/plugin-generator'] --- import kbnPluginGeneratorObj from './kbn_plugin_generator.devdocs.json'; diff --git a/api_docs/kbn_plugin_helpers.mdx b/api_docs/kbn_plugin_helpers.mdx index a4f61037fba890..b14f2415ae3209 100644 --- a/api_docs/kbn_plugin_helpers.mdx +++ b/api_docs/kbn_plugin_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-plugin-helpers title: "@kbn/plugin-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/plugin-helpers plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/plugin-helpers'] --- import kbnPluginHelpersObj from './kbn_plugin_helpers.devdocs.json'; diff --git a/api_docs/kbn_react_field.devdocs.json b/api_docs/kbn_react_field.devdocs.json index 64ce7f66c3796d..009157238dbe84 100644 --- a/api_docs/kbn_react_field.devdocs.json +++ b/api_docs/kbn_react_field.devdocs.json @@ -233,7 +233,7 @@ "\nUse the small size in condensed areas" ], "signature": [ - "\"s\" | \"m\" | undefined" + "\"m\" | \"s\" | undefined" ], "path": "packages/kbn-react-field/src/field_button/field_button.tsx", "deprecated": false @@ -375,7 +375,7 @@ "label": "ButtonSize", "description": [], "signature": [ - "\"s\" | \"m\"" + "\"m\" | \"s\"" ], "path": "packages/kbn-react-field/src/field_button/field_button.tsx", "deprecated": false, diff --git a/api_docs/kbn_react_field.mdx b/api_docs/kbn_react_field.mdx index 64a80ac2eb1cdf..7805a27c2e2533 100644 --- a/api_docs/kbn_react_field.mdx +++ b/api_docs/kbn_react_field.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-field title: "@kbn/react-field" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-field plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-field'] --- import kbnReactFieldObj from './kbn_react_field.devdocs.json'; diff --git a/api_docs/kbn_repo_source_classifier.mdx b/api_docs/kbn_repo_source_classifier.mdx index 007e8caf71553c..123d035d7974ba 100644 --- a/api_docs/kbn_repo_source_classifier.mdx +++ b/api_docs/kbn_repo_source_classifier.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-repo-source-classifier title: "@kbn/repo-source-classifier" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/repo-source-classifier plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/repo-source-classifier'] --- import kbnRepoSourceClassifierObj from './kbn_repo_source_classifier.devdocs.json'; diff --git a/api_docs/kbn_rule_data_utils.mdx b/api_docs/kbn_rule_data_utils.mdx index cc04ec6cd24381..ed2d7e07d1660c 100644 --- a/api_docs/kbn_rule_data_utils.mdx +++ b/api_docs/kbn_rule_data_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-rule-data-utils title: "@kbn/rule-data-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/rule-data-utils plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/rule-data-utils'] --- import kbnRuleDataUtilsObj from './kbn_rule_data_utils.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_autocomplete.devdocs.json b/api_docs/kbn_securitysolution_autocomplete.devdocs.json index 9b398cf6f6c7d5..a510ecf234a9e9 100644 --- a/api_docs/kbn_securitysolution_autocomplete.devdocs.json +++ b/api_docs/kbn_securitysolution_autocomplete.devdocs.json @@ -305,9 +305,9 @@ "\nGiven an array of lists and optionally a field this will return all\nthe lists that match against the field based on the types from the field\n\nNOTE: That we support one additional property from \"FieldSpec\" located here:\nsrc/plugins/data/common/index_patterns/fields/types.ts\nThis type property is esTypes. If it exists and is on there we will read off the esTypes." ], "signature": [ - "(lists: { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; version: number; }[], field?: (", + "(lists: { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; version: number; }[], field?: (", "DataViewFieldBase", - " & { esTypes?: string[] | undefined; }) | undefined) => { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; version: number; }[]" + " & { esTypes?: string[] | undefined; }) | undefined) => { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; version: number; }[]" ], "path": "packages/kbn-securitysolution-autocomplete/src/filter_field_to_list/index.ts", "deprecated": false, @@ -322,7 +322,7 @@ "The lists to match against the field" ], "signature": [ - "{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; version: number; }[]" + "{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; version: number; }[]" ], "path": "packages/kbn-securitysolution-autocomplete/src/filter_field_to_list/index.ts", "deprecated": false, diff --git a/api_docs/kbn_securitysolution_autocomplete.mdx b/api_docs/kbn_securitysolution_autocomplete.mdx index d9f4412c65d218..8b72dd4973df07 100644 --- a/api_docs/kbn_securitysolution_autocomplete.mdx +++ b/api_docs/kbn_securitysolution_autocomplete.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-autocomplete title: "@kbn/securitysolution-autocomplete" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-autocomplete plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-autocomplete'] --- import kbnSecuritysolutionAutocompleteObj from './kbn_securitysolution_autocomplete.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_es_utils.devdocs.json b/api_docs/kbn_securitysolution_es_utils.devdocs.json index 691d22e6d89ad2..821e948cf359bb 100644 --- a/api_docs/kbn_securitysolution_es_utils.devdocs.json +++ b/api_docs/kbn_securitysolution_es_utils.devdocs.json @@ -487,7 +487,9 @@ "TransportRequestOptions", " | undefined): Promise<", "WriteResponseBase", - ">; }; name: string | symbol; transform: ", + ">; }; cluster: ", + "default", + "; eql: ", "default", "; search: { >; }; cluster: ", - "default", - "; eql: ", - "default", - "; create: { (this: That, params: ", + ">; }; create: { (this: That, params: ", "CreateRequest", " | ", "CreateRequest", @@ -555,7 +553,7 @@ "default", "; security: ", "default", - "; index: { (this: That, params: ", + "; name: string | symbol; index: { (this: That, params: ", "IndexRequest", " | ", "IndexRequest", @@ -1563,6 +1561,8 @@ "TermvectorsResponse", ">; }; textStructure: ", "default", + "; transform: ", + "default", "; updateByQuery: { (this: That, params: ", "UpdateByQueryRequest", " | ", @@ -1729,7 +1729,9 @@ "TransportRequestOptions", " | undefined): Promise<", "WriteResponseBase", - ">; }; name: string | symbol; transform: ", + ">; }; cluster: ", + "default", + "; eql: ", "default", "; search: { >; }; cluster: ", - "default", - "; eql: ", - "default", - "; create: { (this: That, params: ", + ">; }; create: { (this: That, params: ", "CreateRequest", " | ", "CreateRequest", @@ -1797,7 +1795,7 @@ "default", "; security: ", "default", - "; index: { (this: That, params: ", + "; name: string | symbol; index: { (this: That, params: ", "IndexRequest", " | ", "IndexRequest", @@ -2805,6 +2803,8 @@ "TermvectorsResponse", ">; }; textStructure: ", "default", + "; transform: ", + "default", "; updateByQuery: { (this: That, params: ", "UpdateByQueryRequest", " | ", diff --git a/api_docs/kbn_securitysolution_es_utils.mdx b/api_docs/kbn_securitysolution_es_utils.mdx index 29d81b841d5703..0d3e682fd00752 100644 --- a/api_docs/kbn_securitysolution_es_utils.mdx +++ b/api_docs/kbn_securitysolution_es_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-es-utils title: "@kbn/securitysolution-es-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-es-utils plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-es-utils'] --- import kbnSecuritysolutionEsUtilsObj from './kbn_securitysolution_es_utils.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_hook_utils.mdx b/api_docs/kbn_securitysolution_hook_utils.mdx index 2900da4ea2a05d..68f91d6e91e3dd 100644 --- a/api_docs/kbn_securitysolution_hook_utils.mdx +++ b/api_docs/kbn_securitysolution_hook_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-hook-utils title: "@kbn/securitysolution-hook-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-hook-utils plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-hook-utils'] --- import kbnSecuritysolutionHookUtilsObj from './kbn_securitysolution_hook_utils.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx b/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx index caad89cf7a3c6d..39029ca2fd688e 100644 --- a/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx +++ b/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-alerting-types title: "@kbn/securitysolution-io-ts-alerting-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-alerting-types plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-io-ts-alerting-types'] --- import kbnSecuritysolutionIoTsAlertingTypesObj from './kbn_securitysolution_io_ts_alerting_types.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_io_ts_list_types.devdocs.json b/api_docs/kbn_securitysolution_io_ts_list_types.devdocs.json index d70b0afdf481ca..5261280f27b3fc 100644 --- a/api_docs/kbn_securitysolution_io_ts_list_types.devdocs.json +++ b/api_docs/kbn_securitysolution_io_ts_list_types.devdocs.json @@ -27,7 +27,7 @@ "label": "updateExceptionListItemValidate", "description": [], "signature": [ - "(schema: { description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }) => string[]" + "(schema: { description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }) => string[]" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/request/update_exception_list_item_validation/index.ts", "deprecated": false, @@ -40,7 +40,7 @@ "label": "schema", "description": [], "signature": [ - "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" + "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/request/update_exception_list_item_validation/index.ts", "deprecated": false, @@ -58,7 +58,7 @@ "label": "validateComments", "description": [], "signature": [ - "(item: { description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }) => string[]" + "(item: { description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }) => string[]" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/request/update_exception_list_item_validation/index.ts", "deprecated": false, @@ -71,7 +71,7 @@ "label": "item", "description": [], "signature": [ - "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" + "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/request/update_exception_list_item_validation/index.ts", "deprecated": false, @@ -153,7 +153,7 @@ "label": "listItem", "description": [], "signature": [ - "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" + "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/typescript_types/index.ts", "deprecated": false @@ -1216,7 +1216,7 @@ "label": "listItem", "description": [], "signature": [ - "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" + "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/typescript_types/index.ts", "deprecated": false @@ -1307,7 +1307,7 @@ "label": "exceptions", "description": [], "signature": [ - "{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }[]" + "{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }[]" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/typescript_types/index.ts", "deprecated": false @@ -1897,7 +1897,7 @@ "label": "CreateEndpointListItemSchemaDecoded", "description": [], "signature": [ - "Omit<{ description: string; entries: ({ field: string; operator: \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; name: string; type: \"simple\"; comments: { comment: string; }[] | undefined; item_id: string | undefined; meta: object | undefined; os_types: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags: string[] | undefined; }, \"tags\" | \"entries\" | \"comments\" | \"item_id\" | \"os_types\"> & { comments: { comment: string; }[]; tags: string[]; item_id: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; os_types: (\"windows\" | \"linux\" | \"macos\")[]; }" + "Omit<{ description: string; entries: ({ field: string; operator: \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; name: string; type: \"simple\"; comments: { comment: string; }[] | undefined; item_id: string | undefined; meta: object | undefined; os_types: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags: string[] | undefined; }, \"tags\" | \"entries\" | \"comments\" | \"item_id\" | \"os_types\"> & { comments: { comment: string; }[]; tags: string[]; item_id: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; os_types: (\"windows\" | \"linux\" | \"macos\")[]; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/request/create_endpoint_list_item_schema/index.ts", "deprecated": false, @@ -1925,7 +1925,7 @@ "label": "CreateExceptionListItemSchema", "description": [], "signature": [ - "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" + "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/request/create_exception_list_item_schema/index.ts", "deprecated": false, @@ -1939,7 +1939,7 @@ "label": "CreateExceptionListItemSchemaDecoded", "description": [], "signature": [ - "Omit<{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; list_id: string; name: string; type: \"simple\"; comments: { comment: string; }[] | undefined; item_id: string | undefined; meta: object | undefined; namespace_type: \"single\" | \"agnostic\" | undefined; os_types: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags: string[] | undefined; }, \"tags\" | \"entries\" | \"comments\" | \"item_id\" | \"namespace_type\"> & { comments: { comment: string; }[]; tags: string[]; item_id: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; }" + "Omit<{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; list_id: string; name: string; type: \"simple\"; comments: { comment: string; }[] | undefined; item_id: string | undefined; meta: object | undefined; namespace_type: \"single\" | \"agnostic\" | undefined; os_types: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags: string[] | undefined; }, \"tags\" | \"entries\" | \"comments\" | \"item_id\" | \"namespace_type\"> & { comments: { comment: string; }[]; tags: string[]; item_id: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/request/create_exception_list_item_schema/index.ts", "deprecated": false, @@ -2009,7 +2009,7 @@ "label": "CreateListSchema", "description": [], "signature": [ - "{ description: string; name: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; } & { deserializer?: string | undefined; id?: string | undefined; meta?: object | undefined; serializer?: string | undefined; version?: number | undefined; }" + "{ description: string; name: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; } & { deserializer?: string | undefined; id?: string | undefined; meta?: object | undefined; serializer?: string | undefined; version?: number | undefined; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/request/create_list_schema/index.ts", "deprecated": false, @@ -2023,7 +2023,7 @@ "label": "CreateListSchemaDecoded", "description": [], "signature": [ - "{ type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; id: string | undefined; name: string; description: string; meta: object | undefined; serializer: string | undefined; deserializer: string | undefined; } & { version: number; }" + "{ type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; id: string | undefined; description: string; name: string; meta: object | undefined; serializer: string | undefined; deserializer: string | undefined; } & { version: number; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/request/create_list_schema/index.ts", "deprecated": false, @@ -2317,7 +2317,7 @@ "label": "EntriesArray", "description": [], "signature": [ - "({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]" + "({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/common/entries/index.ts", "deprecated": false, @@ -2331,7 +2331,7 @@ "label": "EntriesArrayOrUndefined", "description": [], "signature": [ - "({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[] | undefined" + "({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[] | undefined" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/common/entries/index.ts", "deprecated": false, @@ -2345,7 +2345,7 @@ "label": "Entry", "description": [], "signature": [ - "{ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; }" + "{ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/common/entries/index.ts", "deprecated": false, @@ -2373,7 +2373,7 @@ "label": "EntryList", "description": [], "signature": [ - "{ field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; }" + "{ field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/common/entries_list/index.ts", "deprecated": false, @@ -2443,7 +2443,7 @@ "label": "ExceptionListItemSchema", "description": [], "signature": [ - "{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }" + "{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/response/exception_list_item_schema/index.ts", "deprecated": false, @@ -2765,7 +2765,7 @@ "label": "FoundExceptionListItemSchema", "description": [], "signature": [ - "{ data: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }[]; page: number; per_page: number; total: number; } & { pit?: string | undefined; }" + "{ data: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }[]; page: number; per_page: number; total: number; } & { pit?: string | undefined; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/response/found_exception_list_item_schema/index.ts", "deprecated": false, @@ -2793,7 +2793,7 @@ "label": "FoundListItemSchema", "description": [], "signature": [ - "{ cursor: string; data: { _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; value: string; }[]; page: number; per_page: number; total: number; }" + "{ cursor: string; data: { _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; value: string; }[]; page: number; per_page: number; total: number; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/response/found_list_item_schema/index.ts", "deprecated": false, @@ -2807,7 +2807,7 @@ "label": "FoundListSchema", "description": [], "signature": [ - "{ cursor: string; data: { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; version: number; }[]; page: number; per_page: number; total: number; }" + "{ cursor: string; data: { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; version: number; }[]; page: number; per_page: number; total: number; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/response/found_list_schema/index.ts", "deprecated": false, @@ -2919,7 +2919,7 @@ "label": "ImportExceptionListItemSchema", "description": [], "signature": [ - "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; item_id: string; list_id: string; name: string; type: \"simple\"; } & { id?: string | undefined; comments?: (({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; }) | { comment: string; })[] | undefined; created_at?: string | undefined; updated_at?: string | undefined; created_by?: string | undefined; updated_by?: string | undefined; _version?: string | undefined; tie_breaker_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" + "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; item_id: string; list_id: string; name: string; type: \"simple\"; } & { id?: string | undefined; comments?: (({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; }) | { comment: string; })[] | undefined; created_at?: string | undefined; updated_at?: string | undefined; created_by?: string | undefined; updated_by?: string | undefined; _version?: string | undefined; tie_breaker_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/request/import_exception_item_schema/index.ts", "deprecated": false, @@ -2933,7 +2933,7 @@ "label": "ImportExceptionListItemSchemaDecoded", "description": [], "signature": [ - "Omit<{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; item_id: string; list_id: string; name: string; type: \"simple\"; } & { id?: string | undefined; comments?: (({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; }) | { comment: string; })[] | undefined; created_at?: string | undefined; updated_at?: string | undefined; created_by?: string | undefined; updated_by?: string | undefined; _version?: string | undefined; tie_breaker_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }, \"tags\" | \"entries\" | \"comments\" | \"item_id\" | \"namespace_type\"> & { comments: (({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; }) | { comment: string; })[]; tags: string[]; item_id: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; }" + "Omit<{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; item_id: string; list_id: string; name: string; type: \"simple\"; } & { id?: string | undefined; comments?: (({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; }) | { comment: string; })[] | undefined; created_at?: string | undefined; updated_at?: string | undefined; created_by?: string | undefined; updated_by?: string | undefined; _version?: string | undefined; tie_breaker_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }, \"tags\" | \"entries\" | \"comments\" | \"item_id\" | \"namespace_type\"> & { comments: (({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; }) | { comment: string; })[]; tags: string[]; item_id: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/request/import_exception_item_schema/index.ts", "deprecated": false, @@ -2989,7 +2989,7 @@ "label": "ImportListItemQuerySchema", "description": [], "signature": [ - "{ deserializer: string | undefined; list_id: string | undefined; serializer: string | undefined; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\" | undefined; }" + "{ deserializer: string | undefined; list_id: string | undefined; serializer: string | undefined; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\" | undefined; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/request/import_list_item_query_schema/index.ts", "deprecated": false, @@ -3003,7 +3003,7 @@ "label": "ImportListItemQuerySchemaEncoded", "description": [], "signature": [ - "{ deserializer?: string | undefined; list_id?: string | undefined; serializer?: string | undefined; type?: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\" | undefined; }" + "{ deserializer?: string | undefined; list_id?: string | undefined; serializer?: string | undefined; type?: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\" | undefined; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/request/import_list_item_query_schema/index.ts", "deprecated": false, @@ -3115,7 +3115,7 @@ "label": "ListArraySchema", "description": [], "signature": [ - "{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; version: number; }[]" + "{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; version: number; }[]" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/response/list_schema/index.ts", "deprecated": false, @@ -3157,7 +3157,7 @@ "label": "ListItemArraySchema", "description": [], "signature": [ - "{ _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; value: string; }[]" + "{ _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; value: string; }[]" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/response/list_item_schema/index.ts", "deprecated": false, @@ -3185,7 +3185,7 @@ "label": "ListItemSchema", "description": [], "signature": [ - "{ _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; value: string; }" + "{ _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; value: string; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/response/list_item_schema/index.ts", "deprecated": false, @@ -3213,7 +3213,7 @@ "label": "ListSchema", "description": [], "signature": [ - "{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; version: number; }" + "{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; version: number; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/response/list_schema/index.ts", "deprecated": false, @@ -3423,7 +3423,7 @@ "label": "NonEmptyEntriesArray", "description": [], "signature": [ - "({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]" + "({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/common/non_empty_entries_array/index.ts", "deprecated": false, @@ -3437,7 +3437,7 @@ "label": "NonEmptyEntriesArrayDecoded", "description": [], "signature": [ - "({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]" + "({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/common/non_empty_entries_array/index.ts", "deprecated": false, @@ -3829,7 +3829,7 @@ "label": "SearchListItemArraySchema", "description": [], "signature": [ - "{ items: { _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; value: string; }[]; value: unknown; }[]" + "{ items: { _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; value: string; }[]; value: unknown; }[]" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/response/search_list_item_schema/index.ts", "deprecated": false, @@ -3843,7 +3843,7 @@ "label": "SearchListItemSchema", "description": [], "signature": [ - "{ items: { _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; value: string; }[]; value: unknown; }" + "{ items: { _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; value: string; }[]; value: unknown; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/response/search_list_item_schema/index.ts", "deprecated": false, @@ -3983,7 +3983,7 @@ "label": "Type", "description": [], "signature": [ - "\"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"" + "\"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/common/type/index.ts", "deprecated": false, @@ -3997,7 +3997,7 @@ "label": "TypeOrUndefined", "description": [], "signature": [ - "\"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\" | undefined" + "\"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\" | undefined" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/common/type/index.ts", "deprecated": false, @@ -4053,7 +4053,7 @@ "label": "UpdateEndpointListItemSchema", "description": [], "signature": [ - "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" + "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/request/update_endpoint_list_item_schema/index.ts", "deprecated": false, @@ -4067,7 +4067,7 @@ "label": "UpdateEndpointListItemSchemaDecoded", "description": [], "signature": [ - "Omit<{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; name: string; type: \"simple\"; _version: string | undefined; comments: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id: string | undefined; item_id: string | undefined; meta: object | undefined; os_types: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags: string[] | undefined; }, \"tags\" | \"entries\" | \"comments\"> & { comments: ({ comment: string; } & { id?: string | undefined; })[]; tags: string[]; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; os_types: (\"windows\" | \"linux\" | \"macos\")[]; }" + "Omit<{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; name: string; type: \"simple\"; _version: string | undefined; comments: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id: string | undefined; item_id: string | undefined; meta: object | undefined; os_types: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags: string[] | undefined; }, \"tags\" | \"entries\" | \"comments\"> & { comments: ({ comment: string; } & { id?: string | undefined; })[]; tags: string[]; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; os_types: (\"windows\" | \"linux\" | \"macos\")[]; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/request/update_endpoint_list_item_schema/index.ts", "deprecated": false, @@ -4081,7 +4081,7 @@ "label": "UpdateExceptionListItemSchema", "description": [], "signature": [ - "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" + "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/request/update_exception_list_item_schema/index.ts", "deprecated": false, @@ -4095,7 +4095,7 @@ "label": "UpdateExceptionListItemSchemaDecoded", "description": [], "signature": [ - "Omit<{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; name: string; type: \"simple\"; _version: string | undefined; comments: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id: string | undefined; item_id: string | undefined; meta: object | undefined; namespace_type: \"single\" | \"agnostic\" | undefined; os_types: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags: string[] | undefined; }, \"tags\" | \"entries\" | \"comments\" | \"namespace_type\" | \"os_types\"> & { comments: ({ comment: string; } & { id?: string | undefined; })[]; tags: string[]; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; }" + "Omit<{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; name: string; type: \"simple\"; _version: string | undefined; comments: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id: string | undefined; item_id: string | undefined; meta: object | undefined; namespace_type: \"single\" | \"agnostic\" | undefined; os_types: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags: string[] | undefined; }, \"tags\" | \"entries\" | \"comments\" | \"namespace_type\" | \"os_types\"> & { comments: ({ comment: string; } & { id?: string | undefined; })[]; tags: string[]; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/request/update_exception_list_item_schema/index.ts", "deprecated": false, @@ -4628,7 +4628,7 @@ "StringC", "; entries: ", "Type", - "<({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[], ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[], unknown>; list_id: ", + "<({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[], ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[], unknown>; list_id: ", "Type", "; name: ", "StringC", @@ -6914,7 +6914,7 @@ "StringC", "; entries: ", "Type", - "<({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[], ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[], unknown>; item_id: ", + "<({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[], ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[], unknown>; item_id: ", "Type", "; list_id: ", "Type", @@ -7847,7 +7847,7 @@ ], "signature": [ "Type", - "<({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[], ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[], unknown>" + "<({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[], ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[], unknown>" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/common/non_empty_entries_array/index.ts", "deprecated": false, @@ -8780,7 +8780,7 @@ "StringC", "; entries: ", "Type", - "<({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[], ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[], unknown>; name: ", + "<({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[], ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[], unknown>; name: ", "StringC", "; type: ", "KeyofC", @@ -8833,7 +8833,7 @@ "StringC", "; entries: ", "Type", - "<({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[], ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[], unknown>; name: ", + "<({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[], ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[], unknown>; name: ", "StringC", "; type: ", "KeyofC", diff --git a/api_docs/kbn_securitysolution_io_ts_list_types.mdx b/api_docs/kbn_securitysolution_io_ts_list_types.mdx index 1447ce170ef820..6c716e1b0dc2fe 100644 --- a/api_docs/kbn_securitysolution_io_ts_list_types.mdx +++ b/api_docs/kbn_securitysolution_io_ts_list_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-list-types title: "@kbn/securitysolution-io-ts-list-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-list-types plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-io-ts-list-types'] --- import kbnSecuritysolutionIoTsListTypesObj from './kbn_securitysolution_io_ts_list_types.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_io_ts_types.mdx b/api_docs/kbn_securitysolution_io_ts_types.mdx index f7cecb5cba1520..05a77acf754e2e 100644 --- a/api_docs/kbn_securitysolution_io_ts_types.mdx +++ b/api_docs/kbn_securitysolution_io_ts_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-types title: "@kbn/securitysolution-io-ts-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-types plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-io-ts-types'] --- import kbnSecuritysolutionIoTsTypesObj from './kbn_securitysolution_io_ts_types.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_io_ts_utils.mdx b/api_docs/kbn_securitysolution_io_ts_utils.mdx index ab60c507fdac96..216a70495d7299 100644 --- a/api_docs/kbn_securitysolution_io_ts_utils.mdx +++ b/api_docs/kbn_securitysolution_io_ts_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-utils title: "@kbn/securitysolution-io-ts-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-utils plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-io-ts-utils'] --- import kbnSecuritysolutionIoTsUtilsObj from './kbn_securitysolution_io_ts_utils.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_list_api.devdocs.json b/api_docs/kbn_securitysolution_list_api.devdocs.json index 3acfb1f1694019..53a9d300892b88 100644 --- a/api_docs/kbn_securitysolution_list_api.devdocs.json +++ b/api_docs/kbn_securitysolution_list_api.devdocs.json @@ -62,7 +62,7 @@ "signature": [ "({ http, listItem, signal, }: ", "AddExceptionListItemProps", - ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }>" + ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }>" ], "path": "packages/kbn-securitysolution-list-api/src/api/index.ts", "deprecated": false, @@ -206,7 +206,7 @@ "signature": [ "({ http, id, namespaceType, signal, }: ", "ApiCallByIdProps", - ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }>" + ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }>" ], "path": "packages/kbn-securitysolution-list-api/src/api/index.ts", "deprecated": false, @@ -245,7 +245,7 @@ "section": "def-common.DeleteListParams", "text": "DeleteListParams" }, - ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; version: number; }>" + ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; version: number; }>" ], "path": "packages/kbn-securitysolution-list-api/src/list_api/index.ts", "deprecated": false, @@ -399,7 +399,7 @@ "signature": [ "({ http, id, namespaceType, signal, }: ", "ApiCallByIdProps", - ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }>" + ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }>" ], "path": "packages/kbn-securitysolution-list-api/src/api/index.ts", "deprecated": false, @@ -432,7 +432,7 @@ "signature": [ "({ filterOptions, http, listIds, namespaceTypes, pagination, signal, }: ", "ApiCallByListIdProps", - ") => Promise<{ data: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }[]; page: number; per_page: number; total: number; } & { pit?: string | undefined; }>" + ") => Promise<{ data: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }[]; page: number; per_page: number; total: number; } & { pit?: string | undefined; }>" ], "path": "packages/kbn-securitysolution-list-api/src/api/index.ts", "deprecated": false, @@ -504,7 +504,7 @@ "section": "def-common.FindListsParams", "text": "FindListsParams" }, - ") => Promise<{ cursor: string; data: { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; version: number; }[]; page: number; per_page: number; total: number; }>" + ") => Promise<{ cursor: string; data: { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; version: number; }[]; page: number; per_page: number; total: number; }>" ], "path": "packages/kbn-securitysolution-list-api/src/list_api/index.ts", "deprecated": false, @@ -549,7 +549,7 @@ "section": "def-common.ImportListParams", "text": "ImportListParams" }, - ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; version: number; }>" + ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; version: number; }>" ], "path": "packages/kbn-securitysolution-list-api/src/list_api/index.ts", "deprecated": false, @@ -743,7 +743,7 @@ "signature": [ "({ http, listItem, signal, }: ", "UpdateExceptionListItemProps", - ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }>" + ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }>" ], "path": "packages/kbn-securitysolution-list-api/src/api/index.ts", "deprecated": false, @@ -1102,7 +1102,7 @@ "label": "type", "description": [], "signature": [ - "\"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\" | undefined" + "\"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\" | undefined" ], "path": "packages/kbn-securitysolution-list-api/src/list_api/types.ts", "deprecated": false diff --git a/api_docs/kbn_securitysolution_list_api.mdx b/api_docs/kbn_securitysolution_list_api.mdx index 6ef6db1c1d87be..2e3a5854f2801d 100644 --- a/api_docs/kbn_securitysolution_list_api.mdx +++ b/api_docs/kbn_securitysolution_list_api.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-api title: "@kbn/securitysolution-list-api" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-api plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-list-api'] --- import kbnSecuritysolutionListApiObj from './kbn_securitysolution_list_api.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_list_constants.mdx b/api_docs/kbn_securitysolution_list_constants.mdx index 90f5b69d456230..64a295cce13c76 100644 --- a/api_docs/kbn_securitysolution_list_constants.mdx +++ b/api_docs/kbn_securitysolution_list_constants.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-constants title: "@kbn/securitysolution-list-constants" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-constants plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-list-constants'] --- import kbnSecuritysolutionListConstantsObj from './kbn_securitysolution_list_constants.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_list_hooks.devdocs.json b/api_docs/kbn_securitysolution_list_hooks.devdocs.json index cea0783070c182..ad642ef094b124 100644 --- a/api_docs/kbn_securitysolution_list_hooks.devdocs.json +++ b/api_docs/kbn_securitysolution_list_hooks.devdocs.json @@ -29,7 +29,7 @@ "\nThis adds an id to the incoming exception item entries as ReactJS prefers to have\nan id added to them for use as a stable id. Later if we decide to change the data\nmodel to have id's within the array then this code should be removed. If not, then\nthis code should stay as an adapter for ReactJS.\n\nThis does break the type system slightly as we are lying a bit to the type system as we return\nthe same exceptionItem as we have previously but are augmenting the arrays with an id which TypeScript\ndoesn't mind us doing here. However, downstream you will notice that you have an id when the type\ndoes not indicate it. In that case use (ExceptionItem & { id: string }) temporarily if you're using the id. If you're not,\nyou can ignore the id and just use the normal TypeScript with ReactJS.\n" ], "signature": [ - "(exceptionItem: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }) => { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }" + "(exceptionItem: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }) => { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }" ], "path": "packages/kbn-securitysolution-list-hooks/src/transforms/index.ts", "deprecated": false, @@ -44,7 +44,7 @@ "The exceptionItem to add an id to the threat matches." ], "signature": [ - "{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }" + "{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }" ], "path": "packages/kbn-securitysolution-list-hooks/src/transforms/index.ts", "deprecated": false, @@ -66,7 +66,7 @@ "\nThis removes an id from the exceptionItem entries as ReactJS prefers to have\nan id added to them for use as a stable id. Later if we decide to change the data\nmodel to have id's within the array then this code should be removed. If not, then\nthis code should stay as an adapter for ReactJS.\n" ], "signature": [ - "(exceptionItem: T) => T" + "(exceptionItem: T) => T" ], "path": "packages/kbn-securitysolution-list-hooks/src/transforms/index.ts", "deprecated": false, @@ -103,7 +103,7 @@ "\nTransforms the output of rules to compensate for technical debt or UI concerns such as\nReactJS preferences for having ids within arrays if the data is not modeled that way.\n\nIf you add a new transform of the input called \"myNewTransform\" do it\nin the form of:\nflow(addIdToExceptionItemEntries, myNewTransform)(exceptionItem)\n" ], "signature": [ - "(exceptionItem: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }) => { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }" + "(exceptionItem: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }) => { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }" ], "path": "packages/kbn-securitysolution-list-hooks/src/transforms/index.ts", "deprecated": false, @@ -118,7 +118,7 @@ "The exceptionItem to transform the output of" ], "signature": [ - "{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }" + "{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }" ], "path": "packages/kbn-securitysolution-list-hooks/src/transforms/index.ts", "deprecated": false, @@ -138,7 +138,7 @@ "label": "transformNewItemOutput", "description": [], "signature": [ - "(exceptionItem: { description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }) => { description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" + "(exceptionItem: { description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }) => { description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" ], "path": "packages/kbn-securitysolution-list-hooks/src/transforms/index.ts", "deprecated": false, @@ -151,7 +151,7 @@ "label": "exceptionItem", "description": [], "signature": [ - "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" + "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" ], "path": "packages/kbn-securitysolution-list-hooks/src/transforms/index.ts", "deprecated": false, @@ -171,7 +171,7 @@ "\nTransforms the output of exception items to compensate for technical debt or UI concerns such as\nReactJS preferences for having ids within arrays if the data is not modeled that way.\n\nIf you add a new transform of the output called \"myNewTransform\" do it\nin the form of:\nflow(removeIdFromExceptionItemsEntries, myNewTransform)(exceptionItem)\n" ], "signature": [ - "(exceptionItem: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | ({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; })) => { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | ({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; })" + "(exceptionItem: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | ({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; })) => { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | ({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; })" ], "path": "packages/kbn-securitysolution-list-hooks/src/transforms/index.ts", "deprecated": false, @@ -186,7 +186,7 @@ "The exceptionItem to transform the output of" ], "signature": [ - "{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | ({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; })" + "{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | ({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; })" ], "path": "packages/kbn-securitysolution-list-hooks/src/transforms/index.ts", "deprecated": false, @@ -317,7 +317,7 @@ "OptionalSignalArgs", "<", "DeleteListParams", - ">], { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; version: number; }>" + ">], { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; version: number; }>" ], "path": "packages/kbn-securitysolution-list-hooks/src/use_delete_list/index.ts", "deprecated": false, @@ -445,7 +445,7 @@ "OptionalSignalArgs", "<", "FindListsParams", - ">], { cursor: string; data: { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; version: number; }[]; page: number; per_page: number; total: number; }>" + ">], { cursor: string; data: { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; version: number; }[]; page: number; per_page: number; total: number; }>" ], "path": "packages/kbn-securitysolution-list-hooks/src/use_find_lists/index.ts", "deprecated": false, @@ -467,7 +467,7 @@ "OptionalSignalArgs", "<", "ImportListParams", - ">], { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; version: number; }>" + ">], { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; version: number; }>" ], "path": "packages/kbn-securitysolution-list-hooks/src/use_import_list/index.ts", "deprecated": false, @@ -623,7 +623,7 @@ "label": "addExceptionListItem", "description": [], "signature": [ - "(arg: { listItem: { description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }; }) => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }>" + "(arg: { listItem: { description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }; }) => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }>" ], "path": "packages/kbn-securitysolution-list-hooks/src/use_api/index.ts", "deprecated": false, @@ -646,7 +646,7 @@ "label": "listItem", "description": [], "signature": [ - "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" + "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" ], "path": "packages/kbn-securitysolution-list-hooks/src/use_api/index.ts", "deprecated": false @@ -664,7 +664,7 @@ "label": "updateExceptionListItem", "description": [], "signature": [ - "(arg: { listItem: { description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }; }) => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }>" + "(arg: { listItem: { description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }; }) => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }>" ], "path": "packages/kbn-securitysolution-list-hooks/src/use_api/index.ts", "deprecated": false, @@ -687,7 +687,7 @@ "label": "listItem", "description": [], "signature": [ - "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" + "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" ], "path": "packages/kbn-securitysolution-list-hooks/src/use_api/index.ts", "deprecated": false @@ -771,7 +771,7 @@ "signature": [ "(arg: ", "ApiCallMemoProps", - " & { onSuccess: (arg: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }) => void; }) => Promise" + " & { onSuccess: (arg: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }) => void; }) => Promise" ], "path": "packages/kbn-securitysolution-list-hooks/src/use_api/index.ts", "deprecated": false, @@ -785,7 +785,7 @@ "description": [], "signature": [ "ApiCallMemoProps", - " & { onSuccess: (arg: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }) => void; }" + " & { onSuccess: (arg: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }) => void; }" ], "path": "packages/kbn-securitysolution-list-hooks/src/use_api/index.ts", "deprecated": false, @@ -954,7 +954,7 @@ "label": "ReturnExceptionListAndItems", "description": [], "signature": [ - "[boolean, { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }[], ", + "[boolean, { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }[], ", "Pagination", ", Func | null]" ], @@ -996,7 +996,7 @@ "label": "ReturnPersistExceptionItem", "description": [], "signature": [ - "[PersistReturnExceptionItem, React.Dispatch<({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }) | ({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }) | null>]" + "[PersistReturnExceptionItem, React.Dispatch<({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }) | ({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }) | null>]" ], "path": "packages/kbn-securitysolution-list-hooks/src/use_persist_exception_item/index.ts", "deprecated": false, diff --git a/api_docs/kbn_securitysolution_list_hooks.mdx b/api_docs/kbn_securitysolution_list_hooks.mdx index e03c53805a0391..41a92f054e1486 100644 --- a/api_docs/kbn_securitysolution_list_hooks.mdx +++ b/api_docs/kbn_securitysolution_list_hooks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-hooks title: "@kbn/securitysolution-list-hooks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-hooks plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-list-hooks'] --- import kbnSecuritysolutionListHooksObj from './kbn_securitysolution_list_hooks.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_list_utils.devdocs.json b/api_docs/kbn_securitysolution_list_utils.devdocs.json index 000a5f00c264f5..056f6248c08a1d 100644 --- a/api_docs/kbn_securitysolution_list_utils.devdocs.json +++ b/api_docs/kbn_securitysolution_list_utils.devdocs.json @@ -27,7 +27,7 @@ "label": "addIdToEntries", "description": [], "signature": [ - "(entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]) => ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]" + "(entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]) => ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]" ], "path": "packages/kbn-securitysolution-list-utils/src/helpers/index.ts", "deprecated": false, @@ -40,7 +40,7 @@ "label": "entries", "description": [], "signature": [ - "({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]" + "({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]" ], "path": "packages/kbn-securitysolution-list-utils/src/helpers/index.ts", "deprecated": false, @@ -58,7 +58,7 @@ "label": "buildExceptionFilter", "description": [], "signature": [ - "({ lists, excludeExceptions, chunkSize, alias, }: { lists: ({ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | ({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }))[]; excludeExceptions: boolean; chunkSize: number; alias: string | null; }) => ", + "({ lists, excludeExceptions, chunkSize, alias, }: { lists: ({ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | ({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }))[]; excludeExceptions: boolean; chunkSize: number; alias: string | null; }) => ", "Filter", " | undefined" ], @@ -83,7 +83,7 @@ "label": "lists", "description": [], "signature": [ - "({ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | ({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }))[]" + "({ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | ({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }))[]" ], "path": "packages/kbn-securitysolution-list-utils/src/build_exception_filter/index.ts", "deprecated": false @@ -741,7 +741,7 @@ "section": "def-common.ExceptionsBuilderExceptionItem", "text": "ExceptionsBuilderExceptionItem" }, - "[]) => ({ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | ({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }))[]" + "[]) => ({ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | ({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }))[]" ], "path": "packages/kbn-securitysolution-list-utils/src/helpers/index.ts", "deprecated": false, @@ -995,7 +995,7 @@ "section": "def-common.FormattedBuilderEntry", "text": "FormattedBuilderEntry" }, - ") => ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; }) & { id?: string | undefined; }" + ") => ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; }) & { id?: string | undefined; }" ], "path": "packages/kbn-securitysolution-list-utils/src/helpers/index.ts", "deprecated": false, @@ -1137,7 +1137,7 @@ "section": "def-common.FormattedBuilderEntry", "text": "FormattedBuilderEntry" }, - ", newField: { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; version: number; }) => { index: number; updatedEntry: ", + ", newField: { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; version: number; }) => { index: number; updatedEntry: ", { "pluginId": "@kbn/securitysolution-list-utils", "scope": "common", @@ -1182,7 +1182,7 @@ "- newly selected list" ], "signature": [ - "{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; version: number; }" + "{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; version: number; }" ], "path": "packages/kbn-securitysolution-list-utils/src/helpers/index.ts", "deprecated": false, @@ -2567,7 +2567,7 @@ "label": "hasLargeValueList", "description": [], "signature": [ - "(entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]) => boolean" + "(entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]) => boolean" ], "path": "packages/kbn-securitysolution-list-utils/src/has_large_value_list/index.ts", "deprecated": false, @@ -2580,7 +2580,7 @@ "label": "entries", "description": [], "signature": [ - "({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]" + "({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]" ], "path": "packages/kbn-securitysolution-list-utils/src/has_large_value_list/index.ts", "deprecated": false, @@ -3229,7 +3229,7 @@ "label": "BuilderEntry", "description": [], "signature": [ - "(({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; }) & { id?: string | undefined; }) | ", + "(({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; }) & { id?: string | undefined; }) | ", { "pluginId": "@kbn/securitysolution-list-utils", "scope": "common", @@ -3288,7 +3288,7 @@ "label": "CreateExceptionListItemBuilderSchema", "description": [], "signature": [ - "Omit<{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }, \"meta\" | \"entries\"> & { meta: { temporaryUuid: string; }; entries: ", + "Omit<{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }, \"meta\" | \"entries\"> & { meta: { temporaryUuid: string; }; entries: ", { "pluginId": "@kbn/securitysolution-list-utils", "scope": "common", @@ -3422,7 +3422,7 @@ "label": "ExceptionListItemBuilderSchema", "description": [], "signature": [ - "Omit<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }, \"entries\"> & { entries: ", + "Omit<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }, \"entries\"> & { entries: ", { "pluginId": "@kbn/securitysolution-list-utils", "scope": "common", diff --git a/api_docs/kbn_securitysolution_list_utils.mdx b/api_docs/kbn_securitysolution_list_utils.mdx index 298811f5e2fddd..0db4ab6df2f5b1 100644 --- a/api_docs/kbn_securitysolution_list_utils.mdx +++ b/api_docs/kbn_securitysolution_list_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-utils title: "@kbn/securitysolution-list-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-utils plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-list-utils'] --- import kbnSecuritysolutionListUtilsObj from './kbn_securitysolution_list_utils.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_rules.mdx b/api_docs/kbn_securitysolution_rules.mdx index fa83957f1ba5f9..5bcff7eb599175 100644 --- a/api_docs/kbn_securitysolution_rules.mdx +++ b/api_docs/kbn_securitysolution_rules.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-rules title: "@kbn/securitysolution-rules" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-rules plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-rules'] --- import kbnSecuritysolutionRulesObj from './kbn_securitysolution_rules.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_t_grid.mdx b/api_docs/kbn_securitysolution_t_grid.mdx index fcc235a3f7fbeb..224633bc18fb62 100644 --- a/api_docs/kbn_securitysolution_t_grid.mdx +++ b/api_docs/kbn_securitysolution_t_grid.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-t-grid title: "@kbn/securitysolution-t-grid" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-t-grid plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-t-grid'] --- import kbnSecuritysolutionTGridObj from './kbn_securitysolution_t_grid.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_utils.mdx b/api_docs/kbn_securitysolution_utils.mdx index 045af631a35c86..5570eba1631c22 100644 --- a/api_docs/kbn_securitysolution_utils.mdx +++ b/api_docs/kbn_securitysolution_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-utils title: "@kbn/securitysolution-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-utils plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-utils'] --- import kbnSecuritysolutionUtilsObj from './kbn_securitysolution_utils.devdocs.json'; diff --git a/api_docs/kbn_server_http_tools.mdx b/api_docs/kbn_server_http_tools.mdx index 6a788fce5a6b09..1754a9e7d1ac77 100644 --- a/api_docs/kbn_server_http_tools.mdx +++ b/api_docs/kbn_server_http_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-server-http-tools title: "@kbn/server-http-tools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/server-http-tools plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/server-http-tools'] --- import kbnServerHttpToolsObj from './kbn_server_http_tools.devdocs.json'; diff --git a/api_docs/kbn_server_route_repository.mdx b/api_docs/kbn_server_route_repository.mdx index 1d88b6650d1954..fe06fa1ae64445 100644 --- a/api_docs/kbn_server_route_repository.mdx +++ b/api_docs/kbn_server_route_repository.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-server-route-repository title: "@kbn/server-route-repository" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/server-route-repository plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/server-route-repository'] --- import kbnServerRouteRepositoryObj from './kbn_server_route_repository.devdocs.json'; diff --git a/api_docs/kbn_shared_svg.mdx b/api_docs/kbn_shared_svg.mdx index 589bde07e5b770..16a6b5f78a42b4 100644 --- a/api_docs/kbn_shared_svg.mdx +++ b/api_docs/kbn_shared_svg.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-svg title: "@kbn/shared-svg" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-svg plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-svg'] --- import kbnSharedSvgObj from './kbn_shared_svg.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_button_exit_full_screen_mocks.devdocs.json b/api_docs/kbn_shared_ux_button_exit_full_screen_mocks.devdocs.json index cb248defc411ed..7595ab6a2bc3f0 100644 --- a/api_docs/kbn_shared_ux_button_exit_full_screen_mocks.devdocs.json +++ b/api_docs/kbn_shared_ux_button_exit_full_screen_mocks.devdocs.json @@ -9,10 +9,18 @@ "objects": [] }, "server": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "common": { "classes": [ { "parentPluginId": "@kbn/shared-ux-button-exit-full-screen-mocks", - "id": "def-server.StorybookMock", + "id": "def-common.StorybookMock", "type": "Class", "tags": [], "label": "StorybookMock", @@ -22,9 +30,9 @@ "signature": [ { "pluginId": "@kbn/shared-ux-button-exit-full-screen-mocks", - "scope": "server", + "scope": "common", "docId": "kibKbnSharedUxButtonExitFullScreenMocksPluginApi", - "section": "def-server.StorybookMock", + "section": "def-common.StorybookMock", "text": "StorybookMock" }, " extends ", @@ -40,7 +48,7 @@ "children": [ { "parentPluginId": "@kbn/shared-ux-button-exit-full-screen-mocks", - "id": "def-server.StorybookMock.propArguments", + "id": "def-common.StorybookMock.propArguments", "type": "Object", "tags": [], "label": "propArguments", @@ -50,7 +58,7 @@ "children": [ { "parentPluginId": "@kbn/shared-ux-button-exit-full-screen-mocks", - "id": "def-server.StorybookMock.propArguments.toggleChrome", + "id": "def-common.StorybookMock.propArguments.toggleChrome", "type": "Object", "tags": [], "label": "toggleChrome", @@ -60,7 +68,7 @@ "children": [ { "parentPluginId": "@kbn/shared-ux-button-exit-full-screen-mocks", - "id": "def-server.StorybookMock.propArguments.toggleChrome.control", + "id": "def-common.StorybookMock.propArguments.toggleChrome.control", "type": "string", "tags": [], "label": "control", @@ -70,7 +78,7 @@ }, { "parentPluginId": "@kbn/shared-ux-button-exit-full-screen-mocks", - "id": "def-server.StorybookMock.propArguments.toggleChrome.defaultValue", + "id": "def-common.StorybookMock.propArguments.toggleChrome.defaultValue", "type": "boolean", "tags": [], "label": "defaultValue", @@ -84,7 +92,7 @@ }, { "parentPluginId": "@kbn/shared-ux-button-exit-full-screen-mocks", - "id": "def-server.StorybookMock.serviceArguments", + "id": "def-common.StorybookMock.serviceArguments", "type": "Object", "tags": [], "label": "serviceArguments", @@ -95,7 +103,7 @@ }, { "parentPluginId": "@kbn/shared-ux-button-exit-full-screen-mocks", - "id": "def-server.StorybookMock.dependencies", + "id": "def-common.StorybookMock.dependencies", "type": "Array", "tags": [], "label": "dependencies", @@ -108,7 +116,7 @@ }, { "parentPluginId": "@kbn/shared-ux-button-exit-full-screen-mocks", - "id": "def-server.StorybookMock.getProps", + "id": "def-common.StorybookMock.getProps", "type": "Function", "tags": [], "label": "getProps", @@ -117,9 +125,9 @@ "(params?: ", { "pluginId": "@kbn/shared-ux-button-exit-full-screen-mocks", - "scope": "server", + "scope": "common", "docId": "kibKbnSharedUxButtonExitFullScreenMocksPluginApi", - "section": "def-server.Params", + "section": "def-common.Params", "text": "Params" }, " | undefined) => ", @@ -130,7 +138,7 @@ "children": [ { "parentPluginId": "@kbn/shared-ux-button-exit-full-screen-mocks", - "id": "def-server.StorybookMock.getProps.$1", + "id": "def-common.StorybookMock.getProps.$1", "type": "Object", "tags": [], "label": "params", @@ -138,9 +146,9 @@ "signature": [ { "pluginId": "@kbn/shared-ux-button-exit-full-screen-mocks", - "scope": "server", + "scope": "common", "docId": "kibKbnSharedUxButtonExitFullScreenMocksPluginApi", - "section": "def-server.Params", + "section": "def-common.Params", "text": "Params" }, " | undefined" @@ -154,7 +162,7 @@ }, { "parentPluginId": "@kbn/shared-ux-button-exit-full-screen-mocks", - "id": "def-server.StorybookMock.getServices", + "id": "def-common.StorybookMock.getServices", "type": "Function", "tags": [], "label": "getServices", @@ -175,7 +183,7 @@ "functions": [ { "parentPluginId": "@kbn/shared-ux-button-exit-full-screen-mocks", - "id": "def-server.getKibanaDependenciesMock", + "id": "def-common.getKibanaDependenciesMock", "type": "Function", "tags": [], "label": "getKibanaDependenciesMock", @@ -194,7 +202,7 @@ }, { "parentPluginId": "@kbn/shared-ux-button-exit-full-screen-mocks", - "id": "def-server.getServicesMock", + "id": "def-common.getServicesMock", "type": "Function", "tags": [], "label": "getServicesMock", @@ -217,7 +225,7 @@ "misc": [ { "parentPluginId": "@kbn/shared-ux-button-exit-full-screen-mocks", - "id": "def-server.Params", + "id": "def-common.Params", "type": "Type", "tags": [], "label": "Params", @@ -233,13 +241,5 @@ } ], "objects": [] - }, - "common": { - "classes": [], - "functions": [], - "interfaces": [], - "enums": [], - "misc": [], - "objects": [] } } \ No newline at end of file diff --git a/api_docs/kbn_shared_ux_button_exit_full_screen_mocks.mdx b/api_docs/kbn_shared_ux_button_exit_full_screen_mocks.mdx index 9c207bac4b3c1a..fffb4a370f7f18 100644 --- a/api_docs/kbn_shared_ux_button_exit_full_screen_mocks.mdx +++ b/api_docs/kbn_shared_ux_button_exit_full_screen_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-button-exit-full-screen-mocks title: "@kbn/shared-ux-button-exit-full-screen-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-button-exit-full-screen-mocks plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-button-exit-full-screen-mocks'] --- import kbnSharedUxButtonExitFullScreenMocksObj from './kbn_shared_ux_button_exit_full_screen_mocks.devdocs.json'; @@ -23,14 +23,14 @@ Contact [Owner missing] for questions regarding this plugin. |-------------------|-----------|------------------------|-----------------| | 13 | 0 | 9 | 0 | -## Server +## Common ### Functions - + ### Classes - + ### Consts, variables and types - + diff --git a/api_docs/kbn_shared_ux_button_toolbar.mdx b/api_docs/kbn_shared_ux_button_toolbar.mdx index 52e718706f416a..7fcc1db8751c1b 100644 --- a/api_docs/kbn_shared_ux_button_toolbar.mdx +++ b/api_docs/kbn_shared_ux_button_toolbar.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-button-toolbar title: "@kbn/shared-ux-button-toolbar" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-button-toolbar plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-button-toolbar'] --- import kbnSharedUxButtonToolbarObj from './kbn_shared_ux_button_toolbar.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_card_no_data.devdocs.json b/api_docs/kbn_shared_ux_card_no_data.devdocs.json index 5bd520c2260b53..37fb7c13e4e9d0 100644 --- a/api_docs/kbn_shared_ux_card_no_data.devdocs.json +++ b/api_docs/kbn_shared_ux_card_no_data.devdocs.json @@ -142,7 +142,7 @@ "signature": [ "Partial> & { button?: React.ReactNode; onClick?: React.MouseEventHandler | undefined; description?: React.ReactNode; category?: string | undefined; canAccessFleet?: boolean | undefined; }" + ", \"onClick\" | \"description\" | \"isDisabled\" | \"button\" | \"layout\">> & { button?: React.ReactNode; onClick?: React.MouseEventHandler | undefined; description?: React.ReactNode; category?: string | undefined; canAccessFleet?: boolean | undefined; }" ], "path": "node_modules/@kbn/shared-ux-card-no-data-types/index.d.ts", "deprecated": false, @@ -176,21 +176,21 @@ "\nProps for the `NoDataCard` sevice-connected component." ], "signature": [ - "{ children?: React.ReactNode; onError?: React.ReactEventHandler | undefined; className?: string | undefined; id?: string | undefined; lang?: string | undefined; style?: React.CSSProperties | undefined; target?: string | undefined; role?: React.AriaRole | undefined; tabIndex?: number | undefined; display?: \"warning\" | \"primary\" | \"success\" | \"accent\" | \"danger\" | \"subdued\" | \"transparent\" | \"plain\" | undefined; href?: string | undefined; 'aria-activedescendant'?: string | undefined; 'aria-atomic'?: boolean | \"true\" | \"false\" | undefined; 'aria-autocomplete'?: \"none\" | \"list\" | \"inline\" | \"both\" | undefined; 'aria-busy'?: boolean | \"true\" | \"false\" | undefined; 'aria-checked'?: boolean | \"true\" | \"false\" | \"mixed\" | undefined; 'aria-colcount'?: number | undefined; 'aria-colindex'?: number | undefined; 'aria-colspan'?: number | undefined; 'aria-controls'?: string | undefined; 'aria-current'?: boolean | \"date\" | \"location\" | \"true\" | \"false\" | \"page\" | \"step\" | \"time\" | undefined; 'aria-describedby'?: string | undefined; 'aria-details'?: string | undefined; 'aria-disabled'?: boolean | \"true\" | \"false\" | undefined; 'aria-dropeffect'?: \"none\" | \"link\" | \"copy\" | \"execute\" | \"move\" | \"popup\" | undefined; 'aria-errormessage'?: string | undefined; 'aria-expanded'?: boolean | \"true\" | \"false\" | undefined; 'aria-flowto'?: string | undefined; 'aria-grabbed'?: boolean | \"true\" | \"false\" | undefined; 'aria-haspopup'?: boolean | \"dialog\" | \"grid\" | \"listbox\" | \"menu\" | \"tree\" | \"true\" | \"false\" | undefined; 'aria-hidden'?: boolean | \"true\" | \"false\" | undefined; 'aria-invalid'?: boolean | \"true\" | \"false\" | \"grammar\" | \"spelling\" | undefined; 'aria-keyshortcuts'?: string | undefined; 'aria-label'?: string | undefined; 'aria-labelledby'?: string | undefined; 'aria-level'?: number | undefined; 'aria-live'?: \"off\" | \"assertive\" | \"polite\" | undefined; 'aria-modal'?: boolean | \"true\" | \"false\" | undefined; 'aria-multiline'?: boolean | \"true\" | \"false\" | undefined; 'aria-multiselectable'?: boolean | \"true\" | \"false\" | undefined; 'aria-orientation'?: \"horizontal\" | \"vertical\" | undefined; 'aria-owns'?: string | undefined; 'aria-placeholder'?: string | undefined; 'aria-posinset'?: number | undefined; 'aria-pressed'?: boolean | \"true\" | \"false\" | \"mixed\" | undefined; 'aria-readonly'?: boolean | \"true\" | \"false\" | undefined; 'aria-relevant'?: \"all\" | \"text\" | \"additions\" | \"additions removals\" | \"additions text\" | \"removals\" | \"removals additions\" | \"removals text\" | \"text additions\" | \"text removals\" | undefined; 'aria-required'?: boolean | \"true\" | \"false\" | undefined; 'aria-roledescription'?: string | undefined; 'aria-rowcount'?: number | undefined; 'aria-rowindex'?: number | undefined; 'aria-rowspan'?: number | undefined; 'aria-selected'?: boolean | \"true\" | \"false\" | undefined; 'aria-setsize'?: number | undefined; 'aria-sort'?: \"none\" | \"ascending\" | \"descending\" | \"other\" | undefined; 'aria-valuemax'?: number | undefined; 'aria-valuemin'?: number | undefined; 'aria-valuenow'?: number | undefined; 'aria-valuetext'?: string | undefined; dangerouslySetInnerHTML?: { __html: string; } | undefined; onCopy?: React.ClipboardEventHandler | undefined; onCopyCapture?: React.ClipboardEventHandler | undefined; onCut?: React.ClipboardEventHandler | undefined; onCutCapture?: React.ClipboardEventHandler | undefined; onPaste?: React.ClipboardEventHandler | undefined; onPasteCapture?: React.ClipboardEventHandler | undefined; onCompositionEnd?: React.CompositionEventHandler | undefined; onCompositionEndCapture?: React.CompositionEventHandler | undefined; onCompositionStart?: React.CompositionEventHandler | undefined; onCompositionStartCapture?: React.CompositionEventHandler | undefined; onCompositionUpdate?: React.CompositionEventHandler | undefined; onCompositionUpdateCapture?: React.CompositionEventHandler | undefined; onFocus?: React.FocusEventHandler | undefined; onFocusCapture?: React.FocusEventHandler | undefined; onBlur?: React.FocusEventHandler | undefined; onBlurCapture?: React.FocusEventHandler | undefined; onChange?: React.FormEventHandler | undefined; onChangeCapture?: React.FormEventHandler | undefined; onBeforeInput?: React.FormEventHandler | undefined; onBeforeInputCapture?: React.FormEventHandler | undefined; onInput?: React.FormEventHandler | undefined; onInputCapture?: React.FormEventHandler | undefined; onReset?: React.FormEventHandler | undefined; onResetCapture?: React.FormEventHandler | undefined; onSubmit?: React.FormEventHandler | undefined; onSubmitCapture?: React.FormEventHandler | undefined; onInvalid?: React.FormEventHandler | undefined; onInvalidCapture?: React.FormEventHandler | undefined; onLoad?: React.ReactEventHandler | undefined; onLoadCapture?: React.ReactEventHandler | undefined; onErrorCapture?: React.ReactEventHandler | undefined; onKeyDown?: React.KeyboardEventHandler | undefined; onKeyDownCapture?: React.KeyboardEventHandler | undefined; onKeyPress?: React.KeyboardEventHandler | undefined; onKeyPressCapture?: React.KeyboardEventHandler | undefined; onKeyUp?: React.KeyboardEventHandler | undefined; onKeyUpCapture?: React.KeyboardEventHandler | undefined; onAbort?: React.ReactEventHandler | undefined; onAbortCapture?: React.ReactEventHandler | undefined; onCanPlay?: React.ReactEventHandler | undefined; onCanPlayCapture?: React.ReactEventHandler | undefined; onCanPlayThrough?: React.ReactEventHandler | undefined; onCanPlayThroughCapture?: React.ReactEventHandler | undefined; onDurationChange?: React.ReactEventHandler | undefined; onDurationChangeCapture?: React.ReactEventHandler | undefined; onEmptied?: React.ReactEventHandler | undefined; onEmptiedCapture?: React.ReactEventHandler | undefined; onEncrypted?: React.ReactEventHandler | undefined; onEncryptedCapture?: React.ReactEventHandler | undefined; onEnded?: React.ReactEventHandler | undefined; onEndedCapture?: React.ReactEventHandler | undefined; onLoadedData?: React.ReactEventHandler | undefined; onLoadedDataCapture?: React.ReactEventHandler | undefined; onLoadedMetadata?: React.ReactEventHandler | undefined; onLoadedMetadataCapture?: React.ReactEventHandler | undefined; onLoadStart?: React.ReactEventHandler | undefined; onLoadStartCapture?: React.ReactEventHandler | undefined; onPause?: React.ReactEventHandler | undefined; onPauseCapture?: React.ReactEventHandler | undefined; onPlay?: React.ReactEventHandler | undefined; onPlayCapture?: React.ReactEventHandler | undefined; onPlaying?: React.ReactEventHandler | undefined; onPlayingCapture?: React.ReactEventHandler | undefined; onProgress?: React.ReactEventHandler | undefined; onProgressCapture?: React.ReactEventHandler | undefined; onRateChange?: React.ReactEventHandler | undefined; onRateChangeCapture?: React.ReactEventHandler | undefined; onSeeked?: React.ReactEventHandler | undefined; onSeekedCapture?: React.ReactEventHandler | undefined; onSeeking?: React.ReactEventHandler | undefined; onSeekingCapture?: React.ReactEventHandler | undefined; onStalled?: React.ReactEventHandler | undefined; onStalledCapture?: React.ReactEventHandler | undefined; onSuspend?: React.ReactEventHandler | undefined; onSuspendCapture?: React.ReactEventHandler | undefined; onTimeUpdate?: React.ReactEventHandler | undefined; onTimeUpdateCapture?: React.ReactEventHandler | undefined; onVolumeChange?: React.ReactEventHandler | undefined; onVolumeChangeCapture?: React.ReactEventHandler | undefined; onWaiting?: React.ReactEventHandler | undefined; onWaitingCapture?: React.ReactEventHandler | undefined; onAuxClick?: React.MouseEventHandler | undefined; onAuxClickCapture?: React.MouseEventHandler | undefined; onClick?: React.MouseEventHandler | undefined; onClickCapture?: React.MouseEventHandler | undefined; onContextMenu?: React.MouseEventHandler | undefined; onContextMenuCapture?: React.MouseEventHandler | undefined; onDoubleClick?: React.MouseEventHandler | undefined; onDoubleClickCapture?: React.MouseEventHandler | undefined; onDrag?: React.DragEventHandler | undefined; onDragCapture?: React.DragEventHandler | undefined; onDragEnd?: React.DragEventHandler | undefined; onDragEndCapture?: React.DragEventHandler | undefined; onDragEnter?: React.DragEventHandler | undefined; onDragEnterCapture?: React.DragEventHandler | undefined; onDragExit?: React.DragEventHandler | undefined; onDragExitCapture?: React.DragEventHandler | undefined; onDragLeave?: React.DragEventHandler | undefined; onDragLeaveCapture?: React.DragEventHandler | undefined; onDragOver?: React.DragEventHandler | undefined; onDragOverCapture?: React.DragEventHandler | undefined; onDragStart?: React.DragEventHandler | undefined; onDragStartCapture?: React.DragEventHandler | undefined; onDrop?: React.DragEventHandler | undefined; onDropCapture?: React.DragEventHandler | undefined; onMouseDown?: React.MouseEventHandler | undefined; onMouseDownCapture?: React.MouseEventHandler | undefined; onMouseEnter?: React.MouseEventHandler | undefined; onMouseLeave?: React.MouseEventHandler | undefined; onMouseMove?: React.MouseEventHandler | undefined; onMouseMoveCapture?: React.MouseEventHandler | undefined; onMouseOut?: React.MouseEventHandler | undefined; onMouseOutCapture?: React.MouseEventHandler | undefined; onMouseOver?: React.MouseEventHandler | undefined; onMouseOverCapture?: React.MouseEventHandler | undefined; onMouseUp?: React.MouseEventHandler | undefined; onMouseUpCapture?: React.MouseEventHandler | undefined; onSelect?: React.ReactEventHandler | undefined; onSelectCapture?: React.ReactEventHandler | undefined; onTouchCancel?: React.TouchEventHandler | undefined; onTouchCancelCapture?: React.TouchEventHandler | undefined; onTouchEnd?: React.TouchEventHandler | undefined; onTouchEndCapture?: React.TouchEventHandler | undefined; onTouchMove?: React.TouchEventHandler | undefined; onTouchMoveCapture?: React.TouchEventHandler | undefined; onTouchStart?: React.TouchEventHandler | undefined; onTouchStartCapture?: React.TouchEventHandler | undefined; onPointerDown?: React.PointerEventHandler | undefined; onPointerDownCapture?: React.PointerEventHandler | undefined; onPointerMove?: React.PointerEventHandler | undefined; onPointerMoveCapture?: React.PointerEventHandler | undefined; onPointerUp?: React.PointerEventHandler | undefined; onPointerUpCapture?: React.PointerEventHandler | undefined; onPointerCancel?: React.PointerEventHandler | undefined; onPointerCancelCapture?: React.PointerEventHandler | undefined; onPointerEnter?: React.PointerEventHandler | undefined; onPointerEnterCapture?: React.PointerEventHandler | undefined; onPointerLeave?: React.PointerEventHandler | undefined; onPointerLeaveCapture?: React.PointerEventHandler | undefined; onPointerOver?: React.PointerEventHandler | undefined; onPointerOverCapture?: React.PointerEventHandler | undefined; onPointerOut?: React.PointerEventHandler | undefined; onPointerOutCapture?: React.PointerEventHandler | undefined; onGotPointerCapture?: React.PointerEventHandler | undefined; onGotPointerCaptureCapture?: React.PointerEventHandler | undefined; onLostPointerCapture?: React.PointerEventHandler | undefined; onLostPointerCaptureCapture?: React.PointerEventHandler | undefined; onScroll?: React.UIEventHandler | undefined; onScrollCapture?: React.UIEventHandler | undefined; onWheel?: React.WheelEventHandler | undefined; onWheelCapture?: React.WheelEventHandler | undefined; onAnimationStart?: React.AnimationEventHandler | undefined; onAnimationStartCapture?: React.AnimationEventHandler | undefined; onAnimationEnd?: React.AnimationEventHandler | undefined; onAnimationEndCapture?: React.AnimationEventHandler | undefined; onAnimationIteration?: React.AnimationEventHandler | undefined; onAnimationIterationCapture?: React.AnimationEventHandler | undefined; onTransitionEnd?: React.TransitionEventHandler | undefined; onTransitionEndCapture?: React.TransitionEventHandler | undefined; 'data-test-subj'?: string | undefined; title?: boolean | React.ReactChild | React.ReactFragment | React.ReactPortal | undefined; button?: React.ReactNode; hidden?: boolean | undefined; icon?: React.ReactElement<", + "{ children?: React.ReactNode; onError?: React.ReactEventHandler | undefined; hidden?: boolean | undefined; icon?: React.ReactElement<", "EuiIconProps", - ", string | React.JSXElementConstructor> | null | undefined; image?: string | React.ReactElement> | undefined; description?: React.ReactNode; security?: string | undefined; defaultValue?: string | number | readonly string[] | undefined; category?: string | undefined; defaultChecked?: boolean | undefined; suppressContentEditableWarning?: boolean | undefined; suppressHydrationWarning?: boolean | undefined; accessKey?: string | undefined; contentEditable?: \"inherit\" | Booleanish | undefined; contextMenu?: string | undefined; dir?: string | undefined; draggable?: Booleanish | undefined; placeholder?: string | undefined; slot?: string | undefined; spellCheck?: Booleanish | undefined; translate?: \"no\" | \"yes\" | undefined; radioGroup?: string | undefined; about?: string | undefined; datatype?: string | undefined; inlist?: any; prefix?: string | undefined; property?: string | undefined; resource?: string | undefined; typeof?: string | undefined; vocab?: string | undefined; autoCapitalize?: string | undefined; autoCorrect?: string | undefined; autoSave?: string | undefined; itemProp?: string | undefined; itemScope?: boolean | undefined; itemType?: string | undefined; itemID?: string | undefined; itemRef?: string | undefined; results?: number | undefined; unselectable?: \"off\" | \"on\" | undefined; inputMode?: \"none\" | \"text\" | \"search\" | \"email\" | \"tel\" | \"url\" | \"numeric\" | \"decimal\" | undefined; is?: string | undefined; rel?: string | undefined; paddingSize?: \"none\" | \"s\" | \"m\" | \"l\" | \"xl\" | \"xs\" | undefined; footer?: React.ReactNode; hasBorder?: boolean | undefined; textAlign?: CardAlignment | undefined; titleElement?: \"h2\" | \"h3\" | \"h4\" | \"h5\" | \"h6\" | \"span\" | undefined; titleSize?: \"s\" | \"xs\" | undefined; betaBadgeProps?: Partial<(", + ", string | React.JSXElementConstructor> | null | undefined; image?: string | React.ReactElement> | undefined; className?: string | undefined; title?: boolean | React.ReactChild | React.ReactFragment | React.ReactPortal | undefined; onChange?: React.FormEventHandler | undefined; onKeyDown?: React.KeyboardEventHandler | undefined; onClick?: React.MouseEventHandler | undefined; id?: string | undefined; description?: React.ReactNode; security?: string | undefined; defaultValue?: string | number | readonly string[] | undefined; lang?: string | undefined; category?: string | undefined; defaultChecked?: boolean | undefined; suppressContentEditableWarning?: boolean | undefined; suppressHydrationWarning?: boolean | undefined; accessKey?: string | undefined; contentEditable?: \"inherit\" | Booleanish | undefined; contextMenu?: string | undefined; dir?: string | undefined; draggable?: Booleanish | undefined; placeholder?: string | undefined; slot?: string | undefined; spellCheck?: Booleanish | undefined; style?: React.CSSProperties | undefined; tabIndex?: number | undefined; translate?: \"no\" | \"yes\" | undefined; radioGroup?: string | undefined; role?: React.AriaRole | undefined; about?: string | undefined; datatype?: string | undefined; inlist?: any; prefix?: string | undefined; property?: string | undefined; resource?: string | undefined; typeof?: string | undefined; vocab?: string | undefined; autoCapitalize?: string | undefined; autoCorrect?: string | undefined; autoSave?: string | undefined; itemProp?: string | undefined; itemScope?: boolean | undefined; itemType?: string | undefined; itemID?: string | undefined; itemRef?: string | undefined; results?: number | undefined; unselectable?: \"on\" | \"off\" | undefined; inputMode?: \"none\" | \"email\" | \"search\" | \"text\" | \"tel\" | \"url\" | \"numeric\" | \"decimal\" | undefined; is?: string | undefined; 'aria-activedescendant'?: string | undefined; 'aria-atomic'?: Booleanish | undefined; 'aria-autocomplete'?: \"none\" | \"list\" | \"inline\" | \"both\" | undefined; 'aria-busy'?: Booleanish | undefined; 'aria-checked'?: boolean | \"mixed\" | \"false\" | \"true\" | undefined; 'aria-colcount'?: number | undefined; 'aria-colindex'?: number | undefined; 'aria-colspan'?: number | undefined; 'aria-controls'?: string | undefined; 'aria-current'?: boolean | \"date\" | \"location\" | \"time\" | \"page\" | \"false\" | \"true\" | \"step\" | undefined; 'aria-describedby'?: string | undefined; 'aria-details'?: string | undefined; 'aria-disabled'?: Booleanish | undefined; 'aria-dropeffect'?: \"none\" | \"copy\" | \"link\" | \"execute\" | \"move\" | \"popup\" | undefined; 'aria-errormessage'?: string | undefined; 'aria-expanded'?: Booleanish | undefined; 'aria-flowto'?: string | undefined; 'aria-grabbed'?: Booleanish | undefined; 'aria-haspopup'?: boolean | \"grid\" | \"menu\" | \"false\" | \"true\" | \"dialog\" | \"listbox\" | \"tree\" | undefined; 'aria-hidden'?: Booleanish | undefined; 'aria-invalid'?: boolean | \"false\" | \"true\" | \"grammar\" | \"spelling\" | undefined; 'aria-keyshortcuts'?: string | undefined; 'aria-label'?: string | undefined; 'aria-labelledby'?: string | undefined; 'aria-level'?: number | undefined; 'aria-live'?: \"off\" | \"assertive\" | \"polite\" | undefined; 'aria-modal'?: Booleanish | undefined; 'aria-multiline'?: Booleanish | undefined; 'aria-multiselectable'?: Booleanish | undefined; 'aria-orientation'?: \"horizontal\" | \"vertical\" | undefined; 'aria-owns'?: string | undefined; 'aria-placeholder'?: string | undefined; 'aria-posinset'?: number | undefined; 'aria-pressed'?: boolean | \"mixed\" | \"false\" | \"true\" | undefined; 'aria-readonly'?: Booleanish | undefined; 'aria-relevant'?: \"all\" | \"text\" | \"additions\" | \"additions removals\" | \"additions text\" | \"removals\" | \"removals additions\" | \"removals text\" | \"text additions\" | \"text removals\" | undefined; 'aria-required'?: Booleanish | undefined; 'aria-roledescription'?: string | undefined; 'aria-rowcount'?: number | undefined; 'aria-rowindex'?: number | undefined; 'aria-rowspan'?: number | undefined; 'aria-selected'?: Booleanish | undefined; 'aria-setsize'?: number | undefined; 'aria-sort'?: \"none\" | \"other\" | \"ascending\" | \"descending\" | undefined; 'aria-valuemax'?: number | undefined; 'aria-valuemin'?: number | undefined; 'aria-valuenow'?: number | undefined; 'aria-valuetext'?: string | undefined; dangerouslySetInnerHTML?: { __html: string; } | undefined; onCopy?: React.ClipboardEventHandler | undefined; onCopyCapture?: React.ClipboardEventHandler | undefined; onCut?: React.ClipboardEventHandler | undefined; onCutCapture?: React.ClipboardEventHandler | undefined; onPaste?: React.ClipboardEventHandler | undefined; onPasteCapture?: React.ClipboardEventHandler | undefined; onCompositionEnd?: React.CompositionEventHandler | undefined; onCompositionEndCapture?: React.CompositionEventHandler | undefined; onCompositionStart?: React.CompositionEventHandler | undefined; onCompositionStartCapture?: React.CompositionEventHandler | undefined; onCompositionUpdate?: React.CompositionEventHandler | undefined; onCompositionUpdateCapture?: React.CompositionEventHandler | undefined; onFocus?: React.FocusEventHandler | undefined; onFocusCapture?: React.FocusEventHandler | undefined; onBlur?: React.FocusEventHandler | undefined; onBlurCapture?: React.FocusEventHandler | undefined; onChangeCapture?: React.FormEventHandler | undefined; onBeforeInput?: React.FormEventHandler | undefined; onBeforeInputCapture?: React.FormEventHandler | undefined; onInput?: React.FormEventHandler | undefined; onInputCapture?: React.FormEventHandler | undefined; onReset?: React.FormEventHandler | undefined; onResetCapture?: React.FormEventHandler | undefined; onSubmit?: React.FormEventHandler | undefined; onSubmitCapture?: React.FormEventHandler | undefined; onInvalid?: React.FormEventHandler | undefined; onInvalidCapture?: React.FormEventHandler | undefined; onLoad?: React.ReactEventHandler | undefined; onLoadCapture?: React.ReactEventHandler | undefined; onErrorCapture?: React.ReactEventHandler | undefined; onKeyDownCapture?: React.KeyboardEventHandler | undefined; onKeyPress?: React.KeyboardEventHandler | undefined; onKeyPressCapture?: React.KeyboardEventHandler | undefined; onKeyUp?: React.KeyboardEventHandler | undefined; onKeyUpCapture?: React.KeyboardEventHandler | undefined; onAbort?: React.ReactEventHandler | undefined; onAbortCapture?: React.ReactEventHandler | undefined; onCanPlay?: React.ReactEventHandler | undefined; onCanPlayCapture?: React.ReactEventHandler | undefined; onCanPlayThrough?: React.ReactEventHandler | undefined; onCanPlayThroughCapture?: React.ReactEventHandler | undefined; onDurationChange?: React.ReactEventHandler | undefined; onDurationChangeCapture?: React.ReactEventHandler | undefined; onEmptied?: React.ReactEventHandler | undefined; onEmptiedCapture?: React.ReactEventHandler | undefined; onEncrypted?: React.ReactEventHandler | undefined; onEncryptedCapture?: React.ReactEventHandler | undefined; onEnded?: React.ReactEventHandler | undefined; onEndedCapture?: React.ReactEventHandler | undefined; onLoadedData?: React.ReactEventHandler | undefined; onLoadedDataCapture?: React.ReactEventHandler | undefined; onLoadedMetadata?: React.ReactEventHandler | undefined; onLoadedMetadataCapture?: React.ReactEventHandler | undefined; onLoadStart?: React.ReactEventHandler | undefined; onLoadStartCapture?: React.ReactEventHandler | undefined; onPause?: React.ReactEventHandler | undefined; onPauseCapture?: React.ReactEventHandler | undefined; onPlay?: React.ReactEventHandler | undefined; onPlayCapture?: React.ReactEventHandler | undefined; onPlaying?: React.ReactEventHandler | undefined; onPlayingCapture?: React.ReactEventHandler | undefined; onProgress?: React.ReactEventHandler | undefined; onProgressCapture?: React.ReactEventHandler | undefined; onRateChange?: React.ReactEventHandler | undefined; onRateChangeCapture?: React.ReactEventHandler | undefined; onSeeked?: React.ReactEventHandler | undefined; onSeekedCapture?: React.ReactEventHandler | undefined; onSeeking?: React.ReactEventHandler | undefined; onSeekingCapture?: React.ReactEventHandler | undefined; onStalled?: React.ReactEventHandler | undefined; onStalledCapture?: React.ReactEventHandler | undefined; onSuspend?: React.ReactEventHandler | undefined; onSuspendCapture?: React.ReactEventHandler | undefined; onTimeUpdate?: React.ReactEventHandler | undefined; onTimeUpdateCapture?: React.ReactEventHandler | undefined; onVolumeChange?: React.ReactEventHandler | undefined; onVolumeChangeCapture?: React.ReactEventHandler | undefined; onWaiting?: React.ReactEventHandler | undefined; onWaitingCapture?: React.ReactEventHandler | undefined; onAuxClick?: React.MouseEventHandler | undefined; onAuxClickCapture?: React.MouseEventHandler | undefined; onClickCapture?: React.MouseEventHandler | undefined; onContextMenu?: React.MouseEventHandler | undefined; onContextMenuCapture?: React.MouseEventHandler | undefined; onDoubleClick?: React.MouseEventHandler | undefined; onDoubleClickCapture?: React.MouseEventHandler | undefined; onDrag?: React.DragEventHandler | undefined; onDragCapture?: React.DragEventHandler | undefined; onDragEnd?: React.DragEventHandler | undefined; onDragEndCapture?: React.DragEventHandler | undefined; onDragEnter?: React.DragEventHandler | undefined; onDragEnterCapture?: React.DragEventHandler | undefined; onDragExit?: React.DragEventHandler | undefined; onDragExitCapture?: React.DragEventHandler | undefined; onDragLeave?: React.DragEventHandler | undefined; onDragLeaveCapture?: React.DragEventHandler | undefined; onDragOver?: React.DragEventHandler | undefined; onDragOverCapture?: React.DragEventHandler | undefined; onDragStart?: React.DragEventHandler | undefined; onDragStartCapture?: React.DragEventHandler | undefined; onDrop?: React.DragEventHandler | undefined; onDropCapture?: React.DragEventHandler | undefined; onMouseDown?: React.MouseEventHandler | undefined; onMouseDownCapture?: React.MouseEventHandler | undefined; onMouseEnter?: React.MouseEventHandler | undefined; onMouseLeave?: React.MouseEventHandler | undefined; onMouseMove?: React.MouseEventHandler | undefined; onMouseMoveCapture?: React.MouseEventHandler | undefined; onMouseOut?: React.MouseEventHandler | undefined; onMouseOutCapture?: React.MouseEventHandler | undefined; onMouseOver?: React.MouseEventHandler | undefined; onMouseOverCapture?: React.MouseEventHandler | undefined; onMouseUp?: React.MouseEventHandler | undefined; onMouseUpCapture?: React.MouseEventHandler | undefined; onSelect?: React.ReactEventHandler | undefined; onSelectCapture?: React.ReactEventHandler | undefined; onTouchCancel?: React.TouchEventHandler | undefined; onTouchCancelCapture?: React.TouchEventHandler | undefined; onTouchEnd?: React.TouchEventHandler | undefined; onTouchEndCapture?: React.TouchEventHandler | undefined; onTouchMove?: React.TouchEventHandler | undefined; onTouchMoveCapture?: React.TouchEventHandler | undefined; onTouchStart?: React.TouchEventHandler | undefined; onTouchStartCapture?: React.TouchEventHandler | undefined; onPointerDown?: React.PointerEventHandler | undefined; onPointerDownCapture?: React.PointerEventHandler | undefined; onPointerMove?: React.PointerEventHandler | undefined; onPointerMoveCapture?: React.PointerEventHandler | undefined; onPointerUp?: React.PointerEventHandler | undefined; onPointerUpCapture?: React.PointerEventHandler | undefined; onPointerCancel?: React.PointerEventHandler | undefined; onPointerCancelCapture?: React.PointerEventHandler | undefined; onPointerEnter?: React.PointerEventHandler | undefined; onPointerEnterCapture?: React.PointerEventHandler | undefined; onPointerLeave?: React.PointerEventHandler | undefined; onPointerLeaveCapture?: React.PointerEventHandler | undefined; onPointerOver?: React.PointerEventHandler | undefined; onPointerOverCapture?: React.PointerEventHandler | undefined; onPointerOut?: React.PointerEventHandler | undefined; onPointerOutCapture?: React.PointerEventHandler | undefined; onGotPointerCapture?: React.PointerEventHandler | undefined; onGotPointerCaptureCapture?: React.PointerEventHandler | undefined; onLostPointerCapture?: React.PointerEventHandler | undefined; onLostPointerCaptureCapture?: React.PointerEventHandler | undefined; onScroll?: React.UIEventHandler | undefined; onScrollCapture?: React.UIEventHandler | undefined; onWheel?: React.WheelEventHandler | undefined; onWheelCapture?: React.WheelEventHandler | undefined; onAnimationStart?: React.AnimationEventHandler | undefined; onAnimationStartCapture?: React.AnimationEventHandler | undefined; onAnimationEnd?: React.AnimationEventHandler | undefined; onAnimationEndCapture?: React.AnimationEventHandler | undefined; onAnimationIteration?: React.AnimationEventHandler | undefined; onAnimationIterationCapture?: React.AnimationEventHandler | undefined; onTransitionEnd?: React.TransitionEventHandler | undefined; onTransitionEndCapture?: React.TransitionEventHandler | undefined; 'data-test-subj'?: string | undefined; href?: string | undefined; rel?: string | undefined; target?: string | undefined; paddingSize?: \"none\" | \"m\" | \"s\" | \"xs\" | \"l\" | \"xl\" | undefined; button?: React.ReactNode; footer?: React.ReactNode; hasBorder?: boolean | undefined; textAlign?: CardAlignment | undefined; titleElement?: \"h2\" | \"h3\" | \"h4\" | \"h5\" | \"h6\" | \"span\" | undefined; titleSize?: \"s\" | \"xs\" | undefined; betaBadgeProps?: Partial<(", "CommonProps", " & ", "DisambiguateSet", "<(", "DisambiguateSet", - " & { href: string; target?: string | undefined; rel?: string | undefined; } & Omit, \"color\" | \"href\" | \"onClick\">) | (", + " & { href: string; target?: string | undefined; rel?: string | undefined; } & Omit, \"color\" | \"onClick\" | \"href\">) | (", "DisambiguateSet", " & { onClick?: React.MouseEventHandler | undefined; onClickAriaLabel?: string | undefined; } & Omit, \"color\" | \"onClick\">), WithSpanProps> & WithSpanProps & { iconType?: ", "IconType", " | undefined; label: React.ReactNode; tooltipContent?: React.ReactNode; tooltipPosition?: ", "ToolTipPositions", - " | undefined; title?: string | undefined; color?: \"accent\" | \"subdued\" | \"hollow\" | undefined; size?: ", + " | undefined; title?: string | undefined; color?: \"subdued\" | \"accent\" | \"hollow\" | undefined; size?: ", "BetaBadgeSize", " | undefined; } & ", "DisambiguateSet", @@ -200,13 +200,13 @@ "DisambiguateSet", "<(", "DisambiguateSet", - " & { href: string; target?: string | undefined; rel?: string | undefined; } & Omit, \"color\" | \"href\" | \"onClick\">) | (", + " & { href: string; target?: string | undefined; rel?: string | undefined; } & Omit, \"color\" | \"onClick\" | \"href\">) | (", "DisambiguateSet", " & { onClick?: React.MouseEventHandler | undefined; onClickAriaLabel?: string | undefined; } & Omit, \"color\" | \"onClick\">), WithSpanProps> & WithSpanProps & { iconType?: ", "IconType", " | undefined; label: React.ReactNode; tooltipContent?: React.ReactNode; tooltipPosition?: ", "ToolTipPositions", - " | undefined; title?: string | undefined; color?: \"accent\" | \"subdued\" | \"hollow\" | undefined; size?: ", + " | undefined; title?: string | undefined; color?: \"subdued\" | \"accent\" | \"hollow\" | undefined; size?: ", "BetaBadgeSize", " | undefined; } & ", "DisambiguateSet", @@ -218,15 +218,15 @@ "DisambiguateSet", " & { href: string; target?: string | undefined; rel?: string | undefined; } & Omit, \"color\" | \"href\" | \"onClick\">) | (", + " & { href: string; target?: string | undefined; rel?: string | undefined; } & Omit, \"color\" | \"onClick\" | \"href\">) | (", "DisambiguateSet", " & { onClick?: React.MouseEventHandler | undefined; onClickAriaLabel?: string | undefined; } & Omit, \"color\" | \"onClick\">)> & ", "DisambiguateSet", - " & { href: string; target?: string | undefined; rel?: string | undefined; } & Omit, \"color\" | \"href\" | \"onClick\"> & { iconType?: ", + " & { href: string; target?: string | undefined; rel?: string | undefined; } & Omit, \"color\" | \"onClick\" | \"href\"> & { iconType?: ", "IconType", " | undefined; label: React.ReactNode; tooltipContent?: React.ReactNode; tooltipPosition?: ", "ToolTipPositions", - " | undefined; title?: string | undefined; color?: \"accent\" | \"subdued\" | \"hollow\" | undefined; size?: ", + " | undefined; title?: string | undefined; color?: \"subdued\" | \"accent\" | \"hollow\" | undefined; size?: ", "BetaBadgeSize", " | undefined; } & ", "DisambiguateSet", @@ -236,15 +236,15 @@ "DisambiguateSet", " & { href: string; target?: string | undefined; rel?: string | undefined; } & Omit, \"color\" | \"href\" | \"onClick\">) | (", + " & { href: string; target?: string | undefined; rel?: string | undefined; } & Omit, \"color\" | \"onClick\" | \"href\">) | (", "DisambiguateSet", " & { onClick?: React.MouseEventHandler | undefined; onClickAriaLabel?: string | undefined; } & Omit, \"color\" | \"onClick\">)> & ", "DisambiguateSet", - " & { href: string; target?: string | undefined; rel?: string | undefined; } & Omit, \"color\" | \"href\" | \"onClick\"> & { iconType?: ", + " & { href: string; target?: string | undefined; rel?: string | undefined; } & Omit, \"color\" | \"onClick\" | \"href\"> & { iconType?: ", "IconType", " | undefined; label: React.ReactNode; tooltipContent?: React.ReactNode; tooltipPosition?: ", "ToolTipPositions", - " | undefined; title?: string | undefined; color?: \"accent\" | \"subdued\" | \"hollow\" | undefined; size?: ", + " | undefined; title?: string | undefined; color?: \"subdued\" | \"accent\" | \"hollow\" | undefined; size?: ", "BetaBadgeSize", " | undefined; } & ", "DisambiguateSet", @@ -256,15 +256,15 @@ "DisambiguateSet", " & { href: string; target?: string | undefined; rel?: string | undefined; } & Omit, \"color\" | \"href\" | \"onClick\">) | (", + " & { href: string; target?: string | undefined; rel?: string | undefined; } & Omit, \"color\" | \"onClick\" | \"href\">) | (", "DisambiguateSet", " & { onClick?: React.MouseEventHandler | undefined; onClickAriaLabel?: string | undefined; } & Omit, \"color\" | \"onClick\">)> & ", "DisambiguateSet", - " & { href: string; target?: string | undefined; rel?: string | undefined; } & Omit, \"color\" | \"href\" | \"onClick\"> & { iconType?: ", + " & { href: string; target?: string | undefined; rel?: string | undefined; } & Omit, \"color\" | \"onClick\" | \"href\"> & { iconType?: ", "IconType", " | undefined; label: React.ReactNode; tooltipContent?: React.ReactNode; tooltipPosition?: ", "ToolTipPositions", - " | undefined; title?: string | undefined; color?: \"accent\" | \"subdued\" | \"hollow\" | undefined; size?: ", + " | undefined; title?: string | undefined; color?: \"subdued\" | \"accent\" | \"hollow\" | undefined; size?: ", "BetaBadgeSize", " | undefined; } & ", "DisambiguateSet", @@ -276,7 +276,7 @@ "DisambiguateSet", " & { href: string; target?: string | undefined; rel?: string | undefined; } & Omit, \"color\" | \"href\" | \"onClick\">) | (", + " & { href: string; target?: string | undefined; rel?: string | undefined; } & Omit, \"color\" | \"onClick\" | \"href\">) | (", "DisambiguateSet", " & { onClick?: React.MouseEventHandler | undefined; onClickAriaLabel?: string | undefined; } & Omit, \"color\" | \"onClick\">)> & ", "DisambiguateSet", @@ -284,7 +284,7 @@ "IconType", " | undefined; label: React.ReactNode; tooltipContent?: React.ReactNode; tooltipPosition?: ", "ToolTipPositions", - " | undefined; title?: string | undefined; color?: \"accent\" | \"subdued\" | \"hollow\" | undefined; size?: ", + " | undefined; title?: string | undefined; color?: \"subdued\" | \"accent\" | \"hollow\" | undefined; size?: ", "BetaBadgeSize", " | undefined; } & ", "DisambiguateSet", @@ -294,7 +294,7 @@ "DisambiguateSet", " & { href: string; target?: string | undefined; rel?: string | undefined; } & Omit, \"color\" | \"href\" | \"onClick\">) | (", + " & { href: string; target?: string | undefined; rel?: string | undefined; } & Omit, \"color\" | \"onClick\" | \"href\">) | (", "DisambiguateSet", " & { onClick?: React.MouseEventHandler | undefined; onClickAriaLabel?: string | undefined; } & Omit, \"color\" | \"onClick\">)> & ", "DisambiguateSet", @@ -302,7 +302,7 @@ "IconType", " | undefined; label: React.ReactNode; tooltipContent?: React.ReactNode; tooltipPosition?: ", "ToolTipPositions", - " | undefined; title?: string | undefined; color?: \"accent\" | \"subdued\" | \"hollow\" | undefined; size?: ", + " | undefined; title?: string | undefined; color?: \"subdued\" | \"accent\" | \"hollow\" | undefined; size?: ", "BetaBadgeSize", " | undefined; } & ", "DisambiguateSet", @@ -314,7 +314,7 @@ "DisambiguateSet", " & { href: string; target?: string | undefined; rel?: string | undefined; } & Omit, \"color\" | \"href\" | \"onClick\">) | (", + " & { href: string; target?: string | undefined; rel?: string | undefined; } & Omit, \"color\" | \"onClick\" | \"href\">) | (", "DisambiguateSet", " & { onClick?: React.MouseEventHandler | undefined; onClickAriaLabel?: string | undefined; } & Omit, \"color\" | \"onClick\">)> & ", "DisambiguateSet", @@ -322,13 +322,13 @@ "IconType", " | undefined; label: React.ReactNode; tooltipContent?: React.ReactNode; tooltipPosition?: ", "ToolTipPositions", - " | undefined; title?: string | undefined; color?: \"accent\" | \"subdued\" | \"hollow\" | undefined; size?: ", + " | undefined; title?: string | undefined; color?: \"subdued\" | \"accent\" | \"hollow\" | undefined; size?: ", "BetaBadgeSize", " | undefined; } & ", "DisambiguateSet", " & ", "DisambiguateSet", - "<{ tooltipContent: React.ReactNode; title?: string | undefined; }, { title: string; tooltipContent?: React.ReactNode; }> & { title: string; tooltipContent?: React.ReactNode; } & { label: React.ReactNode; })> | undefined; selectable?: ", + "<{ tooltipContent: React.ReactNode; title?: string | undefined; }, { title: string; tooltipContent?: React.ReactNode; }> & { title: string; tooltipContent?: React.ReactNode; } & { label: React.ReactNode; })> | undefined; display?: \"warning\" | \"subdued\" | \"primary\" | \"accent\" | \"success\" | \"danger\" | \"transparent\" | \"plain\" | undefined; selectable?: ", "EuiCardSelectProps", " | undefined; }" ], diff --git a/api_docs/kbn_shared_ux_card_no_data.mdx b/api_docs/kbn_shared_ux_card_no_data.mdx index 4dcbcd085f4941..3ef0cbb768595b 100644 --- a/api_docs/kbn_shared_ux_card_no_data.mdx +++ b/api_docs/kbn_shared_ux_card_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-card-no-data title: "@kbn/shared-ux-card-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-card-no-data plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-card-no-data'] --- import kbnSharedUxCardNoDataObj from './kbn_shared_ux_card_no_data.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_card_no_data_mocks.devdocs.json b/api_docs/kbn_shared_ux_card_no_data_mocks.devdocs.json index c3f38d680e2088..9be1d1c11795da 100644 --- a/api_docs/kbn_shared_ux_card_no_data_mocks.devdocs.json +++ b/api_docs/kbn_shared_ux_card_no_data_mocks.devdocs.json @@ -9,10 +9,18 @@ "objects": [] }, "server": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "common": { "classes": [ { "parentPluginId": "@kbn/shared-ux-card-no-data-mocks", - "id": "def-server.StorybookMock", + "id": "def-common.StorybookMock", "type": "Class", "tags": [], "label": "StorybookMock", @@ -22,9 +30,9 @@ "signature": [ { "pluginId": "@kbn/shared-ux-card-no-data-mocks", - "scope": "server", + "scope": "common", "docId": "kibKbnSharedUxCardNoDataMocksPluginApi", - "section": "def-server.StorybookMock", + "section": "def-common.StorybookMock", "text": "StorybookMock" }, " extends ", @@ -40,7 +48,7 @@ "children": [ { "parentPluginId": "@kbn/shared-ux-card-no-data-mocks", - "id": "def-server.StorybookMock.propArguments", + "id": "def-common.StorybookMock.propArguments", "type": "Object", "tags": [], "label": "propArguments", @@ -50,7 +58,7 @@ "children": [ { "parentPluginId": "@kbn/shared-ux-card-no-data-mocks", - "id": "def-server.StorybookMock.propArguments.category", + "id": "def-common.StorybookMock.propArguments.category", "type": "Object", "tags": [], "label": "category", @@ -60,7 +68,7 @@ "children": [ { "parentPluginId": "@kbn/shared-ux-card-no-data-mocks", - "id": "def-server.StorybookMock.propArguments.category.control", + "id": "def-common.StorybookMock.propArguments.category.control", "type": "Object", "tags": [], "label": "control", @@ -70,7 +78,7 @@ "children": [ { "parentPluginId": "@kbn/shared-ux-card-no-data-mocks", - "id": "def-server.StorybookMock.propArguments.category.control.type", + "id": "def-common.StorybookMock.propArguments.category.control.type", "type": "string", "tags": [], "label": "type", @@ -82,7 +90,7 @@ }, { "parentPluginId": "@kbn/shared-ux-card-no-data-mocks", - "id": "def-server.StorybookMock.propArguments.category.defaultValue", + "id": "def-common.StorybookMock.propArguments.category.defaultValue", "type": "string", "tags": [], "label": "defaultValue", @@ -94,7 +102,7 @@ }, { "parentPluginId": "@kbn/shared-ux-card-no-data-mocks", - "id": "def-server.StorybookMock.propArguments.title", + "id": "def-common.StorybookMock.propArguments.title", "type": "Object", "tags": [], "label": "title", @@ -104,7 +112,7 @@ "children": [ { "parentPluginId": "@kbn/shared-ux-card-no-data-mocks", - "id": "def-server.StorybookMock.propArguments.title.control", + "id": "def-common.StorybookMock.propArguments.title.control", "type": "Object", "tags": [], "label": "control", @@ -114,7 +122,7 @@ "children": [ { "parentPluginId": "@kbn/shared-ux-card-no-data-mocks", - "id": "def-server.StorybookMock.propArguments.title.control.type", + "id": "def-common.StorybookMock.propArguments.title.control.type", "type": "string", "tags": [], "label": "type", @@ -126,7 +134,7 @@ }, { "parentPluginId": "@kbn/shared-ux-card-no-data-mocks", - "id": "def-server.StorybookMock.propArguments.title.defaultValue", + "id": "def-common.StorybookMock.propArguments.title.defaultValue", "type": "string", "tags": [], "label": "defaultValue", @@ -138,7 +146,7 @@ }, { "parentPluginId": "@kbn/shared-ux-card-no-data-mocks", - "id": "def-server.StorybookMock.propArguments.description", + "id": "def-common.StorybookMock.propArguments.description", "type": "Object", "tags": [], "label": "description", @@ -148,7 +156,7 @@ "children": [ { "parentPluginId": "@kbn/shared-ux-card-no-data-mocks", - "id": "def-server.StorybookMock.propArguments.description.control", + "id": "def-common.StorybookMock.propArguments.description.control", "type": "Object", "tags": [], "label": "control", @@ -158,7 +166,7 @@ "children": [ { "parentPluginId": "@kbn/shared-ux-card-no-data-mocks", - "id": "def-server.StorybookMock.propArguments.description.control.type", + "id": "def-common.StorybookMock.propArguments.description.control.type", "type": "string", "tags": [], "label": "type", @@ -170,7 +178,7 @@ }, { "parentPluginId": "@kbn/shared-ux-card-no-data-mocks", - "id": "def-server.StorybookMock.propArguments.description.defaultValue", + "id": "def-common.StorybookMock.propArguments.description.defaultValue", "type": "string", "tags": [], "label": "defaultValue", @@ -182,7 +190,7 @@ }, { "parentPluginId": "@kbn/shared-ux-card-no-data-mocks", - "id": "def-server.StorybookMock.propArguments.button", + "id": "def-common.StorybookMock.propArguments.button", "type": "Object", "tags": [], "label": "button", @@ -192,7 +200,7 @@ "children": [ { "parentPluginId": "@kbn/shared-ux-card-no-data-mocks", - "id": "def-server.StorybookMock.propArguments.button.control", + "id": "def-common.StorybookMock.propArguments.button.control", "type": "Object", "tags": [], "label": "control", @@ -202,7 +210,7 @@ "children": [ { "parentPluginId": "@kbn/shared-ux-card-no-data-mocks", - "id": "def-server.StorybookMock.propArguments.button.control.type", + "id": "def-common.StorybookMock.propArguments.button.control.type", "type": "string", "tags": [], "label": "type", @@ -214,7 +222,7 @@ }, { "parentPluginId": "@kbn/shared-ux-card-no-data-mocks", - "id": "def-server.StorybookMock.propArguments.button.defaultValue", + "id": "def-common.StorybookMock.propArguments.button.defaultValue", "type": "string", "tags": [], "label": "defaultValue", @@ -228,7 +236,7 @@ }, { "parentPluginId": "@kbn/shared-ux-card-no-data-mocks", - "id": "def-server.StorybookMock.serviceArguments", + "id": "def-common.StorybookMock.serviceArguments", "type": "Object", "tags": [], "label": "serviceArguments", @@ -238,7 +246,7 @@ "children": [ { "parentPluginId": "@kbn/shared-ux-card-no-data-mocks", - "id": "def-server.StorybookMock.serviceArguments.canAccessFleet", + "id": "def-common.StorybookMock.serviceArguments.canAccessFleet", "type": "Object", "tags": [], "label": "canAccessFleet", @@ -248,7 +256,7 @@ "children": [ { "parentPluginId": "@kbn/shared-ux-card-no-data-mocks", - "id": "def-server.StorybookMock.serviceArguments.canAccessFleet.control", + "id": "def-common.StorybookMock.serviceArguments.canAccessFleet.control", "type": "string", "tags": [], "label": "control", @@ -258,7 +266,7 @@ }, { "parentPluginId": "@kbn/shared-ux-card-no-data-mocks", - "id": "def-server.StorybookMock.serviceArguments.canAccessFleet.defaultValue", + "id": "def-common.StorybookMock.serviceArguments.canAccessFleet.defaultValue", "type": "boolean", "tags": [], "label": "defaultValue", @@ -272,7 +280,7 @@ }, { "parentPluginId": "@kbn/shared-ux-card-no-data-mocks", - "id": "def-server.StorybookMock.dependencies", + "id": "def-common.StorybookMock.dependencies", "type": "Array", "tags": [], "label": "dependencies", @@ -286,7 +294,7 @@ }, { "parentPluginId": "@kbn/shared-ux-card-no-data-mocks", - "id": "def-server.StorybookMock.getProps", + "id": "def-common.StorybookMock.getProps", "type": "Function", "tags": [], "label": "getProps", @@ -295,9 +303,9 @@ "(params?: ", { "pluginId": "@kbn/shared-ux-card-no-data-mocks", - "scope": "server", + "scope": "common", "docId": "kibKbnSharedUxCardNoDataMocksPluginApi", - "section": "def-server.Params", + "section": "def-common.Params", "text": "Params" }, " | undefined) => ", @@ -308,7 +316,7 @@ "children": [ { "parentPluginId": "@kbn/shared-ux-card-no-data-mocks", - "id": "def-server.StorybookMock.getProps.$1", + "id": "def-common.StorybookMock.getProps.$1", "type": "Object", "tags": [], "label": "params", @@ -316,9 +324,9 @@ "signature": [ { "pluginId": "@kbn/shared-ux-card-no-data-mocks", - "scope": "server", + "scope": "common", "docId": "kibKbnSharedUxCardNoDataMocksPluginApi", - "section": "def-server.Params", + "section": "def-common.Params", "text": "Params" }, " | undefined" @@ -332,7 +340,7 @@ }, { "parentPluginId": "@kbn/shared-ux-card-no-data-mocks", - "id": "def-server.StorybookMock.getServices", + "id": "def-common.StorybookMock.getServices", "type": "Function", "tags": [], "label": "getServices", @@ -341,9 +349,9 @@ "(params: ", { "pluginId": "@kbn/shared-ux-card-no-data-mocks", - "scope": "server", + "scope": "common", "docId": "kibKbnSharedUxCardNoDataMocksPluginApi", - "section": "def-server.Params", + "section": "def-common.Params", "text": "Params" }, ") => ", @@ -354,7 +362,7 @@ "children": [ { "parentPluginId": "@kbn/shared-ux-card-no-data-mocks", - "id": "def-server.StorybookMock.getServices.$1", + "id": "def-common.StorybookMock.getServices.$1", "type": "Object", "tags": [], "label": "params", @@ -362,9 +370,9 @@ "signature": [ { "pluginId": "@kbn/shared-ux-card-no-data-mocks", - "scope": "server", + "scope": "common", "docId": "kibKbnSharedUxCardNoDataMocksPluginApi", - "section": "def-server.Params", + "section": "def-common.Params", "text": "Params" } ], @@ -382,7 +390,7 @@ "functions": [ { "parentPluginId": "@kbn/shared-ux-card-no-data-mocks", - "id": "def-server.getKibanaDependenciesMock", + "id": "def-common.getKibanaDependenciesMock", "type": "Function", "tags": [], "label": "getKibanaDependenciesMock", @@ -400,7 +408,7 @@ "children": [ { "parentPluginId": "@kbn/shared-ux-card-no-data-mocks", - "id": "def-server.getKibanaDependenciesMock.$1", + "id": "def-common.getKibanaDependenciesMock.$1", "type": "Object", "tags": [], "label": "params", @@ -420,7 +428,7 @@ }, { "parentPluginId": "@kbn/shared-ux-card-no-data-mocks", - "id": "def-server.getServicesMock", + "id": "def-common.getServicesMock", "type": "Function", "tags": [], "label": "getServicesMock", @@ -438,7 +446,7 @@ "children": [ { "parentPluginId": "@kbn/shared-ux-card-no-data-mocks", - "id": "def-server.getServicesMock.$1", + "id": "def-common.getServicesMock.$1", "type": "Object", "tags": [], "label": "params", @@ -462,7 +470,7 @@ "misc": [ { "parentPluginId": "@kbn/shared-ux-card-no-data-mocks", - "id": "def-server.Params", + "id": "def-common.Params", "type": "Type", "tags": [], "label": "Params", @@ -470,7 +478,7 @@ "\nStorybook parameters provided from the controls addon." ], "signature": [ - "{ title: any; button: any; description: any; category: any; canAccessFleet: any; }" + "{ title: any; description: any; category: any; button: any; canAccessFleet: any; }" ], "path": "packages/shared-ux/card/no_data/mocks/src/storybook.ts", "deprecated": false, @@ -478,13 +486,5 @@ } ], "objects": [] - }, - "common": { - "classes": [], - "functions": [], - "interfaces": [], - "enums": [], - "misc": [], - "objects": [] } } \ No newline at end of file diff --git a/api_docs/kbn_shared_ux_card_no_data_mocks.mdx b/api_docs/kbn_shared_ux_card_no_data_mocks.mdx index c8f7dbc5eccda8..37fe6794ddffdd 100644 --- a/api_docs/kbn_shared_ux_card_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_card_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-card-no-data-mocks title: "@kbn/shared-ux-card-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-card-no-data-mocks plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-card-no-data-mocks'] --- import kbnSharedUxCardNoDataMocksObj from './kbn_shared_ux_card_no_data_mocks.devdocs.json'; @@ -23,14 +23,14 @@ Contact [Owner missing] for questions regarding this plugin. |-------------------|-----------|------------------------|-----------------| | 32 | 0 | 28 | 0 | -## Server +## Common ### Functions - + ### Classes - + ### Consts, variables and types - + diff --git a/api_docs/kbn_shared_ux_components.devdocs.json b/api_docs/kbn_shared_ux_components.devdocs.json deleted file mode 100644 index 48342694fc62eb..00000000000000 --- a/api_docs/kbn_shared_ux_components.devdocs.json +++ /dev/null @@ -1,257 +0,0 @@ -{ - "id": "@kbn/shared-ux-components", - "client": { - "classes": [], - "functions": [], - "interfaces": [], - "enums": [], - "misc": [], - "objects": [] - }, - "server": { - "classes": [], - "functions": [], - "interfaces": [], - "enums": [], - "misc": [], - "objects": [] - }, - "common": { - "classes": [], - "functions": [ - { - "parentPluginId": "@kbn/shared-ux-components", - "id": "def-common.KibanaPageTemplate", - "type": "Function", - "tags": [], - "label": "KibanaPageTemplate", - "description": [], - "signature": [ - "({ template, className, children, solutionNav, noDataConfig, ...rest }: React.PropsWithChildren<", - { - "pluginId": "@kbn/shared-ux-components", - "scope": "common", - "docId": "kibKbnSharedUxComponentsPluginApi", - "section": "def-common.KibanaPageTemplateProps", - "text": "KibanaPageTemplateProps" - }, - ">) => JSX.Element" - ], - "path": "packages/kbn-shared-ux-components/src/page_template/page_template.tsx", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/shared-ux-components", - "id": "def-common.KibanaPageTemplate.$1", - "type": "CompoundType", - "tags": [], - "label": "{\n template,\n className,\n children,\n solutionNav,\n noDataConfig,\n ...rest\n}", - "description": [], - "signature": [ - "React.PropsWithChildren<", - { - "pluginId": "@kbn/shared-ux-components", - "scope": "common", - "docId": "kibKbnSharedUxComponentsPluginApi", - "section": "def-common.KibanaPageTemplateProps", - "text": "KibanaPageTemplateProps" - }, - ">" - ], - "path": "packages/kbn-shared-ux-components/src/page_template/page_template.tsx", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [], - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/shared-ux-components", - "id": "def-common.NoDataConfigPage", - "type": "Function", - "tags": [], - "label": "NoDataConfigPage", - "description": [], - "signature": [ - "(props: ", - { - "pluginId": "@kbn/shared-ux-components", - "scope": "common", - "docId": "kibKbnSharedUxComponentsPluginApi", - "section": "def-common.KibanaPageTemplateProps", - "text": "KibanaPageTemplateProps" - }, - ") => JSX.Element | null" - ], - "path": "packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_config_page/no_data_config_page.tsx", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/shared-ux-components", - "id": "def-common.NoDataConfigPage.$1", - "type": "CompoundType", - "tags": [], - "label": "props", - "description": [], - "signature": [ - { - "pluginId": "@kbn/shared-ux-components", - "scope": "common", - "docId": "kibKbnSharedUxComponentsPluginApi", - "section": "def-common.KibanaPageTemplateProps", - "text": "KibanaPageTemplateProps" - } - ], - "path": "packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_config_page/no_data_config_page.tsx", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [], - "initialIsOpen": false - } - ], - "interfaces": [ - { - "parentPluginId": "@kbn/shared-ux-components", - "id": "def-common.NoDataPageProps", - "type": "Interface", - "tags": [], - "label": "NoDataPageProps", - "description": [], - "signature": [ - { - "pluginId": "@kbn/shared-ux-components", - "scope": "common", - "docId": "kibKbnSharedUxComponentsPluginApi", - "section": "def-common.NoDataPageProps", - "text": "NoDataPageProps" - }, - " extends ", - "CommonProps" - ], - "path": "packages/kbn-shared-ux-components/src/page_template/no_data_page/types.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/shared-ux-components", - "id": "def-common.NoDataPageProps.solution", - "type": "string", - "tags": [], - "label": "solution", - "description": [ - "\nSingle name for the current solution, used to auto-generate the title, logo, description, and button label" - ], - "path": "packages/kbn-shared-ux-components/src/page_template/no_data_page/types.ts", - "deprecated": false - }, - { - "parentPluginId": "@kbn/shared-ux-components", - "id": "def-common.NoDataPageProps.logo", - "type": "string", - "tags": [], - "label": "logo", - "description": [ - "\nOptionally replace the auto-generated logo" - ], - "signature": [ - "string | undefined" - ], - "path": "packages/kbn-shared-ux-components/src/page_template/no_data_page/types.ts", - "deprecated": false - }, - { - "parentPluginId": "@kbn/shared-ux-components", - "id": "def-common.NoDataPageProps.docsLink", - "type": "string", - "tags": [], - "label": "docsLink", - "description": [ - "\nRequired to set the docs link for the whole solution" - ], - "path": "packages/kbn-shared-ux-components/src/page_template/no_data_page/types.ts", - "deprecated": false - }, - { - "parentPluginId": "@kbn/shared-ux-components", - "id": "def-common.NoDataPageProps.pageTitle", - "type": "string", - "tags": [], - "label": "pageTitle", - "description": [ - "\nOptionally replace the auto-generated page title (h1)" - ], - "signature": [ - "string | undefined" - ], - "path": "packages/kbn-shared-ux-components/src/page_template/no_data_page/types.ts", - "deprecated": false - }, - { - "parentPluginId": "@kbn/shared-ux-components", - "id": "def-common.NoDataPageProps.action", - "type": "Object", - "tags": [], - "label": "action", - "description": [ - "\nAn object of `NoDataPageActions`.\nUse `elasticAgent` as the primary key for pre-configured cards of this type.\nOtherwise use a custom key that contains `EuiCard` props." - ], - "signature": [ - "{ [x: string]: ", - "NoDataCardProps", - "; }" - ], - "path": "packages/kbn-shared-ux-components/src/page_template/no_data_page/types.ts", - "deprecated": false - } - ], - "initialIsOpen": false - } - ], - "enums": [], - "misc": [ - { - "parentPluginId": "@kbn/shared-ux-components", - "id": "def-common.KibanaPageTemplateProps", - "type": "Type", - "tags": [], - "label": "KibanaPageTemplateProps", - "description": [], - "signature": [ - "Omit<", - "EuiPageProps", - ", \"paddingSize\"> & { template?: \"default\" | \"empty\" | \"centeredBody\" | \"centeredContent\" | undefined; paddingSize?: \"none\" | \"s\" | \"m\" | \"l\" | undefined; pageSideBar?: React.ReactNode; pageSideBarProps?: ", - "EuiPageSideBarProps", - " | undefined; pageHeader?: ", - "EuiPageHeaderProps", - " | undefined; pageBodyProps?: ", - "EuiPageBodyProps", - "<\"main\"> | undefined; pageContentProps?: ", - "EuiPageContentProps", - " | undefined; pageContentBodyProps?: ", - "EuiPageContentBodyProps", - " | undefined; bottomBar?: React.ReactNode; bottomBarProps?: ", - "EuiBottomBarProps", - " | undefined; fullHeight?: boolean | \"noscroll\" | undefined; minHeight?: ", - "Property", - ".MinHeight | undefined; } & { isEmptyState?: boolean | undefined; solutionNav?: ", - "SolutionNavProps", - " | undefined; noDataConfig?: ", - { - "pluginId": "@kbn/shared-ux-components", - "scope": "common", - "docId": "kibKbnSharedUxComponentsPluginApi", - "section": "def-common.NoDataPageProps", - "text": "NoDataPageProps" - }, - " | undefined; }" - ], - "path": "packages/kbn-shared-ux-components/src/page_template/types.ts", - "deprecated": false, - "initialIsOpen": false - } - ], - "objects": [] - } -} \ No newline at end of file diff --git a/api_docs/kbn_shared_ux_link_redirect_app_mocks.devdocs.json b/api_docs/kbn_shared_ux_link_redirect_app_mocks.devdocs.json index dded2ace4c3a28..64dc76155d1129 100644 --- a/api_docs/kbn_shared_ux_link_redirect_app_mocks.devdocs.json +++ b/api_docs/kbn_shared_ux_link_redirect_app_mocks.devdocs.json @@ -9,10 +9,18 @@ "objects": [] }, "server": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "common": { "classes": [ { "parentPluginId": "@kbn/shared-ux-link-redirect-app-mocks", - "id": "def-server.StorybookMock", + "id": "def-common.StorybookMock", "type": "Class", "tags": [], "label": "StorybookMock", @@ -20,9 +28,9 @@ "signature": [ { "pluginId": "@kbn/shared-ux-link-redirect-app-mocks", - "scope": "server", + "scope": "common", "docId": "kibKbnSharedUxLinkRedirectAppMocksPluginApi", - "section": "def-server.StorybookMock", + "section": "def-common.StorybookMock", "text": "StorybookMock" }, " extends ", @@ -36,7 +44,7 @@ "children": [ { "parentPluginId": "@kbn/shared-ux-link-redirect-app-mocks", - "id": "def-server.StorybookMock.propArguments", + "id": "def-common.StorybookMock.propArguments", "type": "Object", "tags": [], "label": "propArguments", @@ -47,7 +55,7 @@ }, { "parentPluginId": "@kbn/shared-ux-link-redirect-app-mocks", - "id": "def-server.StorybookMock.serviceArguments", + "id": "def-common.StorybookMock.serviceArguments", "type": "Object", "tags": [], "label": "serviceArguments", @@ -58,7 +66,7 @@ }, { "parentPluginId": "@kbn/shared-ux-link-redirect-app-mocks", - "id": "def-server.StorybookMock.dependencies", + "id": "def-common.StorybookMock.dependencies", "type": "Array", "tags": [], "label": "dependencies", @@ -71,7 +79,7 @@ }, { "parentPluginId": "@kbn/shared-ux-link-redirect-app-mocks", - "id": "def-server.StorybookMock.getProps", + "id": "def-common.StorybookMock.getProps", "type": "Function", "tags": [], "label": "getProps", @@ -88,7 +96,7 @@ }, { "parentPluginId": "@kbn/shared-ux-link-redirect-app-mocks", - "id": "def-server.StorybookMock.getServices", + "id": "def-common.StorybookMock.getServices", "type": "Function", "tags": [], "label": "getServices", @@ -110,24 +118,39 @@ "functions": [ { "parentPluginId": "@kbn/shared-ux-link-redirect-app-mocks", - "id": "def-server.getRedirectAppLinksKibanaDependenciesMock", + "id": "def-common.getRedirectAppLinksKibanaDependenciesMock", "type": "Function", "tags": [], "label": "getRedirectAppLinksKibanaDependenciesMock", "description": [], "signature": [ - "() => ", + "(params?: Partial | undefined) => ", "RedirectAppLinksKibanaDependencies" ], "path": "packages/shared-ux/link/redirect_app/mocks/src/jest.ts", "deprecated": false, - "children": [], + "children": [ + { + "parentPluginId": "@kbn/shared-ux-link-redirect-app-mocks", + "id": "def-common.getRedirectAppLinksKibanaDependenciesMock.$1", + "type": "Object", + "tags": [], + "label": "params", + "description": [], + "signature": [ + "Partial | undefined" + ], + "path": "packages/shared-ux/link/redirect_app/mocks/src/jest.ts", + "deprecated": false, + "isRequired": false + } + ], "returnComment": [], "initialIsOpen": false }, { "parentPluginId": "@kbn/shared-ux-link-redirect-app-mocks", - "id": "def-server.getRedirectAppLinksServicesMock", + "id": "def-common.getRedirectAppLinksServicesMock", "type": "Function", "tags": [], "label": "getRedirectAppLinksServicesMock", @@ -135,12 +158,27 @@ "\nReturns the Jest-compatible service abstractions for the `NoDataCard` Provider." ], "signature": [ - "() => ", + "(params?: Partial | undefined) => ", "RedirectAppLinksServices" ], "path": "packages/shared-ux/link/redirect_app/mocks/src/jest.ts", "deprecated": false, - "children": [], + "children": [ + { + "parentPluginId": "@kbn/shared-ux-link-redirect-app-mocks", + "id": "def-common.getRedirectAppLinksServicesMock.$1", + "type": "Object", + "tags": [], + "label": "params", + "description": [], + "signature": [ + "Partial | undefined" + ], + "path": "packages/shared-ux/link/redirect_app/mocks/src/jest.ts", + "deprecated": false, + "isRequired": false + } + ], "returnComment": [], "initialIsOpen": false } @@ -149,13 +187,5 @@ "enums": [], "misc": [], "objects": [] - }, - "common": { - "classes": [], - "functions": [], - "interfaces": [], - "enums": [], - "misc": [], - "objects": [] } } \ No newline at end of file diff --git a/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx b/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx index 72602d2764696a..cf9245d4f7726b 100644 --- a/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx +++ b/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-link-redirect-app-mocks title: "@kbn/shared-ux-link-redirect-app-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-link-redirect-app-mocks plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-link-redirect-app-mocks'] --- import kbnSharedUxLinkRedirectAppMocksObj from './kbn_shared_ux_link_redirect_app_mocks.devdocs.json'; @@ -21,13 +21,13 @@ Contact [Owner missing] for questions regarding this plugin. | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 8 | 0 | 7 | 0 | +| 10 | 0 | 9 | 0 | -## Server +## Common ### Functions - + ### Classes - + diff --git a/api_docs/kbn_shared_ux_page_analytics_no_data.devdocs.json b/api_docs/kbn_shared_ux_page_analytics_no_data.devdocs.json index ed6fbf24bf21fc..3f1e5a7afa8950 100644 --- a/api_docs/kbn_shared_ux_page_analytics_no_data.devdocs.json +++ b/api_docs/kbn_shared_ux_page_analytics_no_data.devdocs.json @@ -227,7 +227,13 @@ "signature": [ "KibanaDependencies", " & ", - "KibanaNoDataPageKibanaDependencies" + "KibanaDependencies", + " & ", + "NoDataViewsPromptKibanaDependencies", + " & ", + "KibanaDependencies", + " & ", + "RedirectAppLinksKibanaDependencies" ], "path": "node_modules/@kbn/shared-ux-page-analytics-no-data-types/index.d.ts", "deprecated": false, @@ -245,7 +251,13 @@ "signature": [ "Services", " & ", - "KibanaNoDataPageServices" + "Services", + " & ", + "Services", + " & ", + "RedirectAppLinksServices", + " & ", + "NoDataViewsPromptServices" ], "path": "node_modules/@kbn/shared-ux-page-analytics-no-data-types/index.d.ts", "deprecated": false, diff --git a/api_docs/kbn_shared_ux_page_analytics_no_data.mdx b/api_docs/kbn_shared_ux_page_analytics_no_data.mdx index 7853a1a8d0345f..8b871b70c5da49 100644 --- a/api_docs/kbn_shared_ux_page_analytics_no_data.mdx +++ b/api_docs/kbn_shared_ux_page_analytics_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-analytics-no-data title: "@kbn/shared-ux-page-analytics-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-analytics-no-data plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-analytics-no-data'] --- import kbnSharedUxPageAnalyticsNoDataObj from './kbn_shared_ux_page_analytics_no_data.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.devdocs.json b/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.devdocs.json index 79c342c488de80..0ba419e7b51a08 100644 --- a/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.devdocs.json +++ b/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.devdocs.json @@ -9,10 +9,18 @@ "objects": [] }, "server": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "common": { "classes": [ { "parentPluginId": "@kbn/shared-ux-page-analytics-no-data-mocks", - "id": "def-server.StorybookMock", + "id": "def-common.StorybookMock", "type": "Class", "tags": [], "label": "StorybookMock", @@ -20,9 +28,9 @@ "signature": [ { "pluginId": "@kbn/shared-ux-page-analytics-no-data-mocks", - "scope": "server", + "scope": "common", "docId": "kibKbnSharedUxPageAnalyticsNoDataMocksPluginApi", - "section": "def-server.StorybookMock", + "section": "def-common.StorybookMock", "text": "StorybookMock" }, " extends ", @@ -38,7 +46,7 @@ "children": [ { "parentPluginId": "@kbn/shared-ux-page-analytics-no-data-mocks", - "id": "def-server.StorybookMock.propArguments", + "id": "def-common.StorybookMock.propArguments", "type": "Object", "tags": [], "label": "propArguments", @@ -49,7 +57,7 @@ }, { "parentPluginId": "@kbn/shared-ux-page-analytics-no-data-mocks", - "id": "def-server.StorybookMock.serviceArguments", + "id": "def-common.StorybookMock.serviceArguments", "type": "Object", "tags": [], "label": "serviceArguments", @@ -59,7 +67,7 @@ "children": [ { "parentPluginId": "@kbn/shared-ux-page-analytics-no-data-mocks", - "id": "def-server.StorybookMock.serviceArguments.kibanaGuideDocLink", + "id": "def-common.StorybookMock.serviceArguments.kibanaGuideDocLink", "type": "Object", "tags": [], "label": "kibanaGuideDocLink", @@ -69,7 +77,7 @@ "children": [ { "parentPluginId": "@kbn/shared-ux-page-analytics-no-data-mocks", - "id": "def-server.StorybookMock.serviceArguments.kibanaGuideDocLink.control", + "id": "def-common.StorybookMock.serviceArguments.kibanaGuideDocLink.control", "type": "string", "tags": [], "label": "control", @@ -79,7 +87,7 @@ }, { "parentPluginId": "@kbn/shared-ux-page-analytics-no-data-mocks", - "id": "def-server.StorybookMock.serviceArguments.kibanaGuideDocLink.defaultValue", + "id": "def-common.StorybookMock.serviceArguments.kibanaGuideDocLink.defaultValue", "type": "string", "tags": [], "label": "defaultValue", @@ -93,7 +101,7 @@ }, { "parentPluginId": "@kbn/shared-ux-page-analytics-no-data-mocks", - "id": "def-server.StorybookMock.dependencies", + "id": "def-common.StorybookMock.dependencies", "type": "Array", "tags": [], "label": "dependencies", @@ -107,7 +115,7 @@ }, { "parentPluginId": "@kbn/shared-ux-page-analytics-no-data-mocks", - "id": "def-server.StorybookMock.getServices", + "id": "def-common.StorybookMock.getServices", "type": "Function", "tags": [], "label": "getServices", @@ -116,9 +124,9 @@ "(params: ", { "pluginId": "@kbn/shared-ux-page-analytics-no-data-mocks", - "scope": "server", + "scope": "common", "docId": "kibKbnSharedUxPageAnalyticsNoDataMocksPluginApi", - "section": "def-server.Params", + "section": "def-common.Params", "text": "Params" }, ") => ", @@ -129,7 +137,7 @@ "children": [ { "parentPluginId": "@kbn/shared-ux-page-analytics-no-data-mocks", - "id": "def-server.StorybookMock.getServices.$1", + "id": "def-common.StorybookMock.getServices.$1", "type": "CompoundType", "tags": [], "label": "params", @@ -137,9 +145,9 @@ "signature": [ { "pluginId": "@kbn/shared-ux-page-analytics-no-data-mocks", - "scope": "server", + "scope": "common", "docId": "kibKbnSharedUxPageAnalyticsNoDataMocksPluginApi", - "section": "def-server.Params", + "section": "def-common.Params", "text": "Params" } ], @@ -152,7 +160,7 @@ }, { "parentPluginId": "@kbn/shared-ux-page-analytics-no-data-mocks", - "id": "def-server.StorybookMock.getProps", + "id": "def-common.StorybookMock.getProps", "type": "Function", "tags": [], "label": "getProps", @@ -174,7 +182,7 @@ "functions": [ { "parentPluginId": "@kbn/shared-ux-page-analytics-no-data-mocks", - "id": "def-server.getServicesMock", + "id": "def-common.getServicesMock", "type": "Function", "tags": [], "label": "getServicesMock", @@ -195,7 +203,7 @@ "misc": [ { "parentPluginId": "@kbn/shared-ux-page-analytics-no-data-mocks", - "id": "def-server.Params", + "id": "def-common.Params", "type": "Type", "tags": [], "label": "Params", @@ -219,13 +227,5 @@ } ], "objects": [] - }, - "common": { - "classes": [], - "functions": [], - "interfaces": [], - "enums": [], - "misc": [], - "objects": [] } } \ No newline at end of file diff --git a/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.mdx b/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.mdx index 23a72a1fafa66a..dab98daf684c46 100644 --- a/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-analytics-no-data-mocks title: "@kbn/shared-ux-page-analytics-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-analytics-no-data-mocks plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-analytics-no-data-mocks'] --- import kbnSharedUxPageAnalyticsNoDataMocksObj from './kbn_shared_ux_page_analytics_no_data_mocks.devdocs.json'; @@ -23,14 +23,14 @@ Contact [Owner missing] for questions regarding this plugin. |-------------------|-----------|------------------------|-----------------| | 12 | 0 | 12 | 0 | -## Server +## Common ### Functions - + ### Classes - + ### Consts, variables and types - + diff --git a/api_docs/kbn_shared_ux_page_kibana_no_data.devdocs.json b/api_docs/kbn_shared_ux_page_kibana_no_data.devdocs.json index edef04f7c1f13b..cd68f336f22172 100644 --- a/api_docs/kbn_shared_ux_page_kibana_no_data.devdocs.json +++ b/api_docs/kbn_shared_ux_page_kibana_no_data.devdocs.json @@ -129,316 +129,54 @@ "initialIsOpen": false } ], - "interfaces": [ + "interfaces": [], + "enums": [], + "misc": [ { "parentPluginId": "@kbn/shared-ux-page-kibana-no-data", "id": "def-common.KibanaNoDataPageKibanaDependencies", - "type": "Interface", + "type": "Type", "tags": [], "label": "KibanaNoDataPageKibanaDependencies", "description": [ "\nAn interface containing a collection of Kibana plugins and services required to\nrender this component and its dependencies." ], + "signature": [ + "KibanaDependencies", + " & ", + "NoDataViewsPromptKibanaDependencies", + " & ", + "KibanaDependencies", + " & ", + "RedirectAppLinksKibanaDependencies" + ], "path": "node_modules/@kbn/shared-ux-page-kibana-no-data-types/index.d.ts", "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/shared-ux-page-kibana-no-data", - "id": "def-common.KibanaNoDataPageKibanaDependencies.coreStart", - "type": "Object", - "tags": [], - "label": "coreStart", - "description": [], - "signature": [ - "{ application: { capabilities: { navLinks: Record; }; currentAppId$: ", - "Observable", - "; navigateToUrl: (url: string) => Promise; }; chrome: { setIsVisible: (isVisible: boolean) => void; }; docLinks: { links: { indexPatterns: { introduction: string; }; }; }; http: { basePath: { prepend: (url: string) => string; }; }; }" - ], - "path": "node_modules/@kbn/shared-ux-page-kibana-no-data-types/index.d.ts", - "deprecated": false - }, - { - "parentPluginId": "@kbn/shared-ux-page-kibana-no-data", - "id": "def-common.KibanaNoDataPageKibanaDependencies.dataViews", - "type": "Object", - "tags": [], - "label": "dataViews", - "description": [], - "signature": [ - "{ hasData: { hasDataView: () => Promise; hasESData: () => Promise; hasUserDataView: () => Promise; }; }" - ], - "path": "node_modules/@kbn/shared-ux-page-kibana-no-data-types/index.d.ts", - "deprecated": false - }, - { - "parentPluginId": "@kbn/shared-ux-page-kibana-no-data", - "id": "def-common.KibanaNoDataPageKibanaDependencies.dataViewEditor", - "type": "Object", - "tags": [], - "label": "dataViewEditor", - "description": [], - "signature": [ - "{ openEditor: (options: ", - "DataViewEditorOptions", - ") => () => void; userPermissions: { editDataView: () => boolean; }; }" - ], - "path": "node_modules/@kbn/shared-ux-page-kibana-no-data-types/index.d.ts", - "deprecated": false - } - ], "initialIsOpen": false }, { "parentPluginId": "@kbn/shared-ux-page-kibana-no-data", "id": "def-common.KibanaNoDataPageServices", - "type": "Interface", + "type": "Type", "tags": [], "label": "KibanaNoDataPageServices", "description": [ - "\nA list of Services that are consumed by this component.\n\nThis list is temporary, a stopgap as we migrate to a package-based architecture, where\nservices are not collected in a single package. In order to make the transition, this\ninterface is intentionally \"flat\".\n\nExpect this list to dwindle to zero as `@kbn/shared-ux-components` are migrated to their\nown packages, (and `@kbn/shared-ux-services` is removed)." + "\nA list of Services that are consumed by this component.." + ], + "signature": [ + "Services", + " & ", + "Services", + " & ", + "RedirectAppLinksServices", + " & ", + "NoDataViewsPromptServices" ], "path": "node_modules/@kbn/shared-ux-page-kibana-no-data-types/index.d.ts", "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/shared-ux-page-kibana-no-data", - "id": "def-common.KibanaNoDataPageServices.hasESData", - "type": "Function", - "tags": [], - "label": "hasESData", - "description": [ - "True if the cluster contains data, false otherwise." - ], - "signature": [ - "() => Promise" - ], - "path": "node_modules/@kbn/shared-ux-page-kibana-no-data-types/index.d.ts", - "deprecated": false, - "children": [], - "returnComment": [] - }, - { - "parentPluginId": "@kbn/shared-ux-page-kibana-no-data", - "id": "def-common.KibanaNoDataPageServices.hasUserDataView", - "type": "Function", - "tags": [], - "label": "hasUserDataView", - "description": [ - "True if Kibana instance contains user-created data view, false otherwise." - ], - "signature": [ - "() => Promise" - ], - "path": "node_modules/@kbn/shared-ux-page-kibana-no-data-types/index.d.ts", - "deprecated": false, - "children": [], - "returnComment": [] - }, - { - "parentPluginId": "@kbn/shared-ux-page-kibana-no-data", - "id": "def-common.KibanaNoDataPageServices.addBasePath", - "type": "Function", - "tags": [], - "label": "addBasePath", - "description": [ - "Append the server base path to a relative URL." - ], - "signature": [ - "(url: string) => string" - ], - "path": "node_modules/@kbn/shared-ux-page-kibana-no-data-types/index.d.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/shared-ux-page-kibana-no-data", - "id": "def-common.KibanaNoDataPageServices.addBasePath.$1", - "type": "string", - "tags": [], - "label": "url", - "description": [], - "signature": [ - "string" - ], - "path": "node_modules/@kbn/shared-ux-page-kibana-no-data-types/index.d.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [] - }, - { - "parentPluginId": "@kbn/shared-ux-page-kibana-no-data", - "id": "def-common.KibanaNoDataPageServices.canAccessFleet", - "type": "boolean", - "tags": [], - "label": "canAccessFleet", - "description": [ - "True if the user has permission to access Fleet, false otherwise." - ], - "path": "node_modules/@kbn/shared-ux-page-kibana-no-data-types/index.d.ts", - "deprecated": false - }, - { - "parentPluginId": "@kbn/shared-ux-page-kibana-no-data", - "id": "def-common.KibanaNoDataPageServices.canCreateNewDataView", - "type": "boolean", - "tags": [], - "label": "canCreateNewDataView", - "description": [ - "True if the user has permission to create a new Data View, false otherwise." - ], - "path": "node_modules/@kbn/shared-ux-page-kibana-no-data-types/index.d.ts", - "deprecated": false - }, - { - "parentPluginId": "@kbn/shared-ux-page-kibana-no-data", - "id": "def-common.KibanaNoDataPageServices.currentAppId$", - "type": "Object", - "tags": [], - "label": "currentAppId$", - "description": [ - "Observable storing the active, current application ID." - ], - "signature": [ - "Observable", - "" - ], - "path": "node_modules/@kbn/shared-ux-page-kibana-no-data-types/index.d.ts", - "deprecated": false - }, - { - "parentPluginId": "@kbn/shared-ux-page-kibana-no-data", - "id": "def-common.KibanaNoDataPageServices.dataViewsDocLink", - "type": "string", - "tags": [], - "label": "dataViewsDocLink", - "description": [ - "A link to information about Data Views in Kibana" - ], - "path": "node_modules/@kbn/shared-ux-page-kibana-no-data-types/index.d.ts", - "deprecated": false - }, - { - "parentPluginId": "@kbn/shared-ux-page-kibana-no-data", - "id": "def-common.KibanaNoDataPageServices.hasDataView", - "type": "Function", - "tags": [], - "label": "hasDataView", - "description": [ - "True if Kibana instance contains any data view, including system-created ones." - ], - "signature": [ - "() => Promise" - ], - "path": "node_modules/@kbn/shared-ux-page-kibana-no-data-types/index.d.ts", - "deprecated": false, - "children": [], - "returnComment": [] - }, - { - "parentPluginId": "@kbn/shared-ux-page-kibana-no-data", - "id": "def-common.KibanaNoDataPageServices.navigateToUrl", - "type": "Function", - "tags": [], - "label": "navigateToUrl", - "description": [ - "Use Kibana to navigate async to a different URL." - ], - "signature": [ - "(url: string) => void | Promise" - ], - "path": "node_modules/@kbn/shared-ux-page-kibana-no-data-types/index.d.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/shared-ux-page-kibana-no-data", - "id": "def-common.KibanaNoDataPageServices.navigateToUrl.$1", - "type": "string", - "tags": [], - "label": "url", - "description": [], - "signature": [ - "string" - ], - "path": "node_modules/@kbn/shared-ux-page-kibana-no-data-types/index.d.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [] - }, - { - "parentPluginId": "@kbn/shared-ux-page-kibana-no-data", - "id": "def-common.KibanaNoDataPageServices.openDataViewEditor", - "type": "Function", - "tags": [], - "label": "openDataViewEditor", - "description": [ - "A method to open the Data View Editor flow." - ], - "signature": [ - "(options: ", - "DataViewEditorOptions", - ") => () => void" - ], - "path": "node_modules/@kbn/shared-ux-page-kibana-no-data-types/index.d.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/shared-ux-page-kibana-no-data", - "id": "def-common.KibanaNoDataPageServices.openDataViewEditor.$1", - "type": "Object", - "tags": [], - "label": "options", - "description": [], - "signature": [ - "DataViewEditorOptions" - ], - "path": "node_modules/@kbn/shared-ux-page-kibana-no-data-types/index.d.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [] - }, - { - "parentPluginId": "@kbn/shared-ux-page-kibana-no-data", - "id": "def-common.KibanaNoDataPageServices.setIsFullscreen", - "type": "Function", - "tags": [], - "label": "setIsFullscreen", - "description": [ - "Set the Kibana chrome and browser to full screen mode." - ], - "signature": [ - "(isFullscreen: boolean) => void" - ], - "path": "node_modules/@kbn/shared-ux-page-kibana-no-data-types/index.d.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/shared-ux-page-kibana-no-data", - "id": "def-common.KibanaNoDataPageServices.setIsFullscreen.$1", - "type": "boolean", - "tags": [], - "label": "isFullscreen", - "description": [], - "signature": [ - "boolean" - ], - "path": "node_modules/@kbn/shared-ux-page-kibana-no-data-types/index.d.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [] - } - ], "initialIsOpen": false } ], - "enums": [], - "misc": [], "objects": [] } } \ No newline at end of file diff --git a/api_docs/kbn_shared_ux_page_kibana_no_data.mdx b/api_docs/kbn_shared_ux_page_kibana_no_data.mdx index 9f627bca5b87fc..eae6463fac44f4 100644 --- a/api_docs/kbn_shared_ux_page_kibana_no_data.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-no-data title: "@kbn/shared-ux-page-kibana-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-no-data plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-kibana-no-data'] --- import kbnSharedUxPageKibanaNoDataObj from './kbn_shared_ux_page_kibana_no_data.devdocs.json'; @@ -21,13 +21,13 @@ Contact [Owner missing] for questions regarding this plugin. | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 26 | 0 | 3 | 0 | +| 8 | 0 | 3 | 0 | ## Common ### Functions -### Interfaces - +### Consts, variables and types + diff --git a/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.devdocs.json b/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.devdocs.json index dee03e2ae609e0..e833987bc50689 100644 --- a/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.devdocs.json +++ b/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.devdocs.json @@ -9,10 +9,18 @@ "objects": [] }, "server": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "common": { "classes": [ { "parentPluginId": "@kbn/shared-ux-page-kibana-no-data-mocks", - "id": "def-server.StorybookMock", + "id": "def-common.StorybookMock", "type": "Class", "tags": [], "label": "StorybookMock", @@ -20,9 +28,9 @@ "signature": [ { "pluginId": "@kbn/shared-ux-page-kibana-no-data-mocks", - "scope": "server", + "scope": "common", "docId": "kibKbnSharedUxPageKibanaNoDataMocksPluginApi", - "section": "def-server.StorybookMock", + "section": "def-common.StorybookMock", "text": "StorybookMock" }, " extends ", @@ -38,7 +46,7 @@ "children": [ { "parentPluginId": "@kbn/shared-ux-page-kibana-no-data-mocks", - "id": "def-server.StorybookMock.propArguments", + "id": "def-common.StorybookMock.propArguments", "type": "Object", "tags": [], "label": "propArguments", @@ -48,7 +56,7 @@ "children": [ { "parentPluginId": "@kbn/shared-ux-page-kibana-no-data-mocks", - "id": "def-server.StorybookMock.propArguments.solution", + "id": "def-common.StorybookMock.propArguments.solution", "type": "Object", "tags": [], "label": "solution", @@ -58,7 +66,7 @@ "children": [ { "parentPluginId": "@kbn/shared-ux-page-kibana-no-data-mocks", - "id": "def-server.StorybookMock.propArguments.solution.control", + "id": "def-common.StorybookMock.propArguments.solution.control", "type": "string", "tags": [], "label": "control", @@ -68,7 +76,7 @@ }, { "parentPluginId": "@kbn/shared-ux-page-kibana-no-data-mocks", - "id": "def-server.StorybookMock.propArguments.solution.defaultValue", + "id": "def-common.StorybookMock.propArguments.solution.defaultValue", "type": "string", "tags": [], "label": "defaultValue", @@ -80,7 +88,7 @@ }, { "parentPluginId": "@kbn/shared-ux-page-kibana-no-data-mocks", - "id": "def-server.StorybookMock.propArguments.logo", + "id": "def-common.StorybookMock.propArguments.logo", "type": "Object", "tags": [], "label": "logo", @@ -90,7 +98,7 @@ "children": [ { "parentPluginId": "@kbn/shared-ux-page-kibana-no-data-mocks", - "id": "def-server.StorybookMock.propArguments.logo.control", + "id": "def-common.StorybookMock.propArguments.logo.control", "type": "Object", "tags": [], "label": "control", @@ -100,7 +108,7 @@ "children": [ { "parentPluginId": "@kbn/shared-ux-page-kibana-no-data-mocks", - "id": "def-server.StorybookMock.propArguments.logo.control.type", + "id": "def-common.StorybookMock.propArguments.logo.control.type", "type": "string", "tags": [], "label": "type", @@ -112,7 +120,7 @@ }, { "parentPluginId": "@kbn/shared-ux-page-kibana-no-data-mocks", - "id": "def-server.StorybookMock.propArguments.logo.options", + "id": "def-common.StorybookMock.propArguments.logo.options", "type": "Array", "tags": [], "label": "options", @@ -125,7 +133,7 @@ }, { "parentPluginId": "@kbn/shared-ux-page-kibana-no-data-mocks", - "id": "def-server.StorybookMock.propArguments.logo.defaultValue", + "id": "def-common.StorybookMock.propArguments.logo.defaultValue", "type": "Uncategorized", "tags": [], "label": "defaultValue", @@ -142,7 +150,7 @@ }, { "parentPluginId": "@kbn/shared-ux-page-kibana-no-data-mocks", - "id": "def-server.StorybookMock.serviceArguments", + "id": "def-common.StorybookMock.serviceArguments", "type": "Object", "tags": [], "label": "serviceArguments", @@ -152,7 +160,7 @@ "children": [ { "parentPluginId": "@kbn/shared-ux-page-kibana-no-data-mocks", - "id": "def-server.StorybookMock.serviceArguments.hasESData", + "id": "def-common.StorybookMock.serviceArguments.hasESData", "type": "Object", "tags": [], "label": "hasESData", @@ -162,7 +170,7 @@ "children": [ { "parentPluginId": "@kbn/shared-ux-page-kibana-no-data-mocks", - "id": "def-server.StorybookMock.serviceArguments.hasESData.control", + "id": "def-common.StorybookMock.serviceArguments.hasESData.control", "type": "string", "tags": [], "label": "control", @@ -172,7 +180,7 @@ }, { "parentPluginId": "@kbn/shared-ux-page-kibana-no-data-mocks", - "id": "def-server.StorybookMock.serviceArguments.hasESData.defaultValue", + "id": "def-common.StorybookMock.serviceArguments.hasESData.defaultValue", "type": "boolean", "tags": [], "label": "defaultValue", @@ -184,7 +192,7 @@ }, { "parentPluginId": "@kbn/shared-ux-page-kibana-no-data-mocks", - "id": "def-server.StorybookMock.serviceArguments.hasUserDataView", + "id": "def-common.StorybookMock.serviceArguments.hasUserDataView", "type": "Object", "tags": [], "label": "hasUserDataView", @@ -194,7 +202,7 @@ "children": [ { "parentPluginId": "@kbn/shared-ux-page-kibana-no-data-mocks", - "id": "def-server.StorybookMock.serviceArguments.hasUserDataView.control", + "id": "def-common.StorybookMock.serviceArguments.hasUserDataView.control", "type": "string", "tags": [], "label": "control", @@ -204,7 +212,7 @@ }, { "parentPluginId": "@kbn/shared-ux-page-kibana-no-data-mocks", - "id": "def-server.StorybookMock.serviceArguments.hasUserDataView.defaultValue", + "id": "def-common.StorybookMock.serviceArguments.hasUserDataView.defaultValue", "type": "boolean", "tags": [], "label": "defaultValue", @@ -218,7 +226,7 @@ }, { "parentPluginId": "@kbn/shared-ux-page-kibana-no-data-mocks", - "id": "def-server.StorybookMock.dependencies", + "id": "def-common.StorybookMock.dependencies", "type": "Array", "tags": [], "label": "dependencies", @@ -235,7 +243,7 @@ }, { "parentPluginId": "@kbn/shared-ux-page-kibana-no-data-mocks", - "id": "def-server.StorybookMock.getProps", + "id": "def-common.StorybookMock.getProps", "type": "Function", "tags": [], "label": "getProps", @@ -244,9 +252,9 @@ "(params: ", { "pluginId": "@kbn/shared-ux-page-kibana-no-data-mocks", - "scope": "server", + "scope": "common", "docId": "kibKbnSharedUxPageKibanaNoDataMocksPluginApi", - "section": "def-server.Params", + "section": "def-common.Params", "text": "Params" }, ") => { noDataConfig: { solution: any; logo: any; action: { elasticAgent: { title: string; }; }; docsLink: string; }; onDataViewCreated: ", @@ -258,7 +266,7 @@ "children": [ { "parentPluginId": "@kbn/shared-ux-page-kibana-no-data-mocks", - "id": "def-server.StorybookMock.getProps.$1", + "id": "def-common.StorybookMock.getProps.$1", "type": "CompoundType", "tags": [], "label": "params", @@ -266,9 +274,9 @@ "signature": [ { "pluginId": "@kbn/shared-ux-page-kibana-no-data-mocks", - "scope": "server", + "scope": "common", "docId": "kibKbnSharedUxPageKibanaNoDataMocksPluginApi", - "section": "def-server.Params", + "section": "def-common.Params", "text": "Params" } ], @@ -281,7 +289,7 @@ }, { "parentPluginId": "@kbn/shared-ux-page-kibana-no-data-mocks", - "id": "def-server.StorybookMock.getServices", + "id": "def-common.StorybookMock.getServices", "type": "Function", "tags": [], "label": "getServices", @@ -290,9 +298,9 @@ "(params: ", { "pluginId": "@kbn/shared-ux-page-kibana-no-data-mocks", - "scope": "server", + "scope": "common", "docId": "kibKbnSharedUxPageKibanaNoDataMocksPluginApi", - "section": "def-server.Params", + "section": "def-common.Params", "text": "Params" }, ") => ", @@ -303,7 +311,7 @@ "children": [ { "parentPluginId": "@kbn/shared-ux-page-kibana-no-data-mocks", - "id": "def-server.StorybookMock.getServices.$1", + "id": "def-common.StorybookMock.getServices.$1", "type": "CompoundType", "tags": [], "label": "params", @@ -311,9 +319,9 @@ "signature": [ { "pluginId": "@kbn/shared-ux-page-kibana-no-data-mocks", - "scope": "server", + "scope": "common", "docId": "kibKbnSharedUxPageKibanaNoDataMocksPluginApi", - "section": "def-server.Params", + "section": "def-common.Params", "text": "Params" } ], @@ -331,7 +339,7 @@ "functions": [ { "parentPluginId": "@kbn/shared-ux-page-kibana-no-data-mocks", - "id": "def-server.getServicesMock", + "id": "def-common.getServicesMock", "type": "Function", "tags": [], "label": "getServicesMock", @@ -339,9 +347,7 @@ "\nReturns the Jest-compatible service abstractions for the `KibanaNoDataPage` Provider." ], "signature": [ - "(params?: ", - "MockServicesFactoryParams", - " | undefined) => ", + "(params?: Partial | undefined) => ", "KibanaNoDataPageServices" ], "path": "packages/shared-ux/page/kibana_no_data/mocks/src/jest.ts", @@ -349,14 +355,13 @@ "children": [ { "parentPluginId": "@kbn/shared-ux-page-kibana-no-data-mocks", - "id": "def-server.getServicesMock.$1", + "id": "def-common.getServicesMock.$1", "type": "Object", "tags": [], "label": "params", "description": [], "signature": [ - "MockServicesFactoryParams", - " | undefined" + "Partial | undefined" ], "path": "packages/shared-ux/page/kibana_no_data/mocks/src/jest.ts", "deprecated": false, @@ -372,7 +377,7 @@ "misc": [ { "parentPluginId": "@kbn/shared-ux-page-kibana-no-data-mocks", - "id": "def-server.Params", + "id": "def-common.Params", "type": "Type", "tags": [], "label": "Params", @@ -390,13 +395,5 @@ } ], "objects": [] - }, - "common": { - "classes": [], - "functions": [], - "interfaces": [], - "enums": [], - "misc": [], - "objects": [] } } \ No newline at end of file diff --git a/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.mdx b/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.mdx index f241f48c65edd8..71ca7cfbcdc287 100644 --- a/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-no-data-mocks title: "@kbn/shared-ux-page-kibana-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-no-data-mocks plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-kibana-no-data-mocks'] --- import kbnSharedUxPageKibanaNoDataMocksObj from './kbn_shared_ux_page_kibana_no_data_mocks.devdocs.json'; @@ -23,14 +23,14 @@ Contact [Owner missing] for questions regarding this plugin. |-------------------|-----------|------------------------|-----------------| | 25 | 0 | 24 | 0 | -## Server +## Common ### Functions - + ### Classes - + ### Consts, variables and types - + diff --git a/api_docs/kbn_shared_ux_page_kibana_template.devdocs.json b/api_docs/kbn_shared_ux_page_kibana_template.devdocs.json new file mode 100644 index 00000000000000..f8cdca8122258a --- /dev/null +++ b/api_docs/kbn_shared_ux_page_kibana_template.devdocs.json @@ -0,0 +1,218 @@ +{ + "id": "@kbn/shared-ux-page-kibana-template", + "client": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "server": { + "classes": [], + "functions": [ + { + "parentPluginId": "@kbn/shared-ux-page-kibana-template", + "id": "def-server.KibanaPageTemplate", + "type": "Function", + "tags": [], + "label": "KibanaPageTemplate", + "description": [], + "signature": [ + "({ template, className, children, solutionNav, noDataConfig, ...rest }: React.PropsWithChildren<", + "KibanaPageTemplateProps", + ">) => JSX.Element" + ], + "path": "packages/shared-ux/page/kibana_template/impl/src/page_template.tsx", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/shared-ux-page-kibana-template", + "id": "def-server.KibanaPageTemplate.$1", + "type": "CompoundType", + "tags": [], + "label": "{\n template,\n className,\n children,\n solutionNav,\n noDataConfig,\n ...rest\n}", + "description": [], + "signature": [ + "React.PropsWithChildren<", + "KibanaPageTemplateProps", + ">" + ], + "path": "packages/shared-ux/page/kibana_template/impl/src/page_template.tsx", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/shared-ux-page-kibana-template", + "id": "def-server.KibanaPageTemplateKibanaProvider", + "type": "Function", + "tags": [], + "label": "KibanaPageTemplateKibanaProvider", + "description": [ + "\nKibana-specific Provider that maps dependencies to services." + ], + "signature": [ + "({ children, ...dependencies }: React.PropsWithChildren<", + "NoDataCardKibanaDependencies", + ">) => JSX.Element" + ], + "path": "packages/shared-ux/page/kibana_template/impl/src/services.tsx", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/shared-ux-page-kibana-template", + "id": "def-server.KibanaPageTemplateKibanaProvider.$1", + "type": "CompoundType", + "tags": [], + "label": "{\n children,\n ...dependencies\n}", + "description": [], + "signature": [ + "React.PropsWithChildren<", + "NoDataCardKibanaDependencies", + ">" + ], + "path": "packages/shared-ux/page/kibana_template/impl/src/services.tsx", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/shared-ux-page-kibana-template", + "id": "def-server.KibanaPageTemplateProvider", + "type": "Function", + "tags": [], + "label": "KibanaPageTemplateProvider", + "description": [ + "\nA Context Provider that provides services to the component and its dependencies." + ], + "signature": [ + "({ children, ...services }: React.PropsWithChildren<", + "NoDataCardServices", + ">) => JSX.Element" + ], + "path": "packages/shared-ux/page/kibana_template/impl/src/services.tsx", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/shared-ux-page-kibana-template", + "id": "def-server.KibanaPageTemplateProvider.$1", + "type": "CompoundType", + "tags": [], + "label": "{\n children,\n ...services\n}", + "description": [], + "signature": [ + "React.PropsWithChildren<", + "NoDataCardServices", + ">" + ], + "path": "packages/shared-ux/page/kibana_template/impl/src/services.tsx", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + } + ], + "interfaces": [], + "enums": [], + "misc": [ + { + "parentPluginId": "@kbn/shared-ux-page-kibana-template", + "id": "def-server.KibanaPageTemplateKibanaDependencies", + "type": "Type", + "tags": [], + "label": "KibanaPageTemplateKibanaDependencies", + "description": [], + "signature": [ + "KibanaDependencies", + " & ", + "RedirectAppLinksKibanaDependencies" + ], + "path": "node_modules/@kbn/shared-ux-page-kibana-template-types/index.d.ts", + "deprecated": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/shared-ux-page-kibana-template", + "id": "def-server.KibanaPageTemplateProps", + "type": "Type", + "tags": [], + "label": "KibanaPageTemplateProps", + "description": [], + "signature": [ + "Omit<", + "EuiPageProps", + ", \"paddingSize\"> & { template?: \"default\" | \"empty\" | \"centeredBody\" | \"centeredContent\" | undefined; paddingSize?: \"none\" | \"m\" | \"s\" | \"l\" | undefined; pageSideBar?: React.ReactNode; pageSideBarProps?: ", + "EuiPageSideBarProps", + " | undefined; pageHeader?: ", + "EuiPageHeaderProps", + " | undefined; pageBodyProps?: ", + "EuiPageBodyProps", + "<\"main\"> | undefined; pageContentProps?: ", + "EuiPageContentProps", + " | undefined; pageContentBodyProps?: ", + "EuiPageContentBodyProps", + " | undefined; bottomBar?: React.ReactNode; bottomBarProps?: ", + "EuiBottomBarProps", + " | undefined; fullHeight?: boolean | \"noscroll\" | undefined; minHeight?: ", + "Property", + ".MinHeight | undefined; } & { isEmptyState?: boolean | undefined; solutionNav?: ", + "SolutionNavProps", + " | undefined; noDataConfig?: ", + "NoDataPageProps", + " | undefined; }" + ], + "path": "node_modules/@kbn/shared-ux-page-kibana-template-types/index.d.ts", + "deprecated": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/shared-ux-page-kibana-template", + "id": "def-server.KibanaPageTemplateServices", + "type": "Type", + "tags": [], + "label": "KibanaPageTemplateServices", + "description": [], + "signature": [ + "Services", + " & ", + "RedirectAppLinksServices" + ], + "path": "node_modules/@kbn/shared-ux-page-kibana-template-types/index.d.ts", + "deprecated": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/shared-ux-page-kibana-template", + "id": "def-server.NoDataConfig", + "type": "Type", + "tags": [], + "label": "NoDataConfig", + "description": [], + "signature": [ + "NoDataPageProps" + ], + "path": "node_modules/@kbn/shared-ux-page-no-data-config-types/index.d.ts", + "deprecated": false, + "initialIsOpen": false + } + ], + "objects": [] + }, + "common": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + } +} \ No newline at end of file diff --git a/api_docs/kbn_shared_ux_page_kibana_template.mdx b/api_docs/kbn_shared_ux_page_kibana_template.mdx new file mode 100644 index 00000000000000..11a4a91f297bab --- /dev/null +++ b/api_docs/kbn_shared_ux_page_kibana_template.mdx @@ -0,0 +1,33 @@ +--- +#### +#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system. +#### Reach out in #docs-engineering for more info. +#### +id: kibKbnSharedUxPageKibanaTemplatePluginApi +slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-template +title: "@kbn/shared-ux-page-kibana-template" +image: https://source.unsplash.com/400x175/?github +description: API docs for the @kbn/shared-ux-page-kibana-template plugin +date: 2022-08-24 +tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-kibana-template'] +--- +import kbnSharedUxPageKibanaTemplateObj from './kbn_shared_ux_page_kibana_template.devdocs.json'; + + + +Contact [Owner missing] for questions regarding this plugin. + +**Code health stats** + +| Public API count | Any count | Items lacking comments | Missing exports | +|-------------------|-----------|------------------------|-----------------| +| 10 | 0 | 4 | 0 | + +## Server + +### Functions + + +### Consts, variables and types + + diff --git a/api_docs/kbn_shared_ux_page_kibana_template_mocks.devdocs.json b/api_docs/kbn_shared_ux_page_kibana_template_mocks.devdocs.json new file mode 100644 index 00000000000000..5e888519540f05 --- /dev/null +++ b/api_docs/kbn_shared_ux_page_kibana_template_mocks.devdocs.json @@ -0,0 +1,860 @@ +{ + "id": "@kbn/shared-ux-page-kibana-template-mocks", + "client": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "server": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "common": { + "classes": [ + { + "parentPluginId": "@kbn/shared-ux-page-kibana-template-mocks", + "id": "def-common.StorybookMock", + "type": "Class", + "tags": [], + "label": "StorybookMock", + "description": [], + "signature": [ + { + "pluginId": "@kbn/shared-ux-page-kibana-template-mocks", + "scope": "common", + "docId": "kibKbnSharedUxPageKibanaTemplateMocksPluginApi", + "section": "def-common.StorybookMock", + "text": "StorybookMock" + }, + " extends ", + "AbstractStorybookMock", + "<", + "KibanaPageTemplateProps", + ", ", + "NoDataCardServices", + ", PropArguments, {}>" + ], + "path": "packages/shared-ux/page/kibana_template/mocks/src/storybook/all.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/shared-ux-page-kibana-template-mocks", + "id": "def-common.StorybookMock.propArguments", + "type": "Object", + "tags": [], + "label": "propArguments", + "description": [], + "path": "packages/shared-ux/page/kibana_template/mocks/src/storybook/all.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/shared-ux-page-kibana-template-mocks", + "id": "def-common.StorybookMock.propArguments.Unnamed", + "type": "Any", + "tags": [], + "label": "Unnamed", + "description": [], + "signature": [ + "any" + ], + "path": "packages/shared-ux/page/kibana_template/mocks/src/storybook/all.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/shared-ux-page-kibana-template-mocks", + "id": "def-common.StorybookMock.propArguments.Unnamed", + "type": "Any", + "tags": [], + "label": "Unnamed", + "description": [], + "signature": [ + "any" + ], + "path": "packages/shared-ux/page/kibana_template/mocks/src/storybook/all.ts", + "deprecated": false + } + ] + }, + { + "parentPluginId": "@kbn/shared-ux-page-kibana-template-mocks", + "id": "def-common.StorybookMock.serviceArguments", + "type": "Object", + "tags": [], + "label": "serviceArguments", + "description": [], + "path": "packages/shared-ux/page/kibana_template/mocks/src/storybook/all.ts", + "deprecated": false, + "children": [] + }, + { + "parentPluginId": "@kbn/shared-ux-page-kibana-template-mocks", + "id": "def-common.StorybookMock.dependencies", + "type": "Array", + "tags": [], + "label": "dependencies", + "description": [], + "signature": [ + "NoDataConfigPageStorybookMock", + "[]" + ], + "path": "packages/shared-ux/page/kibana_template/mocks/src/storybook/all.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/shared-ux-page-kibana-template-mocks", + "id": "def-common.StorybookMock.getProps", + "type": "Function", + "tags": [], + "label": "getProps", + "description": [], + "signature": [ + "(params?: ", + { + "pluginId": "@kbn/shared-ux-page-kibana-template-mocks", + "scope": "common", + "docId": "kibKbnSharedUxPageKibanaTemplateMocksPluginApi", + "section": "def-common.Params", + "text": "Params" + }, + " | undefined) => ", + "KibanaPageTemplateProps" + ], + "path": "packages/shared-ux/page/kibana_template/mocks/src/storybook/all.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/shared-ux-page-kibana-template-mocks", + "id": "def-common.StorybookMock.getProps.$1", + "type": "CompoundType", + "tags": [], + "label": "params", + "description": [], + "signature": [ + { + "pluginId": "@kbn/shared-ux-page-kibana-template-mocks", + "scope": "common", + "docId": "kibKbnSharedUxPageKibanaTemplateMocksPluginApi", + "section": "def-common.Params", + "text": "Params" + }, + " | undefined" + ], + "path": "packages/shared-ux/page/kibana_template/mocks/src/storybook/all.ts", + "deprecated": false, + "isRequired": false + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/shared-ux-page-kibana-template-mocks", + "id": "def-common.StorybookMock.getServices", + "type": "Function", + "tags": [], + "label": "getServices", + "description": [], + "signature": [ + "(params: ", + { + "pluginId": "@kbn/shared-ux-page-kibana-template-mocks", + "scope": "common", + "docId": "kibKbnSharedUxPageKibanaTemplateMocksPluginApi", + "section": "def-common.Params", + "text": "Params" + }, + ") => ", + "NoDataCardServices" + ], + "path": "packages/shared-ux/page/kibana_template/mocks/src/storybook/all.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/shared-ux-page-kibana-template-mocks", + "id": "def-common.StorybookMock.getServices.$1", + "type": "CompoundType", + "tags": [], + "label": "params", + "description": [], + "signature": [ + { + "pluginId": "@kbn/shared-ux-page-kibana-template-mocks", + "scope": "common", + "docId": "kibKbnSharedUxPageKibanaTemplateMocksPluginApi", + "section": "def-common.Params", + "text": "Params" + } + ], + "path": "packages/shared-ux/page/kibana_template/mocks/src/storybook/all.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/shared-ux-page-kibana-template-mocks", + "id": "def-common.StorybookMock", + "type": "Class", + "tags": [], + "label": "StorybookMock", + "description": [], + "signature": [ + { + "pluginId": "@kbn/shared-ux-page-kibana-template-mocks", + "scope": "common", + "docId": "kibKbnSharedUxPageKibanaTemplateMocksPluginApi", + "section": "def-common.StorybookMock", + "text": "StorybookMock" + }, + " extends ", + "AbstractStorybookMock", + "<", + "KibanaPageTemplateProps", + ", ", + "NoDataCardServices", + ", ", + "NoDataConfigArguments", + ", {}>" + ], + "path": "packages/shared-ux/page/kibana_template/mocks/src/storybook/no_data_config.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/shared-ux-page-kibana-template-mocks", + "id": "def-common.StorybookMock.propArguments", + "type": "Object", + "tags": [], + "label": "propArguments", + "description": [], + "path": "packages/shared-ux/page/kibana_template/mocks/src/storybook/no_data_config.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/shared-ux-page-kibana-template-mocks", + "id": "def-common.StorybookMock.propArguments.Unnamed", + "type": "Any", + "tags": [], + "label": "Unnamed", + "description": [], + "signature": [ + "any" + ], + "path": "packages/shared-ux/page/kibana_template/mocks/src/storybook/no_data_config.ts", + "deprecated": false + } + ] + }, + { + "parentPluginId": "@kbn/shared-ux-page-kibana-template-mocks", + "id": "def-common.StorybookMock.serviceArguments", + "type": "Object", + "tags": [], + "label": "serviceArguments", + "description": [], + "path": "packages/shared-ux/page/kibana_template/mocks/src/storybook/no_data_config.ts", + "deprecated": false, + "children": [] + }, + { + "parentPluginId": "@kbn/shared-ux-page-kibana-template-mocks", + "id": "def-common.StorybookMock.dependencies", + "type": "Array", + "tags": [], + "label": "dependencies", + "description": [], + "signature": [ + "NoDataConfigPageStorybookMock", + "[]" + ], + "path": "packages/shared-ux/page/kibana_template/mocks/src/storybook/no_data_config.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/shared-ux-page-kibana-template-mocks", + "id": "def-common.StorybookMock.getProps", + "type": "Function", + "tags": [], + "label": "getProps", + "description": [], + "signature": [ + "(params?: ", + { + "pluginId": "@kbn/shared-ux-page-kibana-template-mocks", + "scope": "common", + "docId": "kibKbnSharedUxPageKibanaTemplateMocksPluginApi", + "section": "def-common.Params", + "text": "Params" + }, + " | undefined) => ", + "KibanaPageTemplateProps" + ], + "path": "packages/shared-ux/page/kibana_template/mocks/src/storybook/no_data_config.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/shared-ux-page-kibana-template-mocks", + "id": "def-common.StorybookMock.getProps.$1", + "type": "CompoundType", + "tags": [], + "label": "params", + "description": [], + "signature": [ + { + "pluginId": "@kbn/shared-ux-page-kibana-template-mocks", + "scope": "common", + "docId": "kibKbnSharedUxPageKibanaTemplateMocksPluginApi", + "section": "def-common.Params", + "text": "Params" + }, + " | undefined" + ], + "path": "packages/shared-ux/page/kibana_template/mocks/src/storybook/no_data_config.ts", + "deprecated": false, + "isRequired": false + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/shared-ux-page-kibana-template-mocks", + "id": "def-common.StorybookMock.getServices", + "type": "Function", + "tags": [], + "label": "getServices", + "description": [], + "signature": [ + "(params: ", + { + "pluginId": "@kbn/shared-ux-page-kibana-template-mocks", + "scope": "common", + "docId": "kibKbnSharedUxPageKibanaTemplateMocksPluginApi", + "section": "def-common.Params", + "text": "Params" + }, + ") => ", + "NoDataCardServices" + ], + "path": "packages/shared-ux/page/kibana_template/mocks/src/storybook/no_data_config.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/shared-ux-page-kibana-template-mocks", + "id": "def-common.StorybookMock.getServices.$1", + "type": "CompoundType", + "tags": [], + "label": "params", + "description": [], + "signature": [ + { + "pluginId": "@kbn/shared-ux-page-kibana-template-mocks", + "scope": "common", + "docId": "kibKbnSharedUxPageKibanaTemplateMocksPluginApi", + "section": "def-common.Params", + "text": "Params" + } + ], + "path": "packages/shared-ux/page/kibana_template/mocks/src/storybook/no_data_config.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/shared-ux-page-kibana-template-mocks", + "id": "def-common.StorybookMock", + "type": "Class", + "tags": [], + "label": "StorybookMock", + "description": [], + "signature": [ + { + "pluginId": "@kbn/shared-ux-page-kibana-template-mocks", + "scope": "common", + "docId": "kibKbnSharedUxPageKibanaTemplateMocksPluginApi", + "section": "def-common.StorybookMock", + "text": "StorybookMock" + }, + " extends ", + "AbstractStorybookMock", + "<", + "KibanaPageTemplateProps", + ", ", + "NoDataCardServices", + ", ", + "SolutionNavArguments", + ", {}>" + ], + "path": "packages/shared-ux/page/kibana_template/mocks/src/storybook/solution_nav.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/shared-ux-page-kibana-template-mocks", + "id": "def-common.StorybookMock.propArguments", + "type": "Object", + "tags": [], + "label": "propArguments", + "description": [], + "path": "packages/shared-ux/page/kibana_template/mocks/src/storybook/solution_nav.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/shared-ux-page-kibana-template-mocks", + "id": "def-common.StorybookMock.propArguments.Unnamed", + "type": "Any", + "tags": [], + "label": "Unnamed", + "description": [], + "signature": [ + "any" + ], + "path": "packages/shared-ux/page/kibana_template/mocks/src/storybook/solution_nav.ts", + "deprecated": false + } + ] + }, + { + "parentPluginId": "@kbn/shared-ux-page-kibana-template-mocks", + "id": "def-common.StorybookMock.serviceArguments", + "type": "Object", + "tags": [], + "label": "serviceArguments", + "description": [], + "path": "packages/shared-ux/page/kibana_template/mocks/src/storybook/solution_nav.ts", + "deprecated": false, + "children": [] + }, + { + "parentPluginId": "@kbn/shared-ux-page-kibana-template-mocks", + "id": "def-common.StorybookMock.dependencies", + "type": "Array", + "tags": [], + "label": "dependencies", + "description": [], + "signature": [ + "NoDataConfigPageStorybookMock", + "[]" + ], + "path": "packages/shared-ux/page/kibana_template/mocks/src/storybook/solution_nav.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/shared-ux-page-kibana-template-mocks", + "id": "def-common.StorybookMock.getProps", + "type": "Function", + "tags": [], + "label": "getProps", + "description": [], + "signature": [ + "(params?: ", + { + "pluginId": "@kbn/shared-ux-page-kibana-template-mocks", + "scope": "common", + "docId": "kibKbnSharedUxPageKibanaTemplateMocksPluginApi", + "section": "def-common.Params", + "text": "Params" + }, + " | undefined) => ", + "KibanaPageTemplateProps" + ], + "path": "packages/shared-ux/page/kibana_template/mocks/src/storybook/solution_nav.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/shared-ux-page-kibana-template-mocks", + "id": "def-common.StorybookMock.getProps.$1", + "type": "CompoundType", + "tags": [], + "label": "params", + "description": [], + "signature": [ + { + "pluginId": "@kbn/shared-ux-page-kibana-template-mocks", + "scope": "common", + "docId": "kibKbnSharedUxPageKibanaTemplateMocksPluginApi", + "section": "def-common.Params", + "text": "Params" + }, + " | undefined" + ], + "path": "packages/shared-ux/page/kibana_template/mocks/src/storybook/solution_nav.ts", + "deprecated": false, + "isRequired": false + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/shared-ux-page-kibana-template-mocks", + "id": "def-common.StorybookMock.getServices", + "type": "Function", + "tags": [], + "label": "getServices", + "description": [], + "signature": [ + "(params: ", + { + "pluginId": "@kbn/shared-ux-page-kibana-template-mocks", + "scope": "common", + "docId": "kibKbnSharedUxPageKibanaTemplateMocksPluginApi", + "section": "def-common.Params", + "text": "Params" + }, + ") => ", + "NoDataCardServices" + ], + "path": "packages/shared-ux/page/kibana_template/mocks/src/storybook/solution_nav.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/shared-ux-page-kibana-template-mocks", + "id": "def-common.StorybookMock.getServices.$1", + "type": "CompoundType", + "tags": [], + "label": "params", + "description": [], + "signature": [ + { + "pluginId": "@kbn/shared-ux-page-kibana-template-mocks", + "scope": "common", + "docId": "kibKbnSharedUxPageKibanaTemplateMocksPluginApi", + "section": "def-common.Params", + "text": "Params" + } + ], + "path": "packages/shared-ux/page/kibana_template/mocks/src/storybook/solution_nav.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/shared-ux-page-kibana-template-mocks", + "id": "def-common.StorybookMock", + "type": "Class", + "tags": [], + "label": "StorybookMock", + "description": [], + "signature": [ + { + "pluginId": "@kbn/shared-ux-page-kibana-template-mocks", + "scope": "common", + "docId": "kibKbnSharedUxPageKibanaTemplateMocksPluginApi", + "section": "def-common.StorybookMock", + "text": "StorybookMock" + }, + " extends ", + "AbstractStorybookMock", + "<", + "KibanaPageTemplateProps", + ", ", + "NoDataCardServices", + ", PropArguments, {}>" + ], + "path": "packages/shared-ux/page/kibana_template/mocks/src/storybook/inner.tsx", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/shared-ux-page-kibana-template-mocks", + "id": "def-common.StorybookMock.propArguments", + "type": "Object", + "tags": [], + "label": "propArguments", + "description": [], + "path": "packages/shared-ux/page/kibana_template/mocks/src/storybook/inner.tsx", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/shared-ux-page-kibana-template-mocks", + "id": "def-common.StorybookMock.propArguments.Unnamed", + "type": "Any", + "tags": [], + "label": "Unnamed", + "description": [], + "signature": [ + "any" + ], + "path": "packages/shared-ux/page/kibana_template/mocks/src/storybook/inner.tsx", + "deprecated": false + } + ] + }, + { + "parentPluginId": "@kbn/shared-ux-page-kibana-template-mocks", + "id": "def-common.StorybookMock.serviceArguments", + "type": "Object", + "tags": [], + "label": "serviceArguments", + "description": [], + "path": "packages/shared-ux/page/kibana_template/mocks/src/storybook/inner.tsx", + "deprecated": false, + "children": [] + }, + { + "parentPluginId": "@kbn/shared-ux-page-kibana-template-mocks", + "id": "def-common.StorybookMock.dependencies", + "type": "Array", + "tags": [], + "label": "dependencies", + "description": [], + "signature": [ + "never[]" + ], + "path": "packages/shared-ux/page/kibana_template/mocks/src/storybook/inner.tsx", + "deprecated": false + }, + { + "parentPluginId": "@kbn/shared-ux-page-kibana-template-mocks", + "id": "def-common.StorybookMock.getProps", + "type": "Function", + "tags": [], + "label": "getProps", + "description": [], + "signature": [ + "(params?: ", + { + "pluginId": "@kbn/shared-ux-page-kibana-template-mocks", + "scope": "common", + "docId": "kibKbnSharedUxPageKibanaTemplateMocksPluginApi", + "section": "def-common.Params", + "text": "Params" + }, + " | undefined) => ", + "KibanaPageTemplateProps" + ], + "path": "packages/shared-ux/page/kibana_template/mocks/src/storybook/inner.tsx", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/shared-ux-page-kibana-template-mocks", + "id": "def-common.StorybookMock.getProps.$1", + "type": "CompoundType", + "tags": [], + "label": "params", + "description": [], + "signature": [ + { + "pluginId": "@kbn/shared-ux-page-kibana-template-mocks", + "scope": "common", + "docId": "kibKbnSharedUxPageKibanaTemplateMocksPluginApi", + "section": "def-common.Params", + "text": "Params" + }, + " | undefined" + ], + "path": "packages/shared-ux/page/kibana_template/mocks/src/storybook/inner.tsx", + "deprecated": false, + "isRequired": false + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/shared-ux-page-kibana-template-mocks", + "id": "def-common.StorybookMock.getServices", + "type": "Function", + "tags": [], + "label": "getServices", + "description": [], + "signature": [ + "(params: ", + { + "pluginId": "@kbn/shared-ux-page-kibana-template-mocks", + "scope": "common", + "docId": "kibKbnSharedUxPageKibanaTemplateMocksPluginApi", + "section": "def-common.Params", + "text": "Params" + }, + ") => ", + "NoDataCardServices" + ], + "path": "packages/shared-ux/page/kibana_template/mocks/src/storybook/inner.tsx", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/shared-ux-page-kibana-template-mocks", + "id": "def-common.StorybookMock.getServices.$1", + "type": "CompoundType", + "tags": [], + "label": "params", + "description": [], + "signature": [ + { + "pluginId": "@kbn/shared-ux-page-kibana-template-mocks", + "scope": "common", + "docId": "kibKbnSharedUxPageKibanaTemplateMocksPluginApi", + "section": "def-common.Params", + "text": "Params" + } + ], + "path": "packages/shared-ux/page/kibana_template/mocks/src/storybook/inner.tsx", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + } + ], + "initialIsOpen": false + } + ], + "functions": [ + { + "parentPluginId": "@kbn/shared-ux-page-kibana-template-mocks", + "id": "def-common.getKibanaDependenciesMock", + "type": "Function", + "tags": [], + "label": "getKibanaDependenciesMock", + "description": [], + "signature": [ + "() => ", + "NoDataCardKibanaDependencies" + ], + "path": "packages/shared-ux/page/kibana_template/mocks/src/jest.ts", + "deprecated": false, + "children": [], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/shared-ux-page-kibana-template-mocks", + "id": "def-common.getServicesMock", + "type": "Function", + "tags": [], + "label": "getServicesMock", + "description": [], + "signature": [ + "() => ", + "NoDataCardServices" + ], + "path": "packages/shared-ux/page/kibana_template/mocks/src/jest.ts", + "deprecated": false, + "children": [], + "returnComment": [], + "initialIsOpen": false + } + ], + "interfaces": [], + "enums": [], + "misc": [ + { + "parentPluginId": "@kbn/shared-ux-page-kibana-template-mocks", + "id": "def-common.Params", + "type": "Type", + "tags": [], + "label": "Params", + "description": [], + "signature": [ + "ArgumentParams", + " & ", + "ArgumentParams", + "<", + "PropArguments", + ", {}> & ", + "ArgumentParams", + "<", + "PropArguments", + ", {}> & ", + "NoDataCardStorybookParams" + ], + "path": "packages/shared-ux/page/kibana_template/mocks/src/storybook/all.ts", + "deprecated": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/shared-ux-page-kibana-template-mocks", + "id": "def-common.Params", + "type": "Type", + "tags": [], + "label": "Params", + "description": [], + "signature": [ + "ArgumentParams", + "<", + "NoDataConfigArguments", + ", {}> & ", + "ArgumentParams", + "<", + "PropArguments", + ", {}> & ", + "ArgumentParams", + "<", + "PropArguments", + ", {}> & ", + "NoDataCardStorybookParams" + ], + "path": "packages/shared-ux/page/kibana_template/mocks/src/storybook/no_data_config.ts", + "deprecated": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/shared-ux-page-kibana-template-mocks", + "id": "def-common.Params", + "type": "Type", + "tags": [], + "label": "Params", + "description": [], + "signature": [ + "ArgumentParams", + "<", + "SolutionNavArguments", + ", {}> & ", + "ArgumentParams", + "<", + "PropArguments", + ", {}> & ", + "ArgumentParams", + "<", + "PropArguments", + ", {}> & ", + "NoDataCardStorybookParams" + ], + "path": "packages/shared-ux/page/kibana_template/mocks/src/storybook/solution_nav.ts", + "deprecated": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/shared-ux-page-kibana-template-mocks", + "id": "def-common.Params", + "type": "Type", + "tags": [], + "label": "Params", + "description": [], + "signature": [ + "ArgumentParams", + " & ", + "ArgumentParams", + "<", + "PropArguments", + ", {}> & ", + "ArgumentParams", + "<", + "PropArguments", + ", {}> & ", + "NoDataCardStorybookParams" + ], + "path": "packages/shared-ux/page/kibana_template/mocks/src/storybook/inner.tsx", + "deprecated": false, + "initialIsOpen": false + } + ], + "objects": [] + } +} \ No newline at end of file diff --git a/api_docs/kbn_shared_ux_page_kibana_template_mocks.mdx b/api_docs/kbn_shared_ux_page_kibana_template_mocks.mdx new file mode 100644 index 00000000000000..6d4421e1f5b46c --- /dev/null +++ b/api_docs/kbn_shared_ux_page_kibana_template_mocks.mdx @@ -0,0 +1,36 @@ +--- +#### +#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system. +#### Reach out in #docs-engineering for more info. +#### +id: kibKbnSharedUxPageKibanaTemplateMocksPluginApi +slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-template-mocks +title: "@kbn/shared-ux-page-kibana-template-mocks" +image: https://source.unsplash.com/400x175/?github +description: API docs for the @kbn/shared-ux-page-kibana-template-mocks plugin +date: 2022-08-24 +tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-kibana-template-mocks'] +--- +import kbnSharedUxPageKibanaTemplateMocksObj from './kbn_shared_ux_page_kibana_template_mocks.devdocs.json'; + + + +Contact [Owner missing] for questions regarding this plugin. + +**Code health stats** + +| Public API count | Any count | Items lacking comments | Missing exports | +|-------------------|-----------|------------------------|-----------------| +| 43 | 5 | 43 | 2 | + +## Common + +### Functions + + +### Classes + + +### Consts, variables and types + + diff --git a/api_docs/kbn_shared_ux_page_no_data.devdocs.json b/api_docs/kbn_shared_ux_page_no_data.devdocs.json new file mode 100644 index 00000000000000..b67afdf6a138c3 --- /dev/null +++ b/api_docs/kbn_shared_ux_page_no_data.devdocs.json @@ -0,0 +1,247 @@ +{ + "id": "@kbn/shared-ux-page-no-data", + "client": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "server": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "common": { + "classes": [], + "functions": [ + { + "parentPluginId": "@kbn/shared-ux-page-no-data", + "id": "def-common.NoDataPage", + "type": "Function", + "tags": [], + "label": "NoDataPage", + "description": [], + "signature": [ + "({ solution, logo, action, docsLink, pageTitle, className, }: ", + "NoDataPageProps", + ") => JSX.Element" + ], + "path": "packages/shared-ux/page/no_data/impl/src/no_data_page.tsx", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/shared-ux-page-no-data", + "id": "def-common.NoDataPage.$1", + "type": "Object", + "tags": [], + "label": "{\n solution,\n logo,\n action,\n docsLink,\n pageTitle,\n className,\n}", + "description": [], + "signature": [ + "NoDataPageProps" + ], + "path": "packages/shared-ux/page/no_data/impl/src/no_data_page.tsx", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/shared-ux-page-no-data", + "id": "def-common.NoDataPageKibanaProvider", + "type": "Function", + "tags": [], + "label": "NoDataPageKibanaProvider", + "description": [ + "\nKibana-specific Provider that maps dependencies to services." + ], + "signature": [ + "({ children, ...dependencies }: React.PropsWithChildren<", + "NoDataCardKibanaDependencies", + ">) => JSX.Element" + ], + "path": "packages/shared-ux/page/no_data/impl/src/services.tsx", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/shared-ux-page-no-data", + "id": "def-common.NoDataPageKibanaProvider.$1", + "type": "CompoundType", + "tags": [], + "label": "{\n children,\n ...dependencies\n}", + "description": [], + "signature": [ + "React.PropsWithChildren<", + "NoDataCardKibanaDependencies", + ">" + ], + "path": "packages/shared-ux/page/no_data/impl/src/services.tsx", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/shared-ux-page-no-data", + "id": "def-common.NoDataPageProvider", + "type": "Function", + "tags": [], + "label": "NoDataPageProvider", + "description": [ + "\nA Context Provider that provides services to the component and its dependencies." + ], + "signature": [ + "({ children, ...services }: React.PropsWithChildren<", + "NoDataCardServices", + ">) => JSX.Element" + ], + "path": "packages/shared-ux/page/no_data/impl/src/services.tsx", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/shared-ux-page-no-data", + "id": "def-common.NoDataPageProvider.$1", + "type": "CompoundType", + "tags": [], + "label": "{ children, ...services }", + "description": [], + "signature": [ + "React.PropsWithChildren<", + "NoDataCardServices", + ">" + ], + "path": "packages/shared-ux/page/no_data/impl/src/services.tsx", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + } + ], + "interfaces": [ + { + "parentPluginId": "@kbn/shared-ux-page-no-data", + "id": "def-common.NoDataPageProps", + "type": "Interface", + "tags": [], + "label": "NoDataPageProps", + "description": [], + "signature": [ + "NoDataPageProps", + " extends ", + "CommonProps", + ",", + "ActionCardProps" + ], + "path": "node_modules/@kbn/shared-ux-page-no-data-types/index.d.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/shared-ux-page-no-data", + "id": "def-common.NoDataPageProps.solution", + "type": "string", + "tags": [], + "label": "solution", + "description": [ + "\nSingle name for the current solution, used to auto-generate the title, logo, description, and button label" + ], + "path": "node_modules/@kbn/shared-ux-page-no-data-types/index.d.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/shared-ux-page-no-data", + "id": "def-common.NoDataPageProps.docsLink", + "type": "string", + "tags": [], + "label": "docsLink", + "description": [ + "\nRequired to set the docs link for the whole solution" + ], + "path": "node_modules/@kbn/shared-ux-page-no-data-types/index.d.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/shared-ux-page-no-data", + "id": "def-common.NoDataPageProps.logo", + "type": "string", + "tags": [], + "label": "logo", + "description": [ + "\nOptionally replace the auto-generated logo" + ], + "signature": [ + "string | undefined" + ], + "path": "node_modules/@kbn/shared-ux-page-no-data-types/index.d.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/shared-ux-page-no-data", + "id": "def-common.NoDataPageProps.pageTitle", + "type": "string", + "tags": [], + "label": "pageTitle", + "description": [ + "\nOptionally replace the auto-generated page title (h1)" + ], + "signature": [ + "string | undefined" + ], + "path": "node_modules/@kbn/shared-ux-page-no-data-types/index.d.ts", + "deprecated": false + } + ], + "initialIsOpen": false + } + ], + "enums": [], + "misc": [ + { + "parentPluginId": "@kbn/shared-ux-page-no-data", + "id": "def-common.NoDataPageKibanaDependencies", + "type": "Type", + "tags": [], + "label": "NoDataPageKibanaDependencies", + "description": [ + "\nAn interface containing a collection of Kibana plugins and services required to\nrender this component." + ], + "signature": [ + "KibanaDependencies", + " & ", + "RedirectAppLinksKibanaDependencies" + ], + "path": "node_modules/@kbn/shared-ux-page-no-data-types/index.d.ts", + "deprecated": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/shared-ux-page-no-data", + "id": "def-common.NoDataPageServices", + "type": "Type", + "tags": [], + "label": "NoDataPageServices", + "description": [ + "\nA list of services that are consumed by this component." + ], + "signature": [ + "Services", + " & ", + "RedirectAppLinksServices" + ], + "path": "node_modules/@kbn/shared-ux-page-no-data-types/index.d.ts", + "deprecated": false, + "initialIsOpen": false + } + ], + "objects": [] + } +} \ No newline at end of file diff --git a/api_docs/kbn_shared_ux_components.mdx b/api_docs/kbn_shared_ux_page_no_data.mdx similarity index 54% rename from api_docs/kbn_shared_ux_components.mdx rename to api_docs/kbn_shared_ux_page_no_data.mdx index 6624fc67ceeede..db666ab0eb029d 100644 --- a/api_docs/kbn_shared_ux_components.mdx +++ b/api_docs/kbn_shared_ux_page_no_data.mdx @@ -3,15 +3,15 @@ #### This document is auto-generated and is meant to be viewed inside our experimental, new docs system. #### Reach out in #docs-engineering for more info. #### -id: kibKbnSharedUxComponentsPluginApi -slug: /kibana-dev-docs/api/kbn-shared-ux-components -title: "@kbn/shared-ux-components" +id: kibKbnSharedUxPageNoDataPluginApi +slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data +title: "@kbn/shared-ux-page-no-data" image: https://source.unsplash.com/400x175/?github -description: API docs for the @kbn/shared-ux-components plugin -date: 2022-08-17 -tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-components'] +description: API docs for the @kbn/shared-ux-page-no-data plugin +date: 2022-08-24 +tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-no-data'] --- -import kbnSharedUxComponentsObj from './kbn_shared_ux_components.devdocs.json'; +import kbnSharedUxPageNoDataObj from './kbn_shared_ux_page_no_data.devdocs.json'; @@ -21,16 +21,16 @@ Contact [Owner missing] for questions regarding this plugin. | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 11 | 0 | 6 | 0 | +| 13 | 0 | 4 | 0 | ## Common ### Functions - + ### Interfaces - + ### Consts, variables and types - + diff --git a/api_docs/kbn_shared_ux_page_no_data_config.devdocs.json b/api_docs/kbn_shared_ux_page_no_data_config.devdocs.json new file mode 100644 index 00000000000000..33b90569d9d4ee --- /dev/null +++ b/api_docs/kbn_shared_ux_page_no_data_config.devdocs.json @@ -0,0 +1,254 @@ +{ + "id": "@kbn/shared-ux-page-no-data-config", + "client": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "server": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "common": { + "classes": [], + "functions": [ + { + "parentPluginId": "@kbn/shared-ux-page-no-data-config", + "id": "def-common.NoDataConfigPage", + "type": "Function", + "tags": [], + "label": "NoDataConfigPage", + "description": [], + "signature": [ + "(props: ", + "NoDataConfigPageProps", + ") => JSX.Element | null" + ], + "path": "packages/shared-ux/page/no_data_config/impl/src/no_data_config_page.tsx", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/shared-ux-page-no-data-config", + "id": "def-common.NoDataConfigPage.$1", + "type": "CompoundType", + "tags": [], + "label": "props", + "description": [], + "signature": [ + "NoDataConfigPageProps" + ], + "path": "packages/shared-ux/page/no_data_config/impl/src/no_data_config_page.tsx", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/shared-ux-page-no-data-config", + "id": "def-common.NoDataConfigPageKibanaProvider", + "type": "Function", + "tags": [], + "label": "NoDataConfigPageKibanaProvider", + "description": [ + "\nKibana-specific Provider that maps dependencies to services." + ], + "signature": [ + "({ children, ...dependencies }: React.PropsWithChildren<", + "NoDataCardKibanaDependencies", + ">) => JSX.Element" + ], + "path": "packages/shared-ux/page/no_data_config/impl/src/services.tsx", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/shared-ux-page-no-data-config", + "id": "def-common.NoDataConfigPageKibanaProvider.$1", + "type": "CompoundType", + "tags": [], + "label": "{\n children,\n ...dependencies\n}", + "description": [], + "signature": [ + "React.PropsWithChildren<", + "NoDataCardKibanaDependencies", + ">" + ], + "path": "packages/shared-ux/page/no_data_config/impl/src/services.tsx", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/shared-ux-page-no-data-config", + "id": "def-common.NoDataConfigPageProvider", + "type": "Function", + "tags": [], + "label": "NoDataConfigPageProvider", + "description": [ + "\nA Context Provider that provides services to the component and its dependencies." + ], + "signature": [ + "({ children, ...services }: React.PropsWithChildren<", + "NoDataCardServices", + ">) => JSX.Element" + ], + "path": "packages/shared-ux/page/no_data_config/impl/src/services.tsx", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/shared-ux-page-no-data-config", + "id": "def-common.NoDataConfigPageProvider.$1", + "type": "CompoundType", + "tags": [], + "label": "{\n children,\n ...services\n}", + "description": [], + "signature": [ + "React.PropsWithChildren<", + "NoDataCardServices", + ">" + ], + "path": "packages/shared-ux/page/no_data_config/impl/src/services.tsx", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/shared-ux-page-no-data-config", + "id": "def-common.NoDataConfigPageWithSolutionNavBar", + "type": "Function", + "tags": [], + "label": "NoDataConfigPageWithSolutionNavBar", + "description": [], + "signature": [ + "{ (props: ", + "Props", + " & { template?: \"default\" | \"empty\" | \"centeredBody\" | \"centeredContent\" | undefined; paddingSize?: \"none\" | \"m\" | \"s\" | \"l\" | undefined; pageSideBar?: React.ReactNode; pageSideBarProps?: ", + "EuiPageSideBarProps", + " | undefined; pageHeader?: ", + "EuiPageHeaderProps", + " | undefined; pageBodyProps?: ", + "EuiPageBodyProps", + "<\"main\"> | undefined; pageContentProps?: ", + "EuiPageContentProps", + " | undefined; pageContentBodyProps?: ", + "EuiPageContentBodyProps", + " | undefined; bottomBar?: React.ReactNode; bottomBarProps?: ", + "EuiBottomBarProps", + " | undefined; fullHeight?: boolean | \"noscroll\" | undefined; minHeight?: ", + "Property", + ".MinHeight | undefined; } & { noDataConfig?: ", + "NoDataPageProps", + " | undefined; }>): JSX.Element; displayName: string; }" + ], + "path": "packages/shared-ux/page/no_data_config/impl/src/no_data_config_page.tsx", + "deprecated": false, + "returnComment": [], + "children": [ + { + "parentPluginId": "@kbn/shared-ux-page-no-data-config", + "id": "def-common.NoDataConfigPageWithSolutionNavBar.$1", + "type": "CompoundType", + "tags": [], + "label": "props", + "description": [], + "signature": [ + "P & ", + "TemplateProps", + " & { isEmptyState?: boolean | undefined; } & { solutionNav: ", + "SolutionNavProps", + "; }" + ], + "path": "node_modules/@types/kbn__shared-ux-page-solution-nav/index.d.ts", + "deprecated": false + } + ], + "initialIsOpen": false + } + ], + "interfaces": [], + "enums": [], + "misc": [ + { + "parentPluginId": "@kbn/shared-ux-page-no-data-config", + "id": "def-common.NoDataConfigPageKibanaDependencies", + "type": "Type", + "tags": [], + "label": "NoDataConfigPageKibanaDependencies", + "description": [], + "signature": [ + "KibanaDependencies", + " & ", + "RedirectAppLinksKibanaDependencies" + ], + "path": "node_modules/@kbn/shared-ux-page-no-data-config-types/index.d.ts", + "deprecated": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/shared-ux-page-no-data-config", + "id": "def-common.NoDataConfigPageProps", + "type": "Type", + "tags": [], + "label": "NoDataConfigPageProps", + "description": [], + "signature": [ + "Omit<", + "EuiPageProps", + ", \"paddingSize\"> & { template?: \"default\" | \"empty\" | \"centeredBody\" | \"centeredContent\" | undefined; paddingSize?: \"none\" | \"m\" | \"s\" | \"l\" | undefined; pageSideBar?: React.ReactNode; pageSideBarProps?: ", + "EuiPageSideBarProps", + " | undefined; pageHeader?: ", + "EuiPageHeaderProps", + " | undefined; pageBodyProps?: ", + "EuiPageBodyProps", + "<\"main\"> | undefined; pageContentProps?: ", + "EuiPageContentProps", + " | undefined; pageContentBodyProps?: ", + "EuiPageContentBodyProps", + " | undefined; bottomBar?: React.ReactNode; bottomBarProps?: ", + "EuiBottomBarProps", + " | undefined; fullHeight?: boolean | \"noscroll\" | undefined; minHeight?: ", + "Property", + ".MinHeight | undefined; } & { noDataConfig?: ", + "NoDataPageProps", + " | undefined; }" + ], + "path": "node_modules/@kbn/shared-ux-page-no-data-config-types/index.d.ts", + "deprecated": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/shared-ux-page-no-data-config", + "id": "def-common.NoDataConfigPageServices", + "type": "Type", + "tags": [], + "label": "NoDataConfigPageServices", + "description": [], + "signature": [ + "Services", + " & ", + "RedirectAppLinksServices" + ], + "path": "node_modules/@kbn/shared-ux-page-no-data-config-types/index.d.ts", + "deprecated": false, + "initialIsOpen": false + } + ], + "objects": [] + } +} \ No newline at end of file diff --git a/api_docs/kbn_shared_ux_storybook.mdx b/api_docs/kbn_shared_ux_page_no_data_config.mdx similarity index 50% rename from api_docs/kbn_shared_ux_storybook.mdx rename to api_docs/kbn_shared_ux_page_no_data_config.mdx index fcf41351eaff2b..1631d5b1a3613c 100644 --- a/api_docs/kbn_shared_ux_storybook.mdx +++ b/api_docs/kbn_shared_ux_page_no_data_config.mdx @@ -3,15 +3,15 @@ #### This document is auto-generated and is meant to be viewed inside our experimental, new docs system. #### Reach out in #docs-engineering for more info. #### -id: kibKbnSharedUxStorybookPluginApi -slug: /kibana-dev-docs/api/kbn-shared-ux-storybook -title: "@kbn/shared-ux-storybook" +id: kibKbnSharedUxPageNoDataConfigPluginApi +slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data-config +title: "@kbn/shared-ux-page-no-data-config" image: https://source.unsplash.com/400x175/?github -description: API docs for the @kbn/shared-ux-storybook plugin -date: 2022-08-17 -tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-storybook'] +description: API docs for the @kbn/shared-ux-page-no-data-config plugin +date: 2022-08-24 +tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-no-data-config'] --- -import kbnSharedUxStorybookObj from './kbn_shared_ux_storybook.devdocs.json'; +import kbnSharedUxPageNoDataConfigObj from './kbn_shared_ux_page_no_data_config.devdocs.json'; @@ -21,13 +21,13 @@ Contact [Owner missing] for questions regarding this plugin. | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 16 | 0 | 7 | 0 | +| 11 | 0 | 5 | 0 | ## Common ### Functions - + -### Interfaces - +### Consts, variables and types + diff --git a/api_docs/kbn_shared_ux_page_no_data_config_mocks.devdocs.json b/api_docs/kbn_shared_ux_page_no_data_config_mocks.devdocs.json new file mode 100644 index 00000000000000..9cff904b1bb17c --- /dev/null +++ b/api_docs/kbn_shared_ux_page_no_data_config_mocks.devdocs.json @@ -0,0 +1,380 @@ +{ + "id": "@kbn/shared-ux-page-no-data-config-mocks", + "client": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "server": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "common": { + "classes": [ + { + "parentPluginId": "@kbn/shared-ux-page-no-data-config-mocks", + "id": "def-common.NoDataConfigPageStorybookMock", + "type": "Class", + "tags": [], + "label": "NoDataConfigPageStorybookMock", + "description": [], + "signature": [ + { + "pluginId": "@kbn/shared-ux-page-no-data-config-mocks", + "scope": "common", + "docId": "kibKbnSharedUxPageNoDataConfigMocksPluginApi", + "section": "def-common.NoDataConfigPageStorybookMock", + "text": "NoDataConfigPageStorybookMock" + }, + " extends ", + "AbstractStorybookMock", + "<", + "NoDataConfigPageProps", + ", ", + "NoDataCardServices", + ", PropArguments, {}>" + ], + "path": "packages/shared-ux/page/no_data_config/mocks/src/storybook.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/shared-ux-page-no-data-config-mocks", + "id": "def-common.NoDataConfigPageStorybookMock.propArguments", + "type": "Object", + "tags": [], + "label": "propArguments", + "description": [], + "path": "packages/shared-ux/page/no_data_config/mocks/src/storybook.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/shared-ux-page-no-data-config-mocks", + "id": "def-common.NoDataConfigPageStorybookMock.propArguments.solution", + "type": "Object", + "tags": [], + "label": "solution", + "description": [], + "path": "packages/shared-ux/page/no_data_config/mocks/src/storybook.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/shared-ux-page-no-data-config-mocks", + "id": "def-common.NoDataConfigPageStorybookMock.propArguments.solution.control", + "type": "string", + "tags": [], + "label": "control", + "description": [], + "path": "packages/shared-ux/page/no_data_config/mocks/src/storybook.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/shared-ux-page-no-data-config-mocks", + "id": "def-common.NoDataConfigPageStorybookMock.propArguments.solution.defaultValue", + "type": "string", + "tags": [], + "label": "defaultValue", + "description": [], + "path": "packages/shared-ux/page/no_data_config/mocks/src/storybook.ts", + "deprecated": false + } + ] + }, + { + "parentPluginId": "@kbn/shared-ux-page-no-data-config-mocks", + "id": "def-common.NoDataConfigPageStorybookMock.propArguments.logo", + "type": "Object", + "tags": [], + "label": "logo", + "description": [], + "path": "packages/shared-ux/page/no_data_config/mocks/src/storybook.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/shared-ux-page-no-data-config-mocks", + "id": "def-common.NoDataConfigPageStorybookMock.propArguments.logo.control", + "type": "Object", + "tags": [], + "label": "control", + "description": [], + "path": "packages/shared-ux/page/no_data_config/mocks/src/storybook.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/shared-ux-page-no-data-config-mocks", + "id": "def-common.NoDataConfigPageStorybookMock.propArguments.logo.control.type", + "type": "string", + "tags": [], + "label": "type", + "description": [], + "path": "packages/shared-ux/page/no_data_config/mocks/src/storybook.ts", + "deprecated": false + } + ] + }, + { + "parentPluginId": "@kbn/shared-ux-page-no-data-config-mocks", + "id": "def-common.NoDataConfigPageStorybookMock.propArguments.logo.options", + "type": "Array", + "tags": [], + "label": "options", + "description": [], + "signature": [ + "(string | undefined)[]" + ], + "path": "packages/shared-ux/page/no_data_config/mocks/src/storybook.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/shared-ux-page-no-data-config-mocks", + "id": "def-common.NoDataConfigPageStorybookMock.propArguments.logo.defaultValue", + "type": "Uncategorized", + "tags": [], + "label": "defaultValue", + "description": [], + "signature": [ + "undefined" + ], + "path": "packages/shared-ux/page/no_data_config/mocks/src/storybook.ts", + "deprecated": false + } + ] + }, + { + "parentPluginId": "@kbn/shared-ux-page-no-data-config-mocks", + "id": "def-common.NoDataConfigPageStorybookMock.propArguments.docsLink", + "type": "Object", + "tags": [], + "label": "docsLink", + "description": [], + "path": "packages/shared-ux/page/no_data_config/mocks/src/storybook.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/shared-ux-page-no-data-config-mocks", + "id": "def-common.NoDataConfigPageStorybookMock.propArguments.docsLink.control", + "type": "string", + "tags": [], + "label": "control", + "description": [], + "path": "packages/shared-ux/page/no_data_config/mocks/src/storybook.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/shared-ux-page-no-data-config-mocks", + "id": "def-common.NoDataConfigPageStorybookMock.propArguments.docsLink.defaultValue", + "type": "string", + "tags": [], + "label": "defaultValue", + "description": [], + "path": "packages/shared-ux/page/no_data_config/mocks/src/storybook.ts", + "deprecated": false + } + ] + }, + { + "parentPluginId": "@kbn/shared-ux-page-no-data-config-mocks", + "id": "def-common.NoDataConfigPageStorybookMock.propArguments.pageTitle", + "type": "Object", + "tags": [], + "label": "pageTitle", + "description": [], + "path": "packages/shared-ux/page/no_data_config/mocks/src/storybook.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/shared-ux-page-no-data-config-mocks", + "id": "def-common.NoDataConfigPageStorybookMock.propArguments.pageTitle.control", + "type": "string", + "tags": [], + "label": "control", + "description": [], + "path": "packages/shared-ux/page/no_data_config/mocks/src/storybook.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/shared-ux-page-no-data-config-mocks", + "id": "def-common.NoDataConfigPageStorybookMock.propArguments.pageTitle.defaultValue", + "type": "string", + "tags": [], + "label": "defaultValue", + "description": [], + "path": "packages/shared-ux/page/no_data_config/mocks/src/storybook.ts", + "deprecated": false + } + ] + } + ] + }, + { + "parentPluginId": "@kbn/shared-ux-page-no-data-config-mocks", + "id": "def-common.NoDataConfigPageStorybookMock.serviceArguments", + "type": "Object", + "tags": [], + "label": "serviceArguments", + "description": [], + "path": "packages/shared-ux/page/no_data_config/mocks/src/storybook.ts", + "deprecated": false, + "children": [] + }, + { + "parentPluginId": "@kbn/shared-ux-page-no-data-config-mocks", + "id": "def-common.NoDataConfigPageStorybookMock.dependencies", + "type": "Array", + "tags": [], + "label": "dependencies", + "description": [], + "signature": [ + "NoDataPageStorybookMock", + "[]" + ], + "path": "packages/shared-ux/page/no_data_config/mocks/src/storybook.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/shared-ux-page-no-data-config-mocks", + "id": "def-common.NoDataConfigPageStorybookMock.getProps", + "type": "Function", + "tags": [], + "label": "getProps", + "description": [], + "signature": [ + "(params?: ", + { + "pluginId": "@kbn/shared-ux-page-no-data-config-mocks", + "scope": "common", + "docId": "kibKbnSharedUxPageNoDataConfigMocksPluginApi", + "section": "def-common.Params", + "text": "Params" + }, + " | undefined) => ", + "NoDataConfigPageProps" + ], + "path": "packages/shared-ux/page/no_data_config/mocks/src/storybook.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/shared-ux-page-no-data-config-mocks", + "id": "def-common.NoDataConfigPageStorybookMock.getProps.$1", + "type": "CompoundType", + "tags": [], + "label": "params", + "description": [], + "signature": [ + { + "pluginId": "@kbn/shared-ux-page-no-data-config-mocks", + "scope": "common", + "docId": "kibKbnSharedUxPageNoDataConfigMocksPluginApi", + "section": "def-common.Params", + "text": "Params" + }, + " | undefined" + ], + "path": "packages/shared-ux/page/no_data_config/mocks/src/storybook.ts", + "deprecated": false, + "isRequired": false + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/shared-ux-page-no-data-config-mocks", + "id": "def-common.NoDataConfigPageStorybookMock.getServices", + "type": "Function", + "tags": [], + "label": "getServices", + "description": [], + "signature": [ + "(params: ", + { + "pluginId": "@kbn/shared-ux-page-no-data-config-mocks", + "scope": "common", + "docId": "kibKbnSharedUxPageNoDataConfigMocksPluginApi", + "section": "def-common.Params", + "text": "Params" + }, + ") => ", + "NoDataCardServices" + ], + "path": "packages/shared-ux/page/no_data_config/mocks/src/storybook.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/shared-ux-page-no-data-config-mocks", + "id": "def-common.NoDataConfigPageStorybookMock.getServices.$1", + "type": "CompoundType", + "tags": [], + "label": "params", + "description": [], + "signature": [ + { + "pluginId": "@kbn/shared-ux-page-no-data-config-mocks", + "scope": "common", + "docId": "kibKbnSharedUxPageNoDataConfigMocksPluginApi", + "section": "def-common.Params", + "text": "Params" + } + ], + "path": "packages/shared-ux/page/no_data_config/mocks/src/storybook.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + } + ], + "initialIsOpen": false + } + ], + "functions": [ + { + "parentPluginId": "@kbn/shared-ux-page-no-data-config-mocks", + "id": "def-common.getServicesMock", + "type": "Function", + "tags": [], + "label": "getServicesMock", + "description": [], + "signature": [ + "() => ", + "NoDataCardServices" + ], + "path": "packages/shared-ux/page/no_data_config/mocks/src/jest.ts", + "deprecated": false, + "children": [], + "returnComment": [], + "initialIsOpen": false + } + ], + "interfaces": [], + "enums": [], + "misc": [ + { + "parentPluginId": "@kbn/shared-ux-page-no-data-config-mocks", + "id": "def-common.Params", + "type": "Type", + "tags": [], + "label": "Params", + "description": [], + "signature": [ + "ArgumentParams", + " & ", + "ArgumentParams", + "<", + "PropArguments", + ", {}> & ", + "NoDataCardStorybookParams" + ], + "path": "packages/shared-ux/page/no_data_config/mocks/src/storybook.ts", + "deprecated": false, + "initialIsOpen": false + } + ], + "objects": [] + } +} \ No newline at end of file diff --git a/api_docs/kbn_shared_ux_page_no_data_config_mocks.mdx b/api_docs/kbn_shared_ux_page_no_data_config_mocks.mdx new file mode 100644 index 00000000000000..d382f2d63ea9c6 --- /dev/null +++ b/api_docs/kbn_shared_ux_page_no_data_config_mocks.mdx @@ -0,0 +1,36 @@ +--- +#### +#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system. +#### Reach out in #docs-engineering for more info. +#### +id: kibKbnSharedUxPageNoDataConfigMocksPluginApi +slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data-config-mocks +title: "@kbn/shared-ux-page-no-data-config-mocks" +image: https://source.unsplash.com/400x175/?github +description: API docs for the @kbn/shared-ux-page-no-data-config-mocks plugin +date: 2022-08-24 +tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-no-data-config-mocks'] +--- +import kbnSharedUxPageNoDataConfigMocksObj from './kbn_shared_ux_page_no_data_config_mocks.devdocs.json'; + + + +Contact [Owner missing] for questions regarding this plugin. + +**Code health stats** + +| Public API count | Any count | Items lacking comments | Missing exports | +|-------------------|-----------|------------------------|-----------------| +| 24 | 0 | 24 | 0 | + +## Common + +### Functions + + +### Classes + + +### Consts, variables and types + + diff --git a/api_docs/kbn_shared_ux_page_no_data_mocks.devdocs.json b/api_docs/kbn_shared_ux_page_no_data_mocks.devdocs.json new file mode 100644 index 00000000000000..76c026ad3a55db --- /dev/null +++ b/api_docs/kbn_shared_ux_page_no_data_mocks.devdocs.json @@ -0,0 +1,433 @@ +{ + "id": "@kbn/shared-ux-page-no-data-mocks", + "client": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "server": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "common": { + "classes": [ + { + "parentPluginId": "@kbn/shared-ux-page-no-data-mocks", + "id": "def-common.NoDataPageStorybookMock", + "type": "Class", + "tags": [], + "label": "NoDataPageStorybookMock", + "description": [], + "signature": [ + { + "pluginId": "@kbn/shared-ux-page-no-data-mocks", + "scope": "common", + "docId": "kibKbnSharedUxPageNoDataMocksPluginApi", + "section": "def-common.NoDataPageStorybookMock", + "text": "NoDataPageStorybookMock" + }, + " extends ", + "AbstractStorybookMock", + "<", + "NoDataPageProps", + ", ", + "NoDataCardServices", + ", PropArguments, {}>" + ], + "path": "packages/shared-ux/page/no_data/mocks/src/storybook.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/shared-ux-page-no-data-mocks", + "id": "def-common.NoDataPageStorybookMock.propArguments", + "type": "Object", + "tags": [], + "label": "propArguments", + "description": [], + "path": "packages/shared-ux/page/no_data/mocks/src/storybook.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/shared-ux-page-no-data-mocks", + "id": "def-common.NoDataPageStorybookMock.propArguments.solution", + "type": "Object", + "tags": [], + "label": "solution", + "description": [], + "path": "packages/shared-ux/page/no_data/mocks/src/storybook.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/shared-ux-page-no-data-mocks", + "id": "def-common.NoDataPageStorybookMock.propArguments.solution.control", + "type": "string", + "tags": [], + "label": "control", + "description": [], + "path": "packages/shared-ux/page/no_data/mocks/src/storybook.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/shared-ux-page-no-data-mocks", + "id": "def-common.NoDataPageStorybookMock.propArguments.solution.defaultValue", + "type": "string", + "tags": [], + "label": "defaultValue", + "description": [], + "path": "packages/shared-ux/page/no_data/mocks/src/storybook.ts", + "deprecated": false + } + ] + }, + { + "parentPluginId": "@kbn/shared-ux-page-no-data-mocks", + "id": "def-common.NoDataPageStorybookMock.propArguments.logo", + "type": "Object", + "tags": [], + "label": "logo", + "description": [], + "path": "packages/shared-ux/page/no_data/mocks/src/storybook.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/shared-ux-page-no-data-mocks", + "id": "def-common.NoDataPageStorybookMock.propArguments.logo.control", + "type": "Object", + "tags": [], + "label": "control", + "description": [], + "path": "packages/shared-ux/page/no_data/mocks/src/storybook.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/shared-ux-page-no-data-mocks", + "id": "def-common.NoDataPageStorybookMock.propArguments.logo.control.type", + "type": "string", + "tags": [], + "label": "type", + "description": [], + "path": "packages/shared-ux/page/no_data/mocks/src/storybook.ts", + "deprecated": false + } + ] + }, + { + "parentPluginId": "@kbn/shared-ux-page-no-data-mocks", + "id": "def-common.NoDataPageStorybookMock.propArguments.logo.options", + "type": "Array", + "tags": [], + "label": "options", + "description": [], + "signature": [ + "(string | undefined)[]" + ], + "path": "packages/shared-ux/page/no_data/mocks/src/storybook.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/shared-ux-page-no-data-mocks", + "id": "def-common.NoDataPageStorybookMock.propArguments.logo.defaultValue", + "type": "Uncategorized", + "tags": [], + "label": "defaultValue", + "description": [], + "signature": [ + "undefined" + ], + "path": "packages/shared-ux/page/no_data/mocks/src/storybook.ts", + "deprecated": false + } + ] + }, + { + "parentPluginId": "@kbn/shared-ux-page-no-data-mocks", + "id": "def-common.NoDataPageStorybookMock.propArguments.docsLink", + "type": "Object", + "tags": [], + "label": "docsLink", + "description": [], + "path": "packages/shared-ux/page/no_data/mocks/src/storybook.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/shared-ux-page-no-data-mocks", + "id": "def-common.NoDataPageStorybookMock.propArguments.docsLink.control", + "type": "string", + "tags": [], + "label": "control", + "description": [], + "path": "packages/shared-ux/page/no_data/mocks/src/storybook.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/shared-ux-page-no-data-mocks", + "id": "def-common.NoDataPageStorybookMock.propArguments.docsLink.defaultValue", + "type": "string", + "tags": [], + "label": "defaultValue", + "description": [], + "path": "packages/shared-ux/page/no_data/mocks/src/storybook.ts", + "deprecated": false + } + ] + }, + { + "parentPluginId": "@kbn/shared-ux-page-no-data-mocks", + "id": "def-common.NoDataPageStorybookMock.propArguments.pageTitle", + "type": "Object", + "tags": [], + "label": "pageTitle", + "description": [], + "path": "packages/shared-ux/page/no_data/mocks/src/storybook.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/shared-ux-page-no-data-mocks", + "id": "def-common.NoDataPageStorybookMock.propArguments.pageTitle.control", + "type": "string", + "tags": [], + "label": "control", + "description": [], + "path": "packages/shared-ux/page/no_data/mocks/src/storybook.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/shared-ux-page-no-data-mocks", + "id": "def-common.NoDataPageStorybookMock.propArguments.pageTitle.defaultValue", + "type": "string", + "tags": [], + "label": "defaultValue", + "description": [], + "path": "packages/shared-ux/page/no_data/mocks/src/storybook.ts", + "deprecated": false + } + ] + } + ] + }, + { + "parentPluginId": "@kbn/shared-ux-page-no-data-mocks", + "id": "def-common.NoDataPageStorybookMock.serviceArguments", + "type": "Object", + "tags": [], + "label": "serviceArguments", + "description": [], + "path": "packages/shared-ux/page/no_data/mocks/src/storybook.ts", + "deprecated": false, + "children": [] + }, + { + "parentPluginId": "@kbn/shared-ux-page-no-data-mocks", + "id": "def-common.NoDataPageStorybookMock.dependencies", + "type": "Array", + "tags": [], + "label": "dependencies", + "description": [], + "signature": [ + "NoDataCardStorybookMock", + "[]" + ], + "path": "packages/shared-ux/page/no_data/mocks/src/storybook.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/shared-ux-page-no-data-mocks", + "id": "def-common.NoDataPageStorybookMock.getProps", + "type": "Function", + "tags": [], + "label": "getProps", + "description": [], + "signature": [ + "(params?: ", + { + "pluginId": "@kbn/shared-ux-page-no-data-mocks", + "scope": "common", + "docId": "kibKbnSharedUxPageNoDataMocksPluginApi", + "section": "def-common.Params", + "text": "Params" + }, + " | undefined) => ", + "NoDataPageProps" + ], + "path": "packages/shared-ux/page/no_data/mocks/src/storybook.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/shared-ux-page-no-data-mocks", + "id": "def-common.NoDataPageStorybookMock.getProps.$1", + "type": "CompoundType", + "tags": [], + "label": "params", + "description": [], + "signature": [ + { + "pluginId": "@kbn/shared-ux-page-no-data-mocks", + "scope": "common", + "docId": "kibKbnSharedUxPageNoDataMocksPluginApi", + "section": "def-common.Params", + "text": "Params" + }, + " | undefined" + ], + "path": "packages/shared-ux/page/no_data/mocks/src/storybook.ts", + "deprecated": false, + "isRequired": false + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/shared-ux-page-no-data-mocks", + "id": "def-common.NoDataPageStorybookMock.getServices", + "type": "Function", + "tags": [], + "label": "getServices", + "description": [], + "signature": [ + "(params: ", + { + "pluginId": "@kbn/shared-ux-page-no-data-mocks", + "scope": "common", + "docId": "kibKbnSharedUxPageNoDataMocksPluginApi", + "section": "def-common.Params", + "text": "Params" + }, + ") => ", + "NoDataCardServices" + ], + "path": "packages/shared-ux/page/no_data/mocks/src/storybook.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/shared-ux-page-no-data-mocks", + "id": "def-common.NoDataPageStorybookMock.getServices.$1", + "type": "CompoundType", + "tags": [], + "label": "params", + "description": [], + "signature": [ + { + "pluginId": "@kbn/shared-ux-page-no-data-mocks", + "scope": "common", + "docId": "kibKbnSharedUxPageNoDataMocksPluginApi", + "section": "def-common.Params", + "text": "Params" + } + ], + "path": "packages/shared-ux/page/no_data/mocks/src/storybook.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + } + ], + "initialIsOpen": false + } + ], + "functions": [ + { + "parentPluginId": "@kbn/shared-ux-page-no-data-mocks", + "id": "def-common.getKibanaDependenciesMock", + "type": "Function", + "tags": [], + "label": "getKibanaDependenciesMock", + "description": [ + "\nReturn a Jest mock of the Kibana dependencies for the `NoDataPageKibanaProvider`." + ], + "signature": [ + "(params?: Partial<", + "NoDataCardServices", + ">) => ", + "NoDataCardKibanaDependencies" + ], + "path": "packages/shared-ux/page/no_data/mocks/src/jest.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/shared-ux-page-no-data-mocks", + "id": "def-common.getKibanaDependenciesMock.$1", + "type": "Object", + "tags": [], + "label": "params", + "description": [], + "signature": [ + "Partial<", + "NoDataCardServices", + ">" + ], + "path": "packages/shared-ux/page/no_data/mocks/src/jest.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/shared-ux-page-no-data-mocks", + "id": "def-common.getServicesMock", + "type": "Function", + "tags": [], + "label": "getServicesMock", + "description": [], + "signature": [ + "(params?: Partial<", + "NoDataCardServices", + ">) => ", + "NoDataCardServices" + ], + "path": "packages/shared-ux/page/no_data/mocks/src/jest.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/shared-ux-page-no-data-mocks", + "id": "def-common.getServicesMock.$1", + "type": "Object", + "tags": [], + "label": "params", + "description": [], + "signature": [ + "Partial<", + "NoDataCardServices", + ">" + ], + "path": "packages/shared-ux/page/no_data/mocks/src/jest.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + } + ], + "interfaces": [], + "enums": [], + "misc": [ + { + "parentPluginId": "@kbn/shared-ux-page-no-data-mocks", + "id": "def-common.Params", + "type": "Type", + "tags": [], + "label": "Params", + "description": [], + "signature": [ + "ArgumentParams", + " & ", + "NoDataCardStorybookParams" + ], + "path": "packages/shared-ux/page/no_data/mocks/src/storybook.ts", + "deprecated": false, + "initialIsOpen": false + } + ], + "objects": [] + } +} \ No newline at end of file diff --git a/api_docs/kbn_shared_ux_page_no_data_mocks.mdx b/api_docs/kbn_shared_ux_page_no_data_mocks.mdx new file mode 100644 index 00000000000000..9d124843350e5b --- /dev/null +++ b/api_docs/kbn_shared_ux_page_no_data_mocks.mdx @@ -0,0 +1,36 @@ +--- +#### +#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system. +#### Reach out in #docs-engineering for more info. +#### +id: kibKbnSharedUxPageNoDataMocksPluginApi +slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data-mocks +title: "@kbn/shared-ux-page-no-data-mocks" +image: https://source.unsplash.com/400x175/?github +description: API docs for the @kbn/shared-ux-page-no-data-mocks plugin +date: 2022-08-24 +tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-no-data-mocks'] +--- +import kbnSharedUxPageNoDataMocksObj from './kbn_shared_ux_page_no_data_mocks.devdocs.json'; + + + +Contact [Owner missing] for questions regarding this plugin. + +**Code health stats** + +| Public API count | Any count | Items lacking comments | Missing exports | +|-------------------|-----------|------------------------|-----------------| +| 27 | 0 | 26 | 0 | + +## Common + +### Functions + + +### Classes + + +### Consts, variables and types + + diff --git a/api_docs/kbn_shared_ux_page_solution_nav.mdx b/api_docs/kbn_shared_ux_page_solution_nav.mdx index e8c5b20c053f0a..fad24dc217be3b 100644 --- a/api_docs/kbn_shared_ux_page_solution_nav.mdx +++ b/api_docs/kbn_shared_ux_page_solution_nav.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-solution-nav title: "@kbn/shared-ux-page-solution-nav" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-solution-nav plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-solution-nav'] --- import kbnSharedUxPageSolutionNavObj from './kbn_shared_ux_page_solution_nav.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_prompt_no_data_views.devdocs.json b/api_docs/kbn_shared_ux_prompt_no_data_views.devdocs.json index 3c2025f7d0d9ee..6b323a41bb51dc 100644 --- a/api_docs/kbn_shared_ux_prompt_no_data_views.devdocs.json +++ b/api_docs/kbn_shared_ux_prompt_no_data_views.devdocs.json @@ -100,7 +100,7 @@ ], "signature": [ "({ children, ...services }: React.PropsWithChildren<", - "NoDataViewsPromptKibanaServices", + "NoDataViewsPromptKibanaDependencies", ">) => JSX.Element" ], "path": "packages/shared-ux/prompt/no_data_views/impl/src/services.tsx", @@ -115,7 +115,7 @@ "description": [], "signature": [ "React.PropsWithChildren<", - "NoDataViewsPromptKibanaServices", + "NoDataViewsPromptKibanaDependencies", ">" ], "path": "packages/shared-ux/prompt/no_data_views/impl/src/services.tsx", @@ -229,7 +229,7 @@ "The background color of the prompt; defaults to `plain`." ], "signature": [ - "\"warning\" | \"primary\" | \"success\" | \"accent\" | \"danger\" | \"subdued\" | \"transparent\" | \"plain\" | undefined" + "\"warning\" | \"subdued\" | \"primary\" | \"accent\" | \"success\" | \"danger\" | \"transparent\" | \"plain\" | undefined" ], "path": "node_modules/@kbn/shared-ux-prompt-no-data-views-types/index.d.ts", "deprecated": false @@ -239,10 +239,10 @@ }, { "parentPluginId": "@kbn/shared-ux-prompt-no-data-views", - "id": "def-common.NoDataViewsPromptKibanaServices", + "id": "def-common.NoDataViewsPromptKibanaDependencies", "type": "Interface", "tags": [], - "label": "NoDataViewsPromptKibanaServices", + "label": "NoDataViewsPromptKibanaDependencies", "description": [ "\nKibana-specific service types." ], @@ -251,7 +251,7 @@ "children": [ { "parentPluginId": "@kbn/shared-ux-prompt-no-data-views", - "id": "def-common.NoDataViewsPromptKibanaServices.coreStart", + "id": "def-common.NoDataViewsPromptKibanaDependencies.coreStart", "type": "Object", "tags": [], "label": "coreStart", @@ -264,7 +264,7 @@ }, { "parentPluginId": "@kbn/shared-ux-prompt-no-data-views", - "id": "def-common.NoDataViewsPromptKibanaServices.dataViewEditor", + "id": "def-common.NoDataViewsPromptKibanaDependencies.dataViewEditor", "type": "Object", "tags": [], "label": "dataViewEditor", diff --git a/api_docs/kbn_shared_ux_prompt_no_data_views.mdx b/api_docs/kbn_shared_ux_prompt_no_data_views.mdx index 12046d407f978c..d766b083bb3fab 100644 --- a/api_docs/kbn_shared_ux_prompt_no_data_views.mdx +++ b/api_docs/kbn_shared_ux_prompt_no_data_views.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-prompt-no-data-views title: "@kbn/shared-ux-prompt-no-data-views" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-prompt-no-data-views plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-prompt-no-data-views'] --- import kbnSharedUxPromptNoDataViewsObj from './kbn_shared_ux_prompt_no_data_views.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.devdocs.json b/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.devdocs.json index 33f49ec84b7fa1..6ce6b2d959557b 100644 --- a/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.devdocs.json +++ b/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.devdocs.json @@ -9,10 +9,18 @@ "objects": [] }, "server": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "common": { "classes": [ { "parentPluginId": "@kbn/shared-ux-prompt-no-data-views-mocks", - "id": "def-server.StorybookMock", + "id": "def-common.StorybookMock", "type": "Class", "tags": [], "label": "StorybookMock", @@ -20,9 +28,9 @@ "signature": [ { "pluginId": "@kbn/shared-ux-prompt-no-data-views-mocks", - "scope": "server", + "scope": "common", "docId": "kibKbnSharedUxPromptNoDataViewsMocksPluginApi", - "section": "def-server.StorybookMock", + "section": "def-common.StorybookMock", "text": "StorybookMock" }, " extends ", @@ -38,7 +46,7 @@ "children": [ { "parentPluginId": "@kbn/shared-ux-prompt-no-data-views-mocks", - "id": "def-server.StorybookMock.propArguments", + "id": "def-common.StorybookMock.propArguments", "type": "Object", "tags": [], "label": "propArguments", @@ -49,7 +57,7 @@ }, { "parentPluginId": "@kbn/shared-ux-prompt-no-data-views-mocks", - "id": "def-server.StorybookMock.serviceArguments", + "id": "def-common.StorybookMock.serviceArguments", "type": "Object", "tags": [], "label": "serviceArguments", @@ -59,7 +67,7 @@ "children": [ { "parentPluginId": "@kbn/shared-ux-prompt-no-data-views-mocks", - "id": "def-server.StorybookMock.serviceArguments.canCreateNewDataView", + "id": "def-common.StorybookMock.serviceArguments.canCreateNewDataView", "type": "Object", "tags": [], "label": "canCreateNewDataView", @@ -69,7 +77,7 @@ "children": [ { "parentPluginId": "@kbn/shared-ux-prompt-no-data-views-mocks", - "id": "def-server.StorybookMock.serviceArguments.canCreateNewDataView.control", + "id": "def-common.StorybookMock.serviceArguments.canCreateNewDataView.control", "type": "string", "tags": [], "label": "control", @@ -79,7 +87,7 @@ }, { "parentPluginId": "@kbn/shared-ux-prompt-no-data-views-mocks", - "id": "def-server.StorybookMock.serviceArguments.canCreateNewDataView.defaultValue", + "id": "def-common.StorybookMock.serviceArguments.canCreateNewDataView.defaultValue", "type": "boolean", "tags": [], "label": "defaultValue", @@ -91,7 +99,7 @@ }, { "parentPluginId": "@kbn/shared-ux-prompt-no-data-views-mocks", - "id": "def-server.StorybookMock.serviceArguments.dataViewsDocLink", + "id": "def-common.StorybookMock.serviceArguments.dataViewsDocLink", "type": "Object", "tags": [], "label": "dataViewsDocLink", @@ -101,7 +109,7 @@ "children": [ { "parentPluginId": "@kbn/shared-ux-prompt-no-data-views-mocks", - "id": "def-server.StorybookMock.serviceArguments.dataViewsDocLink.options", + "id": "def-common.StorybookMock.serviceArguments.dataViewsDocLink.options", "type": "Array", "tags": [], "label": "options", @@ -114,7 +122,7 @@ }, { "parentPluginId": "@kbn/shared-ux-prompt-no-data-views-mocks", - "id": "def-server.StorybookMock.serviceArguments.dataViewsDocLink.control", + "id": "def-common.StorybookMock.serviceArguments.dataViewsDocLink.control", "type": "Object", "tags": [], "label": "control", @@ -124,7 +132,7 @@ "children": [ { "parentPluginId": "@kbn/shared-ux-prompt-no-data-views-mocks", - "id": "def-server.StorybookMock.serviceArguments.dataViewsDocLink.control.type", + "id": "def-common.StorybookMock.serviceArguments.dataViewsDocLink.control.type", "type": "string", "tags": [], "label": "type", @@ -140,7 +148,7 @@ }, { "parentPluginId": "@kbn/shared-ux-prompt-no-data-views-mocks", - "id": "def-server.StorybookMock.dependencies", + "id": "def-common.StorybookMock.dependencies", "type": "Array", "tags": [], "label": "dependencies", @@ -153,7 +161,7 @@ }, { "parentPluginId": "@kbn/shared-ux-prompt-no-data-views-mocks", - "id": "def-server.StorybookMock.getProps", + "id": "def-common.StorybookMock.getProps", "type": "Function", "tags": [], "label": "getProps", @@ -170,7 +178,7 @@ }, { "parentPluginId": "@kbn/shared-ux-prompt-no-data-views-mocks", - "id": "def-server.StorybookMock.getServices", + "id": "def-common.StorybookMock.getServices", "type": "Function", "tags": [], "label": "getServices", @@ -179,9 +187,9 @@ "(params: ", { "pluginId": "@kbn/shared-ux-prompt-no-data-views-mocks", - "scope": "server", + "scope": "common", "docId": "kibKbnSharedUxPromptNoDataViewsMocksPluginApi", - "section": "def-server.Params", + "section": "def-common.Params", "text": "Params" }, ") => ", @@ -192,7 +200,7 @@ "children": [ { "parentPluginId": "@kbn/shared-ux-prompt-no-data-views-mocks", - "id": "def-server.StorybookMock.getServices.$1", + "id": "def-common.StorybookMock.getServices.$1", "type": "Object", "tags": [], "label": "params", @@ -200,9 +208,9 @@ "signature": [ { "pluginId": "@kbn/shared-ux-prompt-no-data-views-mocks", - "scope": "server", + "scope": "common", "docId": "kibKbnSharedUxPromptNoDataViewsMocksPluginApi", - "section": "def-server.Params", + "section": "def-common.Params", "text": "Params" } ], @@ -220,7 +228,7 @@ "functions": [ { "parentPluginId": "@kbn/shared-ux-prompt-no-data-views-mocks", - "id": "def-server.getNoDataViewsPromptServicesMock", + "id": "def-common.getNoDataViewsPromptServicesMock", "type": "Function", "tags": [], "label": "getNoDataViewsPromptServicesMock", @@ -238,7 +246,7 @@ "children": [ { "parentPluginId": "@kbn/shared-ux-prompt-no-data-views-mocks", - "id": "def-server.getNoDataViewsPromptServicesMock.$1", + "id": "def-common.getNoDataViewsPromptServicesMock.$1", "type": "Object", "tags": [], "label": "params", @@ -262,7 +270,7 @@ "misc": [ { "parentPluginId": "@kbn/shared-ux-prompt-no-data-views-mocks", - "id": "def-server.Params", + "id": "def-common.Params", "type": "Type", "tags": [], "label": "Params", @@ -276,13 +284,5 @@ } ], "objects": [] - }, - "common": { - "classes": [], - "functions": [], - "interfaces": [], - "enums": [], - "misc": [], - "objects": [] } } \ No newline at end of file diff --git a/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.mdx b/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.mdx index 0369e29e6178c1..261ebce08b4f5f 100644 --- a/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.mdx +++ b/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-prompt-no-data-views-mocks title: "@kbn/shared-ux-prompt-no-data-views-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-prompt-no-data-views-mocks plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-prompt-no-data-views-mocks'] --- import kbnSharedUxPromptNoDataViewsMocksObj from './kbn_shared_ux_prompt_no_data_views_mocks.devdocs.json'; @@ -23,14 +23,14 @@ Contact [Owner missing] for questions regarding this plugin. |-------------------|-----------|------------------------|-----------------| | 17 | 0 | 16 | 0 | -## Server +## Common ### Functions - + ### Classes - + ### Consts, variables and types - + diff --git a/api_docs/kbn_shared_ux_services.devdocs.json b/api_docs/kbn_shared_ux_services.devdocs.json deleted file mode 100644 index b608a43ecc7448..00000000000000 --- a/api_docs/kbn_shared_ux_services.devdocs.json +++ /dev/null @@ -1,1568 +0,0 @@ -{ - "id": "@kbn/shared-ux-services", - "client": { - "classes": [], - "functions": [], - "interfaces": [], - "enums": [], - "misc": [], - "objects": [] - }, - "server": { - "classes": [], - "functions": [], - "interfaces": [], - "enums": [], - "misc": [], - "objects": [] - }, - "common": { - "classes": [], - "functions": [ - { - "parentPluginId": "@kbn/shared-ux-services", - "id": "def-common.mockServicesFactory", - "type": "Function", - "tags": [], - "label": "mockServicesFactory", - "description": [ - "\nA factory function for creating a Jest-based implementation of `SharedUxServices`." - ], - "signature": [ - "(params?: ", - { - "pluginId": "@kbn/shared-ux-services", - "scope": "common", - "docId": "kibKbnSharedUxServicesPluginApi", - "section": "def-common.MockServicesFactoryParams", - "text": "MockServicesFactoryParams" - }, - " | undefined) => { application: ", - { - "pluginId": "@kbn/shared-ux-services", - "scope": "common", - "docId": "kibKbnSharedUxServicesPluginApi", - "section": "def-common.SharedUxApplicationService", - "text": "SharedUxApplicationService" - }, - "; docLinks: ", - { - "pluginId": "@kbn/shared-ux-services", - "scope": "common", - "docId": "kibKbnSharedUxServicesPluginApi", - "section": "def-common.SharedUxDocLinksService", - "text": "SharedUxDocLinksService" - }, - "; editors: ", - { - "pluginId": "@kbn/shared-ux-services", - "scope": "common", - "docId": "kibKbnSharedUxServicesPluginApi", - "section": "def-common.SharedUxEditorsService", - "text": "SharedUxEditorsService" - }, - "; http: ", - { - "pluginId": "@kbn/shared-ux-services", - "scope": "common", - "docId": "kibKbnSharedUxServicesPluginApi", - "section": "def-common.SharedUxHttpService", - "text": "SharedUxHttpService" - }, - "; permissions: ", - { - "pluginId": "@kbn/shared-ux-services", - "scope": "common", - "docId": "kibKbnSharedUxServicesPluginApi", - "section": "def-common.SharedUxUserPermissionsService", - "text": "SharedUxUserPermissionsService" - }, - "; platform: ", - { - "pluginId": "@kbn/shared-ux-services", - "scope": "common", - "docId": "kibKbnSharedUxServicesPluginApi", - "section": "def-common.SharedUxPlatformService", - "text": "SharedUxPlatformService" - }, - "; data: ", - { - "pluginId": "@kbn/shared-ux-services", - "scope": "common", - "docId": "kibKbnSharedUxServicesPluginApi", - "section": "def-common.SharedUxDataService", - "text": "SharedUxDataService" - }, - "; }" - ], - "path": "packages/kbn-shared-ux-services/src/services/mock/index.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/shared-ux-services", - "id": "def-common.mockServicesFactory.$1", - "type": "Object", - "tags": [], - "label": "params", - "description": [], - "signature": [ - { - "pluginId": "@kbn/shared-ux-services", - "scope": "common", - "docId": "kibKbnSharedUxServicesPluginApi", - "section": "def-common.MockServicesFactoryParams", - "text": "MockServicesFactoryParams" - }, - " | undefined" - ], - "path": "packages/kbn-shared-ux-services/src/services/mock/index.ts", - "deprecated": false, - "isRequired": false - } - ], - "returnComment": [], - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/shared-ux-services", - "id": "def-common.SharedUxServicesProvider", - "type": "Function", - "tags": [], - "label": "SharedUxServicesProvider", - "description": [ - "\nThe `React.Context` Provider component for the `SharedUxServices` context. Any\nplugin or environment that consumes SharedUX components needs to wrap their React\ntree with this provider.\n\nWithin a plugin, you can use use the Shared UX plugin and retrieve a fully-configured\ncontext from the `start` contract." - ], - "signature": [ - "({ children, ...services }: React.PropsWithChildren<", - { - "pluginId": "@kbn/shared-ux-services", - "scope": "common", - "docId": "kibKbnSharedUxServicesPluginApi", - "section": "def-common.SharedUxServices", - "text": "SharedUxServices" - }, - ">) => JSX.Element" - ], - "path": "packages/kbn-shared-ux-services/src/context.tsx", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/shared-ux-services", - "id": "def-common.SharedUxServicesProvider.$1", - "type": "CompoundType", - "tags": [], - "label": "{ children, ...services }", - "description": [], - "signature": [ - "React.PropsWithChildren<", - { - "pluginId": "@kbn/shared-ux-services", - "scope": "common", - "docId": "kibKbnSharedUxServicesPluginApi", - "section": "def-common.SharedUxServices", - "text": "SharedUxServices" - }, - ">" - ], - "path": "packages/kbn-shared-ux-services/src/context.tsx", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [], - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/shared-ux-services", - "id": "def-common.stubServicesFactory", - "type": "Function", - "tags": [], - "label": "stubServicesFactory", - "description": [ - "\nA factory function for creating simple stubbed implementations of all `SharedUxServices`." - ], - "signature": [ - "() => { application: ", - { - "pluginId": "@kbn/shared-ux-services", - "scope": "common", - "docId": "kibKbnSharedUxServicesPluginApi", - "section": "def-common.SharedUxApplicationService", - "text": "SharedUxApplicationService" - }, - "; docLinks: ", - { - "pluginId": "@kbn/shared-ux-services", - "scope": "common", - "docId": "kibKbnSharedUxServicesPluginApi", - "section": "def-common.SharedUxDocLinksService", - "text": "SharedUxDocLinksService" - }, - "; editors: ", - { - "pluginId": "@kbn/shared-ux-services", - "scope": "common", - "docId": "kibKbnSharedUxServicesPluginApi", - "section": "def-common.SharedUxEditorsService", - "text": "SharedUxEditorsService" - }, - "; http: ", - { - "pluginId": "@kbn/shared-ux-services", - "scope": "common", - "docId": "kibKbnSharedUxServicesPluginApi", - "section": "def-common.SharedUxHttpService", - "text": "SharedUxHttpService" - }, - "; permissions: ", - { - "pluginId": "@kbn/shared-ux-services", - "scope": "common", - "docId": "kibKbnSharedUxServicesPluginApi", - "section": "def-common.SharedUxUserPermissionsService", - "text": "SharedUxUserPermissionsService" - }, - "; platform: ", - { - "pluginId": "@kbn/shared-ux-services", - "scope": "common", - "docId": "kibKbnSharedUxServicesPluginApi", - "section": "def-common.SharedUxPlatformService", - "text": "SharedUxPlatformService" - }, - "; data: ", - { - "pluginId": "@kbn/shared-ux-services", - "scope": "common", - "docId": "kibKbnSharedUxServicesPluginApi", - "section": "def-common.SharedUxDataService", - "text": "SharedUxDataService" - }, - "; }" - ], - "path": "packages/kbn-shared-ux-services/src/services/stub/index.ts", - "deprecated": false, - "children": [], - "returnComment": [], - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/shared-ux-services", - "id": "def-common.useApplication", - "type": "Function", - "tags": [], - "label": "useApplication", - "description": [], - "signature": [ - "() => ", - { - "pluginId": "@kbn/shared-ux-services", - "scope": "common", - "docId": "kibKbnSharedUxServicesPluginApi", - "section": "def-common.SharedUxApplicationService", - "text": "SharedUxApplicationService" - } - ], - "path": "packages/kbn-shared-ux-services/src/context.tsx", - "deprecated": false, - "children": [], - "returnComment": [], - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/shared-ux-services", - "id": "def-common.useData", - "type": "Function", - "tags": [], - "label": "useData", - "description": [ - "\nReact hook for accessing the pre-wired `SharedUxDataService`." - ], - "signature": [ - "() => ", - { - "pluginId": "@kbn/shared-ux-services", - "scope": "common", - "docId": "kibKbnSharedUxServicesPluginApi", - "section": "def-common.SharedUxDataService", - "text": "SharedUxDataService" - } - ], - "path": "packages/kbn-shared-ux-services/src/context.tsx", - "deprecated": false, - "children": [], - "returnComment": [], - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/shared-ux-services", - "id": "def-common.useDocLinks", - "type": "Function", - "tags": [], - "label": "useDocLinks", - "description": [ - "\nReact hook for accessing the pre-wired `SharedUxDocLinksService`." - ], - "signature": [ - "() => ", - { - "pluginId": "@kbn/shared-ux-services", - "scope": "common", - "docId": "kibKbnSharedUxServicesPluginApi", - "section": "def-common.SharedUxDocLinksService", - "text": "SharedUxDocLinksService" - } - ], - "path": "packages/kbn-shared-ux-services/src/context.tsx", - "deprecated": false, - "children": [], - "returnComment": [], - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/shared-ux-services", - "id": "def-common.useEditors", - "type": "Function", - "tags": [], - "label": "useEditors", - "description": [ - "\nReact hook for accessing the pre-wired `SharedUxEditorsService`." - ], - "signature": [ - "() => ", - { - "pluginId": "@kbn/shared-ux-services", - "scope": "common", - "docId": "kibKbnSharedUxServicesPluginApi", - "section": "def-common.SharedUxEditorsService", - "text": "SharedUxEditorsService" - } - ], - "path": "packages/kbn-shared-ux-services/src/context.tsx", - "deprecated": false, - "children": [], - "returnComment": [], - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/shared-ux-services", - "id": "def-common.useHttp", - "type": "Function", - "tags": [], - "label": "useHttp", - "description": [], - "signature": [ - "() => ", - { - "pluginId": "@kbn/shared-ux-services", - "scope": "common", - "docId": "kibKbnSharedUxServicesPluginApi", - "section": "def-common.SharedUxHttpService", - "text": "SharedUxHttpService" - } - ], - "path": "packages/kbn-shared-ux-services/src/context.tsx", - "deprecated": false, - "children": [], - "returnComment": [], - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/shared-ux-services", - "id": "def-common.usePermissions", - "type": "Function", - "tags": [], - "label": "usePermissions", - "description": [ - "\nReact hook for accessing the pre-wired `SharedUxPermissionsService`." - ], - "signature": [ - "() => ", - { - "pluginId": "@kbn/shared-ux-services", - "scope": "common", - "docId": "kibKbnSharedUxServicesPluginApi", - "section": "def-common.SharedUxUserPermissionsService", - "text": "SharedUxUserPermissionsService" - } - ], - "path": "packages/kbn-shared-ux-services/src/context.tsx", - "deprecated": false, - "children": [], - "returnComment": [], - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/shared-ux-services", - "id": "def-common.usePlatformService", - "type": "Function", - "tags": [], - "label": "usePlatformService", - "description": [ - "\nReact hook for accessing the pre-wired `SharedUxPlatformService`." - ], - "signature": [ - "() => ", - { - "pluginId": "@kbn/shared-ux-services", - "scope": "common", - "docId": "kibKbnSharedUxServicesPluginApi", - "section": "def-common.SharedUxPlatformService", - "text": "SharedUxPlatformService" - } - ], - "path": "packages/kbn-shared-ux-services/src/context.tsx", - "deprecated": false, - "children": [], - "returnComment": [], - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/shared-ux-services", - "id": "def-common.useSharedUxServices", - "type": "Function", - "tags": [], - "label": "useSharedUxServices", - "description": [ - "\nReact hook for accessing pre-wired `SharedUxServices`." - ], - "signature": [ - "() => ", - { - "pluginId": "@kbn/shared-ux-services", - "scope": "common", - "docId": "kibKbnSharedUxServicesPluginApi", - "section": "def-common.SharedUxServices", - "text": "SharedUxServices" - } - ], - "path": "packages/kbn-shared-ux-services/src/context.tsx", - "deprecated": false, - "children": [], - "returnComment": [], - "initialIsOpen": false - } - ], - "interfaces": [ - { - "parentPluginId": "@kbn/shared-ux-services", - "id": "def-common.MockServicesFactoryParams", - "type": "Interface", - "tags": [], - "label": "MockServicesFactoryParams", - "description": [], - "path": "packages/kbn-shared-ux-services/src/services/mock/index.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/shared-ux-services", - "id": "def-common.MockServicesFactoryParams.config", - "type": "Object", - "tags": [], - "label": "config", - "description": [], - "signature": [ - "MockDataServiceFactoryConfig" - ], - "path": "packages/kbn-shared-ux-services/src/services/mock/index.ts", - "deprecated": false - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/shared-ux-services", - "id": "def-common.SharedUxApplicationService", - "type": "Interface", - "tags": [], - "label": "SharedUxApplicationService", - "description": [], - "path": "packages/kbn-shared-ux-services/src/services/application.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/shared-ux-services", - "id": "def-common.SharedUxApplicationService.navigateToUrl", - "type": "Function", - "tags": [], - "label": "navigateToUrl", - "description": [], - "signature": [ - "(url: string) => void | Promise" - ], - "path": "packages/kbn-shared-ux-services/src/services/application.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/shared-ux-services", - "id": "def-common.SharedUxApplicationService.navigateToUrl.$1", - "type": "string", - "tags": [], - "label": "url", - "description": [], - "signature": [ - "string" - ], - "path": "packages/kbn-shared-ux-services/src/services/application.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [] - }, - { - "parentPluginId": "@kbn/shared-ux-services", - "id": "def-common.SharedUxApplicationService.currentAppId$", - "type": "Object", - "tags": [], - "label": "currentAppId$", - "description": [], - "signature": [ - "Observable", - "" - ], - "path": "packages/kbn-shared-ux-services/src/services/application.ts", - "deprecated": false - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/shared-ux-services", - "id": "def-common.SharedUxDataService", - "type": "Interface", - "tags": [], - "label": "SharedUxDataService", - "description": [ - "\nA service providing data information. Typically used for handling of empty state.." - ], - "path": "packages/kbn-shared-ux-services/src/services/data.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/shared-ux-services", - "id": "def-common.SharedUxDataService.hasESData", - "type": "Function", - "tags": [], - "label": "hasESData", - "description": [ - "True if the cluster contains data, false otherwise." - ], - "signature": [ - "() => Promise" - ], - "path": "packages/kbn-shared-ux-services/src/services/data.ts", - "deprecated": false, - "children": [], - "returnComment": [] - }, - { - "parentPluginId": "@kbn/shared-ux-services", - "id": "def-common.SharedUxDataService.hasUserDataView", - "type": "Function", - "tags": [], - "label": "hasUserDataView", - "description": [ - "True if Kibana instance contains user-created data view, false otherwise." - ], - "signature": [ - "() => Promise" - ], - "path": "packages/kbn-shared-ux-services/src/services/data.ts", - "deprecated": false, - "children": [], - "returnComment": [] - }, - { - "parentPluginId": "@kbn/shared-ux-services", - "id": "def-common.SharedUxDataService.hasDataView", - "type": "Function", - "tags": [], - "label": "hasDataView", - "description": [ - "True if Kibana instance contains any data view, including system-created ones." - ], - "signature": [ - "() => Promise" - ], - "path": "packages/kbn-shared-ux-services/src/services/data.ts", - "deprecated": false, - "children": [], - "returnComment": [] - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/shared-ux-services", - "id": "def-common.SharedUxDocLinksService", - "type": "Interface", - "tags": [], - "label": "SharedUxDocLinksService", - "description": [ - "\nA service providing links to documentation about various features in Kibana." - ], - "path": "packages/kbn-shared-ux-services/src/services/doc_links.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/shared-ux-services", - "id": "def-common.SharedUxDocLinksService.dataViewsDocLink", - "type": "string", - "tags": [], - "label": "dataViewsDocLink", - "description": [ - "A link to information about Data Views in Kibana" - ], - "path": "packages/kbn-shared-ux-services/src/services/doc_links.ts", - "deprecated": false - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/shared-ux-services", - "id": "def-common.SharedUxEditorsService", - "type": "Interface", - "tags": [], - "label": "SharedUxEditorsService", - "description": [ - "\nA service providing methods to invoke and interact with various editors provided\nin Kibana." - ], - "path": "packages/kbn-shared-ux-services/src/services/editors.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/shared-ux-services", - "id": "def-common.SharedUxEditorsService.openDataViewEditor", - "type": "Function", - "tags": [], - "label": "openDataViewEditor", - "description": [ - "A method to open the Data View Editor flow." - ], - "signature": [ - "(options: DataViewEditorOptions) => () => void" - ], - "path": "packages/kbn-shared-ux-services/src/services/editors.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/shared-ux-services", - "id": "def-common.SharedUxEditorsService.openDataViewEditor.$1", - "type": "Object", - "tags": [], - "label": "options", - "description": [], - "signature": [ - "DataViewEditorOptions" - ], - "path": "packages/kbn-shared-ux-services/src/services/editors.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [] - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/shared-ux-services", - "id": "def-common.SharedUxHttpService", - "type": "Interface", - "tags": [], - "label": "SharedUxHttpService", - "description": [], - "path": "packages/kbn-shared-ux-services/src/services/http.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/shared-ux-services", - "id": "def-common.SharedUxHttpService.addBasePath", - "type": "Function", - "tags": [], - "label": "addBasePath", - "description": [], - "signature": [ - "(url: string) => string" - ], - "path": "packages/kbn-shared-ux-services/src/services/http.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/shared-ux-services", - "id": "def-common.SharedUxHttpService.addBasePath.$1", - "type": "string", - "tags": [], - "label": "url", - "description": [], - "signature": [ - "string" - ], - "path": "packages/kbn-shared-ux-services/src/services/http.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [] - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/shared-ux-services", - "id": "def-common.SharedUxPlatformService", - "type": "Interface", - "tags": [], - "label": "SharedUxPlatformService", - "description": [ - "\nA service providing methods to interact with the platform in which this code is\nrunning, (almost always Kibana).\n\nRather than provide the entire `CoreStart` contract to components, we provide simplified\nabstractions around a use case specific to Shared UX. This way, we know exactly how the\n`CoreStart` and other plugins are used. This makes mocking and refactoring easier when\n upstream dependencies change." - ], - "path": "packages/kbn-shared-ux-services/src/services/platform.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/shared-ux-services", - "id": "def-common.SharedUxPlatformService.setIsFullscreen", - "type": "Function", - "tags": [], - "label": "setIsFullscreen", - "description": [ - "\nSets the fullscreen state of the chrome." - ], - "signature": [ - "(isFullscreen: boolean) => void" - ], - "path": "packages/kbn-shared-ux-services/src/services/platform.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/shared-ux-services", - "id": "def-common.SharedUxPlatformService.setIsFullscreen.$1", - "type": "boolean", - "tags": [], - "label": "isFullscreen", - "description": [ - "True if the chrome should be fullscreen, false otherwise." - ], - "signature": [ - "boolean" - ], - "path": "packages/kbn-shared-ux-services/src/services/platform.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [] - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/shared-ux-services", - "id": "def-common.SharedUxServices", - "type": "Interface", - "tags": [], - "label": "SharedUxServices", - "description": [ - "\nA collection of services utilized by SharedUX. This serves as a thin\nabstraction layer between services provided by Kibana and other plugins\nwhile allowing this plugin to be developed independently of those contracts.\n\nIt also allows us to \"swap out\" differenct implementations of these services\nfor different environments, (e.g. Jest, Storybook, etc.)" - ], - "path": "packages/kbn-shared-ux-services/src/types.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/shared-ux-services", - "id": "def-common.SharedUxServices.application", - "type": "Object", - "tags": [], - "label": "application", - "description": [], - "signature": [ - { - "pluginId": "@kbn/shared-ux-services", - "scope": "common", - "docId": "kibKbnSharedUxServicesPluginApi", - "section": "def-common.SharedUxApplicationService", - "text": "SharedUxApplicationService" - } - ], - "path": "packages/kbn-shared-ux-services/src/types.ts", - "deprecated": false - }, - { - "parentPluginId": "@kbn/shared-ux-services", - "id": "def-common.SharedUxServices.docLinks", - "type": "Object", - "tags": [], - "label": "docLinks", - "description": [], - "signature": [ - { - "pluginId": "@kbn/shared-ux-services", - "scope": "common", - "docId": "kibKbnSharedUxServicesPluginApi", - "section": "def-common.SharedUxDocLinksService", - "text": "SharedUxDocLinksService" - } - ], - "path": "packages/kbn-shared-ux-services/src/types.ts", - "deprecated": false - }, - { - "parentPluginId": "@kbn/shared-ux-services", - "id": "def-common.SharedUxServices.editors", - "type": "Object", - "tags": [], - "label": "editors", - "description": [], - "signature": [ - { - "pluginId": "@kbn/shared-ux-services", - "scope": "common", - "docId": "kibKbnSharedUxServicesPluginApi", - "section": "def-common.SharedUxEditorsService", - "text": "SharedUxEditorsService" - } - ], - "path": "packages/kbn-shared-ux-services/src/types.ts", - "deprecated": false - }, - { - "parentPluginId": "@kbn/shared-ux-services", - "id": "def-common.SharedUxServices.http", - "type": "Object", - "tags": [], - "label": "http", - "description": [], - "signature": [ - { - "pluginId": "@kbn/shared-ux-services", - "scope": "common", - "docId": "kibKbnSharedUxServicesPluginApi", - "section": "def-common.SharedUxHttpService", - "text": "SharedUxHttpService" - } - ], - "path": "packages/kbn-shared-ux-services/src/types.ts", - "deprecated": false - }, - { - "parentPluginId": "@kbn/shared-ux-services", - "id": "def-common.SharedUxServices.permissions", - "type": "Object", - "tags": [], - "label": "permissions", - "description": [], - "signature": [ - { - "pluginId": "@kbn/shared-ux-services", - "scope": "common", - "docId": "kibKbnSharedUxServicesPluginApi", - "section": "def-common.SharedUxUserPermissionsService", - "text": "SharedUxUserPermissionsService" - } - ], - "path": "packages/kbn-shared-ux-services/src/types.ts", - "deprecated": false - }, - { - "parentPluginId": "@kbn/shared-ux-services", - "id": "def-common.SharedUxServices.platform", - "type": "Object", - "tags": [], - "label": "platform", - "description": [], - "signature": [ - { - "pluginId": "@kbn/shared-ux-services", - "scope": "common", - "docId": "kibKbnSharedUxServicesPluginApi", - "section": "def-common.SharedUxPlatformService", - "text": "SharedUxPlatformService" - } - ], - "path": "packages/kbn-shared-ux-services/src/types.ts", - "deprecated": false - }, - { - "parentPluginId": "@kbn/shared-ux-services", - "id": "def-common.SharedUxServices.data", - "type": "Object", - "tags": [], - "label": "data", - "description": [], - "signature": [ - { - "pluginId": "@kbn/shared-ux-services", - "scope": "common", - "docId": "kibKbnSharedUxServicesPluginApi", - "section": "def-common.SharedUxDataService", - "text": "SharedUxDataService" - } - ], - "path": "packages/kbn-shared-ux-services/src/types.ts", - "deprecated": false - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/shared-ux-services", - "id": "def-common.SharedUxUserPermissionsService", - "type": "Interface", - "tags": [], - "label": "SharedUxUserPermissionsService", - "description": [ - "\nA service providing permissions information, typically for the current user." - ], - "path": "packages/kbn-shared-ux-services/src/services/permissions.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/shared-ux-services", - "id": "def-common.SharedUxUserPermissionsService.canCreateNewDataView", - "type": "boolean", - "tags": [], - "label": "canCreateNewDataView", - "description": [ - "True if the user has permission to create a new Data View, false otherwise." - ], - "path": "packages/kbn-shared-ux-services/src/services/permissions.ts", - "deprecated": false - }, - { - "parentPluginId": "@kbn/shared-ux-services", - "id": "def-common.SharedUxUserPermissionsService.canAccessFleet", - "type": "boolean", - "tags": [], - "label": "canAccessFleet", - "description": [], - "path": "packages/kbn-shared-ux-services/src/services/permissions.ts", - "deprecated": false - } - ], - "initialIsOpen": false - } - ], - "enums": [], - "misc": [ - { - "parentPluginId": "@kbn/shared-ux-services", - "id": "def-common.ServiceFactory", - "type": "Type", - "tags": [], - "label": "ServiceFactory", - "description": [ - "\nA factory function for creating one or more services.\n\nThe `S` generic determines the shape of the API being produced.\nThe `Parameters` generic determines what parameters are expected to\ncreate the service." - ], - "signature": [ - "(params: Parameters) => S" - ], - "path": "packages/kbn-shared-ux-services/src/types.ts", - "deprecated": false, - "returnComment": [], - "children": [ - { - "parentPluginId": "@kbn/shared-ux-services", - "id": "def-common.ServiceFactory.$1", - "type": "Uncategorized", - "tags": [], - "label": "params", - "description": [], - "signature": [ - "Parameters" - ], - "path": "packages/kbn-shared-ux-services/src/types.ts", - "deprecated": false - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/shared-ux-services", - "id": "def-common.SharedUxServicesContext", - "type": "Type", - "tags": [], - "label": "SharedUxServicesContext", - "description": [ - "\nA type representing a component that provides the `SharedUxServices` through a\nReact Context." - ], - "signature": [ - "React.FunctionComponent<{}>" - ], - "path": "packages/kbn-shared-ux-services/src/types.ts", - "deprecated": false, - "returnComment": [], - "children": [ - { - "parentPluginId": "@kbn/shared-ux-services", - "id": "def-common.SharedUxServicesContext.$1", - "type": "CompoundType", - "tags": [], - "label": "props", - "description": [], - "signature": [ - "P & { children?: React.ReactNode; }" - ], - "path": "node_modules/@types/react/index.d.ts", - "deprecated": false - }, - { - "parentPluginId": "@kbn/shared-ux-services", - "id": "def-common.SharedUxServicesContext.$2", - "type": "Any", - "tags": [], - "label": "context", - "description": [], - "signature": [ - "any" - ], - "path": "node_modules/@types/react/index.d.ts", - "deprecated": false - } - ], - "initialIsOpen": false - } - ], - "objects": [ - { - "parentPluginId": "@kbn/shared-ux-services", - "id": "def-common.mockServiceFactories", - "type": "Object", - "tags": [], - "label": "mockServiceFactories", - "description": [ - "\nA collection of mock Service Factories." - ], - "path": "packages/kbn-shared-ux-services/src/services/mock/index.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/shared-ux-services", - "id": "def-common.mockServiceFactories.applicationServiceFactory", - "type": "Function", - "tags": [], - "label": "applicationServiceFactory", - "description": [], - "signature": [ - "(params: void) => ", - { - "pluginId": "@kbn/shared-ux-services", - "scope": "common", - "docId": "kibKbnSharedUxServicesPluginApi", - "section": "def-common.SharedUxApplicationService", - "text": "SharedUxApplicationService" - } - ], - "path": "packages/kbn-shared-ux-services/src/services/mock/index.ts", - "deprecated": false, - "returnComment": [], - "children": [ - { - "parentPluginId": "@kbn/shared-ux-services", - "id": "def-common.mockServiceFactories.applicationServiceFactory.$1", - "type": "Uncategorized", - "tags": [], - "label": "params", - "description": [], - "signature": [ - "Parameters" - ], - "path": "packages/kbn-shared-ux-services/src/types.ts", - "deprecated": false - } - ] - }, - { - "parentPluginId": "@kbn/shared-ux-services", - "id": "def-common.mockServiceFactories.docLinksServiceFactory", - "type": "Function", - "tags": [], - "label": "docLinksServiceFactory", - "description": [], - "signature": [ - "(params: void) => ", - { - "pluginId": "@kbn/shared-ux-services", - "scope": "common", - "docId": "kibKbnSharedUxServicesPluginApi", - "section": "def-common.SharedUxDocLinksService", - "text": "SharedUxDocLinksService" - } - ], - "path": "packages/kbn-shared-ux-services/src/services/mock/index.ts", - "deprecated": false, - "returnComment": [], - "children": [ - { - "parentPluginId": "@kbn/shared-ux-services", - "id": "def-common.mockServiceFactories.docLinksServiceFactory.$1", - "type": "Uncategorized", - "tags": [], - "label": "params", - "description": [], - "signature": [ - "Parameters" - ], - "path": "packages/kbn-shared-ux-services/src/types.ts", - "deprecated": false - } - ] - }, - { - "parentPluginId": "@kbn/shared-ux-services", - "id": "def-common.mockServiceFactories.editorsServiceFactory", - "type": "Function", - "tags": [], - "label": "editorsServiceFactory", - "description": [], - "signature": [ - "(params: void) => ", - { - "pluginId": "@kbn/shared-ux-services", - "scope": "common", - "docId": "kibKbnSharedUxServicesPluginApi", - "section": "def-common.SharedUxEditorsService", - "text": "SharedUxEditorsService" - } - ], - "path": "packages/kbn-shared-ux-services/src/services/mock/index.ts", - "deprecated": false, - "returnComment": [], - "children": [ - { - "parentPluginId": "@kbn/shared-ux-services", - "id": "def-common.mockServiceFactories.editorsServiceFactory.$1", - "type": "Uncategorized", - "tags": [], - "label": "params", - "description": [], - "signature": [ - "Parameters" - ], - "path": "packages/kbn-shared-ux-services/src/types.ts", - "deprecated": false - } - ] - }, - { - "parentPluginId": "@kbn/shared-ux-services", - "id": "def-common.mockServiceFactories.httpServiceFactory", - "type": "Function", - "tags": [], - "label": "httpServiceFactory", - "description": [], - "signature": [ - "(params: void) => ", - { - "pluginId": "@kbn/shared-ux-services", - "scope": "common", - "docId": "kibKbnSharedUxServicesPluginApi", - "section": "def-common.SharedUxHttpService", - "text": "SharedUxHttpService" - } - ], - "path": "packages/kbn-shared-ux-services/src/services/mock/index.ts", - "deprecated": false, - "returnComment": [], - "children": [ - { - "parentPluginId": "@kbn/shared-ux-services", - "id": "def-common.mockServiceFactories.httpServiceFactory.$1", - "type": "Uncategorized", - "tags": [], - "label": "params", - "description": [], - "signature": [ - "Parameters" - ], - "path": "packages/kbn-shared-ux-services/src/types.ts", - "deprecated": false - } - ] - }, - { - "parentPluginId": "@kbn/shared-ux-services", - "id": "def-common.mockServiceFactories.platformServiceFactory", - "type": "Function", - "tags": [], - "label": "platformServiceFactory", - "description": [], - "signature": [ - "(params: void) => ", - { - "pluginId": "@kbn/shared-ux-services", - "scope": "common", - "docId": "kibKbnSharedUxServicesPluginApi", - "section": "def-common.SharedUxPlatformService", - "text": "SharedUxPlatformService" - } - ], - "path": "packages/kbn-shared-ux-services/src/services/mock/index.ts", - "deprecated": false, - "returnComment": [], - "children": [ - { - "parentPluginId": "@kbn/shared-ux-services", - "id": "def-common.mockServiceFactories.platformServiceFactory.$1", - "type": "Uncategorized", - "tags": [], - "label": "params", - "description": [], - "signature": [ - "Parameters" - ], - "path": "packages/kbn-shared-ux-services/src/types.ts", - "deprecated": false - } - ] - }, - { - "parentPluginId": "@kbn/shared-ux-services", - "id": "def-common.mockServiceFactories.userPermissionsServiceFactory", - "type": "Function", - "tags": [], - "label": "userPermissionsServiceFactory", - "description": [], - "signature": [ - "(params: void) => ", - { - "pluginId": "@kbn/shared-ux-services", - "scope": "common", - "docId": "kibKbnSharedUxServicesPluginApi", - "section": "def-common.SharedUxUserPermissionsService", - "text": "SharedUxUserPermissionsService" - } - ], - "path": "packages/kbn-shared-ux-services/src/services/mock/index.ts", - "deprecated": false, - "returnComment": [], - "children": [ - { - "parentPluginId": "@kbn/shared-ux-services", - "id": "def-common.mockServiceFactories.userPermissionsServiceFactory.$1", - "type": "Uncategorized", - "tags": [], - "label": "params", - "description": [], - "signature": [ - "Parameters" - ], - "path": "packages/kbn-shared-ux-services/src/types.ts", - "deprecated": false - } - ] - }, - { - "parentPluginId": "@kbn/shared-ux-services", - "id": "def-common.mockServiceFactories.dataServiceFactory", - "type": "Function", - "tags": [], - "label": "dataServiceFactory", - "description": [], - "signature": [ - "(config?: ", - "MockDataServiceFactoryConfig", - " | undefined) => ", - { - "pluginId": "@kbn/shared-ux-services", - "scope": "common", - "docId": "kibKbnSharedUxServicesPluginApi", - "section": "def-common.SharedUxDataService", - "text": "SharedUxDataService" - } - ], - "path": "packages/kbn-shared-ux-services/src/services/mock/index.ts", - "deprecated": false, - "returnComment": [], - "children": [ - { - "parentPluginId": "@kbn/shared-ux-services", - "id": "def-common.mockServiceFactories.dataServiceFactory.$1", - "type": "Object", - "tags": [], - "label": "config", - "description": [], - "signature": [ - "MockDataServiceFactoryConfig", - " | undefined" - ], - "path": "packages/kbn-shared-ux-services/src/services/mock/data.mock.ts", - "deprecated": false - } - ] - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/shared-ux-services", - "id": "def-common.stubServiceFactories", - "type": "Object", - "tags": [], - "label": "stubServiceFactories", - "description": [ - "\nA collection of stubbed service factories." - ], - "path": "packages/kbn-shared-ux-services/src/services/stub/index.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/shared-ux-services", - "id": "def-common.stubServiceFactories.applicationServiceFactory", - "type": "Function", - "tags": [], - "label": "applicationServiceFactory", - "description": [], - "signature": [ - "(params: void) => ", - { - "pluginId": "@kbn/shared-ux-services", - "scope": "common", - "docId": "kibKbnSharedUxServicesPluginApi", - "section": "def-common.SharedUxApplicationService", - "text": "SharedUxApplicationService" - } - ], - "path": "packages/kbn-shared-ux-services/src/services/stub/index.ts", - "deprecated": false, - "returnComment": [], - "children": [ - { - "parentPluginId": "@kbn/shared-ux-services", - "id": "def-common.stubServiceFactories.applicationServiceFactory.$1", - "type": "Uncategorized", - "tags": [], - "label": "params", - "description": [], - "signature": [ - "Parameters" - ], - "path": "packages/kbn-shared-ux-services/src/types.ts", - "deprecated": false - } - ] - }, - { - "parentPluginId": "@kbn/shared-ux-services", - "id": "def-common.stubServiceFactories.docLinksServiceFactory", - "type": "Function", - "tags": [], - "label": "docLinksServiceFactory", - "description": [], - "signature": [ - "(params: void) => ", - { - "pluginId": "@kbn/shared-ux-services", - "scope": "common", - "docId": "kibKbnSharedUxServicesPluginApi", - "section": "def-common.SharedUxDocLinksService", - "text": "SharedUxDocLinksService" - } - ], - "path": "packages/kbn-shared-ux-services/src/services/stub/index.ts", - "deprecated": false, - "returnComment": [], - "children": [ - { - "parentPluginId": "@kbn/shared-ux-services", - "id": "def-common.stubServiceFactories.docLinksServiceFactory.$1", - "type": "Uncategorized", - "tags": [], - "label": "params", - "description": [], - "signature": [ - "Parameters" - ], - "path": "packages/kbn-shared-ux-services/src/types.ts", - "deprecated": false - } - ] - }, - { - "parentPluginId": "@kbn/shared-ux-services", - "id": "def-common.stubServiceFactories.editorsServiceFactory", - "type": "Function", - "tags": [], - "label": "editorsServiceFactory", - "description": [], - "signature": [ - "(params: void) => ", - { - "pluginId": "@kbn/shared-ux-services", - "scope": "common", - "docId": "kibKbnSharedUxServicesPluginApi", - "section": "def-common.SharedUxEditorsService", - "text": "SharedUxEditorsService" - } - ], - "path": "packages/kbn-shared-ux-services/src/services/stub/index.ts", - "deprecated": false, - "returnComment": [], - "children": [ - { - "parentPluginId": "@kbn/shared-ux-services", - "id": "def-common.stubServiceFactories.editorsServiceFactory.$1", - "type": "Uncategorized", - "tags": [], - "label": "params", - "description": [], - "signature": [ - "Parameters" - ], - "path": "packages/kbn-shared-ux-services/src/types.ts", - "deprecated": false - } - ] - }, - { - "parentPluginId": "@kbn/shared-ux-services", - "id": "def-common.stubServiceFactories.httpServiceFactory", - "type": "Function", - "tags": [], - "label": "httpServiceFactory", - "description": [], - "signature": [ - "(params: void) => ", - { - "pluginId": "@kbn/shared-ux-services", - "scope": "common", - "docId": "kibKbnSharedUxServicesPluginApi", - "section": "def-common.SharedUxHttpService", - "text": "SharedUxHttpService" - } - ], - "path": "packages/kbn-shared-ux-services/src/services/stub/index.ts", - "deprecated": false, - "returnComment": [], - "children": [ - { - "parentPluginId": "@kbn/shared-ux-services", - "id": "def-common.stubServiceFactories.httpServiceFactory.$1", - "type": "Uncategorized", - "tags": [], - "label": "params", - "description": [], - "signature": [ - "Parameters" - ], - "path": "packages/kbn-shared-ux-services/src/types.ts", - "deprecated": false - } - ] - }, - { - "parentPluginId": "@kbn/shared-ux-services", - "id": "def-common.stubServiceFactories.platformServiceFactory", - "type": "Function", - "tags": [], - "label": "platformServiceFactory", - "description": [], - "signature": [ - "(params: void) => ", - { - "pluginId": "@kbn/shared-ux-services", - "scope": "common", - "docId": "kibKbnSharedUxServicesPluginApi", - "section": "def-common.SharedUxPlatformService", - "text": "SharedUxPlatformService" - } - ], - "path": "packages/kbn-shared-ux-services/src/services/stub/index.ts", - "deprecated": false, - "returnComment": [], - "children": [ - { - "parentPluginId": "@kbn/shared-ux-services", - "id": "def-common.stubServiceFactories.platformServiceFactory.$1", - "type": "Uncategorized", - "tags": [], - "label": "params", - "description": [], - "signature": [ - "Parameters" - ], - "path": "packages/kbn-shared-ux-services/src/types.ts", - "deprecated": false - } - ] - }, - { - "parentPluginId": "@kbn/shared-ux-services", - "id": "def-common.stubServiceFactories.userPermissionsServiceFactory", - "type": "Function", - "tags": [], - "label": "userPermissionsServiceFactory", - "description": [], - "signature": [ - "(params: void) => ", - { - "pluginId": "@kbn/shared-ux-services", - "scope": "common", - "docId": "kibKbnSharedUxServicesPluginApi", - "section": "def-common.SharedUxUserPermissionsService", - "text": "SharedUxUserPermissionsService" - } - ], - "path": "packages/kbn-shared-ux-services/src/services/stub/index.ts", - "deprecated": false, - "returnComment": [], - "children": [ - { - "parentPluginId": "@kbn/shared-ux-services", - "id": "def-common.stubServiceFactories.userPermissionsServiceFactory.$1", - "type": "Uncategorized", - "tags": [], - "label": "params", - "description": [], - "signature": [ - "Parameters" - ], - "path": "packages/kbn-shared-ux-services/src/types.ts", - "deprecated": false - } - ] - }, - { - "parentPluginId": "@kbn/shared-ux-services", - "id": "def-common.stubServiceFactories.dataServiceFactory", - "type": "Function", - "tags": [], - "label": "dataServiceFactory", - "description": [], - "signature": [ - "(params: void) => ", - { - "pluginId": "@kbn/shared-ux-services", - "scope": "common", - "docId": "kibKbnSharedUxServicesPluginApi", - "section": "def-common.SharedUxDataService", - "text": "SharedUxDataService" - } - ], - "path": "packages/kbn-shared-ux-services/src/services/stub/index.ts", - "deprecated": false, - "returnComment": [], - "children": [ - { - "parentPluginId": "@kbn/shared-ux-services", - "id": "def-common.stubServiceFactories.dataServiceFactory.$1", - "type": "Uncategorized", - "tags": [], - "label": "params", - "description": [], - "signature": [ - "Parameters" - ], - "path": "packages/kbn-shared-ux-services/src/types.ts", - "deprecated": false - } - ] - } - ], - "initialIsOpen": false - } - ] - } -} \ No newline at end of file diff --git a/api_docs/kbn_shared_ux_services.mdx b/api_docs/kbn_shared_ux_services.mdx deleted file mode 100644 index c17c02294c8e5a..00000000000000 --- a/api_docs/kbn_shared_ux_services.mdx +++ /dev/null @@ -1,39 +0,0 @@ ---- -#### -#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system. -#### Reach out in #docs-engineering for more info. -#### -id: kibKbnSharedUxServicesPluginApi -slug: /kibana-dev-docs/api/kbn-shared-ux-services -title: "@kbn/shared-ux-services" -image: https://source.unsplash.com/400x175/?github -description: API docs for the @kbn/shared-ux-services plugin -date: 2022-08-17 -tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-services'] ---- -import kbnSharedUxServicesObj from './kbn_shared_ux_services.devdocs.json'; - - - -Contact [Owner missing] for questions regarding this plugin. - -**Code health stats** - -| Public API count | Any count | Items lacking comments | Missing exports | -|-------------------|-----------|------------------------|-----------------| -| 80 | 0 | 51 | 1 | - -## Common - -### Objects - - -### Functions - - -### Interfaces - - -### Consts, variables and types - - diff --git a/api_docs/kbn_shared_ux_storybook.devdocs.json b/api_docs/kbn_shared_ux_storybook.devdocs.json deleted file mode 100644 index 82e09aac247b96..00000000000000 --- a/api_docs/kbn_shared_ux_storybook.devdocs.json +++ /dev/null @@ -1,324 +0,0 @@ -{ - "id": "@kbn/shared-ux-storybook", - "client": { - "classes": [], - "functions": [], - "interfaces": [], - "enums": [], - "misc": [], - "objects": [] - }, - "server": { - "classes": [], - "functions": [], - "interfaces": [], - "enums": [], - "misc": [], - "objects": [] - }, - "common": { - "classes": [], - "functions": [ - { - "parentPluginId": "@kbn/shared-ux-storybook", - "id": "def-common.applicationServiceFactory", - "type": "Function", - "tags": [], - "label": "applicationServiceFactory", - "description": [ - "\nA factory function for creating for creating a storybook implementation of `SharedUXApplicationService`." - ], - "signature": [ - "() => { navigateToUrl: (url: string) => Promise; currentAppId$: ", - "BehaviorSubject", - "; }" - ], - "path": "packages/kbn-shared-ux-storybook/src/services/application.ts", - "deprecated": false, - "children": [], - "returnComment": [], - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/shared-ux-storybook", - "id": "def-common.dataServiceFactory", - "type": "Function", - "tags": [], - "label": "dataServiceFactory", - "description": [ - "\nA factory function for creating a Storybook implementation of `SharedUxDataService`." - ], - "signature": [ - "(params: ", - { - "pluginId": "@kbn/shared-ux-storybook", - "scope": "common", - "docId": "kibKbnSharedUxStorybookPluginApi", - "section": "def-common.DataServiceFactoryConfig", - "text": "DataServiceFactoryConfig" - }, - ") => { hasESData: () => Promise; hasDataView: () => Promise; hasUserDataView: () => Promise; }" - ], - "path": "packages/kbn-shared-ux-storybook/src/services/data.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/shared-ux-storybook", - "id": "def-common.dataServiceFactory.$1", - "type": "Object", - "tags": [], - "label": "params", - "description": [], - "signature": [ - { - "pluginId": "@kbn/shared-ux-storybook", - "scope": "common", - "docId": "kibKbnSharedUxStorybookPluginApi", - "section": "def-common.DataServiceFactoryConfig", - "text": "DataServiceFactoryConfig" - } - ], - "path": "packages/kbn-shared-ux-storybook/src/services/data.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [], - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/shared-ux-storybook", - "id": "def-common.docLinksServiceFactory", - "type": "Function", - "tags": [], - "label": "docLinksServiceFactory", - "description": [ - "\nA factory function for creating a Storybook implementation of `SharedUxDocLinksService`." - ], - "signature": [ - "() => { dataViewsDocLink: string; kibanaGuideDocLink: string; }" - ], - "path": "packages/kbn-shared-ux-storybook/src/services/doc_links.ts", - "deprecated": false, - "children": [], - "returnComment": [], - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/shared-ux-storybook", - "id": "def-common.editorsServiceFactory", - "type": "Function", - "tags": [], - "label": "editorsServiceFactory", - "description": [ - "\nA factory function for creating a Storybook implementation of `SharedUxEditorsService`." - ], - "signature": [ - "() => { openDataViewEditor: (options: ", - "DataViewEditorOptions", - ") => () => void; }" - ], - "path": "packages/kbn-shared-ux-storybook/src/services/editors.ts", - "deprecated": false, - "children": [], - "returnComment": [], - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/shared-ux-storybook", - "id": "def-common.httpServiceFactory", - "type": "Function", - "tags": [], - "label": "httpServiceFactory", - "description": [ - "\nA factory function for creating a Storybook-based implementation of `SharedUXHttpService`." - ], - "signature": [ - "() => { addBasePath: (url: string) => string; }" - ], - "path": "packages/kbn-shared-ux-storybook/src/services/http.ts", - "deprecated": false, - "children": [], - "returnComment": [], - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/shared-ux-storybook", - "id": "def-common.platformServiceFactory", - "type": "Function", - "tags": [], - "label": "platformServiceFactory", - "description": [ - "\nA factory function for creating a Storybook implementation of `SharedUxPlatformService`." - ], - "signature": [ - "() => { setIsFullscreen: ", - "HandlerFunction", - "; }" - ], - "path": "packages/kbn-shared-ux-storybook/src/services/platform.ts", - "deprecated": false, - "children": [], - "returnComment": [], - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/shared-ux-storybook", - "id": "def-common.servicesDecorator", - "type": "Function", - "tags": [], - "label": "servicesDecorator", - "description": [ - "\nA Storybook decorator that provides the Shared UX `ServicesProvider` with Storybook-specific\nimplementations to stories." - ], - "signature": [ - "(storyFn: ", - "PartialStoryFn", - ", ", - "Args", - ">) => JSX.Element" - ], - "path": "packages/kbn-shared-ux-storybook/src/decorators.tsx", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/shared-ux-storybook", - "id": "def-common.servicesDecorator.$1", - "type": "Function", - "tags": [], - "label": "storyFn", - "description": [], - "signature": [ - "PartialStoryFn", - ", ", - "Args", - ">" - ], - "path": "packages/kbn-shared-ux-storybook/src/decorators.tsx", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [], - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/shared-ux-storybook", - "id": "def-common.servicesFactory", - "type": "Function", - "tags": [], - "label": "servicesFactory", - "description": [ - "\nA factory function for creating a Storybook implementation of `SharedUxServices`." - ], - "signature": [ - "(params: {}) => { application: ", - "SharedUxApplicationService", - "; docLinks: ", - "SharedUxDocLinksService", - "; editors: ", - "SharedUxEditorsService", - "; http: ", - "SharedUxHttpService", - "; permissions: ", - "SharedUxUserPermissionsService", - "; platform: ", - "SharedUxPlatformService", - "; data: ", - "SharedUxDataService", - "; }" - ], - "path": "packages/kbn-shared-ux-storybook/src/services/index.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/shared-ux-storybook", - "id": "def-common.servicesFactory.$1", - "type": "Object", - "tags": [], - "label": "params", - "description": [], - "signature": [ - "{}" - ], - "path": "packages/kbn-shared-ux-storybook/src/services/index.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [], - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/shared-ux-storybook", - "id": "def-common.userPermissionsServiceFactory", - "type": "Function", - "tags": [], - "label": "userPermissionsServiceFactory", - "description": [ - "\nA factory function for creating a Storybook implementation of `SharedUxUserPermissionsService`." - ], - "signature": [ - "() => { canCreateNewDataView: true; canAccessFleet: true; }" - ], - "path": "packages/kbn-shared-ux-storybook/src/services/permissions.ts", - "deprecated": false, - "children": [], - "returnComment": [], - "initialIsOpen": false - } - ], - "interfaces": [ - { - "parentPluginId": "@kbn/shared-ux-storybook", - "id": "def-common.DataServiceFactoryConfig", - "type": "Interface", - "tags": [], - "label": "DataServiceFactoryConfig", - "description": [], - "path": "packages/kbn-shared-ux-storybook/src/services/data.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/shared-ux-storybook", - "id": "def-common.DataServiceFactoryConfig.hasESData", - "type": "boolean", - "tags": [], - "label": "hasESData", - "description": [], - "path": "packages/kbn-shared-ux-storybook/src/services/data.ts", - "deprecated": false - }, - { - "parentPluginId": "@kbn/shared-ux-storybook", - "id": "def-common.DataServiceFactoryConfig.hasDataView", - "type": "boolean", - "tags": [], - "label": "hasDataView", - "description": [], - "path": "packages/kbn-shared-ux-storybook/src/services/data.ts", - "deprecated": false - }, - { - "parentPluginId": "@kbn/shared-ux-storybook", - "id": "def-common.DataServiceFactoryConfig.hasUserDataView", - "type": "boolean", - "tags": [], - "label": "hasUserDataView", - "description": [], - "path": "packages/kbn-shared-ux-storybook/src/services/data.ts", - "deprecated": false - } - ], - "initialIsOpen": false - } - ], - "enums": [], - "misc": [], - "objects": [] - } -} \ No newline at end of file diff --git a/api_docs/kbn_shared_ux_storybook_mock.devdocs.json b/api_docs/kbn_shared_ux_storybook_mock.devdocs.json index 63551c7aca499c..2db55d58a00a69 100644 --- a/api_docs/kbn_shared_ux_storybook_mock.devdocs.json +++ b/api_docs/kbn_shared_ux_storybook_mock.devdocs.json @@ -9,10 +9,18 @@ "objects": [] }, "server": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "common": { "classes": [ { "parentPluginId": "@kbn/shared-ux-storybook-mock", - "id": "def-server.AbstractStorybookMock", + "id": "def-common.AbstractStorybookMock", "type": "Class", "tags": [], "label": "AbstractStorybookMock", @@ -22,9 +30,9 @@ "signature": [ { "pluginId": "@kbn/shared-ux-storybook-mock", - "scope": "server", + "scope": "common", "docId": "kibKbnSharedUxStorybookMockPluginApi", - "section": "def-server.AbstractStorybookMock", + "section": "def-common.AbstractStorybookMock", "text": "AbstractStorybookMock" }, "" @@ -34,7 +42,7 @@ "children": [ { "parentPluginId": "@kbn/shared-ux-storybook-mock", - "id": "def-server.AbstractStorybookMock.propArguments", + "id": "def-common.AbstractStorybookMock.propArguments", "type": "Object", "tags": [], "label": "propArguments", @@ -51,7 +59,7 @@ }, { "parentPluginId": "@kbn/shared-ux-storybook-mock", - "id": "def-server.AbstractStorybookMock.serviceArguments", + "id": "def-common.AbstractStorybookMock.serviceArguments", "type": "Object", "tags": [], "label": "serviceArguments", @@ -68,7 +76,7 @@ }, { "parentPluginId": "@kbn/shared-ux-storybook-mock", - "id": "def-server.AbstractStorybookMock.dependencies", + "id": "def-common.AbstractStorybookMock.dependencies", "type": "Array", "tags": [], "label": "dependencies", @@ -78,9 +86,9 @@ "signature": [ { "pluginId": "@kbn/shared-ux-storybook-mock", - "scope": "server", + "scope": "common", "docId": "kibKbnSharedUxStorybookMockPluginApi", - "section": "def-server.AbstractStorybookMock", + "section": "def-common.AbstractStorybookMock", "text": "AbstractStorybookMock" }, "<", @@ -92,7 +100,7 @@ }, { "parentPluginId": "@kbn/shared-ux-storybook-mock", - "id": "def-server.AbstractStorybookMock.getPropArgumentTypes", + "id": "def-common.AbstractStorybookMock.getPropArgumentTypes", "type": "Function", "tags": [], "label": "getPropArgumentTypes", @@ -111,7 +119,7 @@ }, { "parentPluginId": "@kbn/shared-ux-storybook-mock", - "id": "def-server.AbstractStorybookMock.getServiceArgumentTypes", + "id": "def-common.AbstractStorybookMock.getServiceArgumentTypes", "type": "Function", "tags": [], "label": "getServiceArgumentTypes", @@ -134,7 +142,7 @@ }, { "parentPluginId": "@kbn/shared-ux-storybook-mock", - "id": "def-server.AbstractStorybookMock.getArgumentTypes", + "id": "def-common.AbstractStorybookMock.getArgumentTypes", "type": "Function", "tags": [], "label": "getArgumentTypes", @@ -159,7 +167,7 @@ }, { "parentPluginId": "@kbn/shared-ux-storybook-mock", - "id": "def-server.AbstractStorybookMock.getArgumentValue", + "id": "def-common.AbstractStorybookMock.getArgumentValue", "type": "Function", "tags": [], "label": "getArgumentValue", @@ -176,7 +184,7 @@ "children": [ { "parentPluginId": "@kbn/shared-ux-storybook-mock", - "id": "def-server.AbstractStorybookMock.getArgumentValue.$1", + "id": "def-common.AbstractStorybookMock.getArgumentValue.$1", "type": "CompoundType", "tags": [], "label": "arg", @@ -190,7 +198,7 @@ }, { "parentPluginId": "@kbn/shared-ux-storybook-mock", - "id": "def-server.AbstractStorybookMock.getArgumentValue.$2", + "id": "def-common.AbstractStorybookMock.getArgumentValue.$2", "type": "Object", "tags": [], "label": "params", @@ -208,7 +216,7 @@ }, { "parentPluginId": "@kbn/shared-ux-storybook-mock", - "id": "def-server.AbstractStorybookMock.getProps", + "id": "def-common.AbstractStorybookMock.getProps", "type": "Function", "tags": [], "label": "getProps", @@ -225,7 +233,7 @@ "children": [ { "parentPluginId": "@kbn/shared-ux-storybook-mock", - "id": "def-server.AbstractStorybookMock.getProps.$1", + "id": "def-common.AbstractStorybookMock.getProps.$1", "type": "Object", "tags": [], "label": "params", @@ -243,7 +251,7 @@ }, { "parentPluginId": "@kbn/shared-ux-storybook-mock", - "id": "def-server.AbstractStorybookMock.getServices", + "id": "def-common.AbstractStorybookMock.getServices", "type": "Function", "tags": [], "label": "getServices", @@ -260,7 +268,7 @@ "children": [ { "parentPluginId": "@kbn/shared-ux-storybook-mock", - "id": "def-server.AbstractStorybookMock.getServices.$1", + "id": "def-common.AbstractStorybookMock.getServices.$1", "type": "Object", "tags": [], "label": "params", @@ -285,13 +293,5 @@ "enums": [], "misc": [], "objects": [] - }, - "common": { - "classes": [], - "functions": [], - "interfaces": [], - "enums": [], - "misc": [], - "objects": [] } } \ No newline at end of file diff --git a/api_docs/kbn_shared_ux_storybook_mock.mdx b/api_docs/kbn_shared_ux_storybook_mock.mdx index d656d4adac87b1..a1b94c66f0e2ce 100644 --- a/api_docs/kbn_shared_ux_storybook_mock.mdx +++ b/api_docs/kbn_shared_ux_storybook_mock.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-storybook-mock title: "@kbn/shared-ux-storybook-mock" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-storybook-mock plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-storybook-mock'] --- import kbnSharedUxStorybookMockObj from './kbn_shared_ux_storybook_mock.devdocs.json'; @@ -23,8 +23,8 @@ Contact [Owner missing] for questions regarding this plugin. |-------------------|-----------|------------------------|-----------------| | 14 | 0 | 4 | 1 | -## Server +## Common ### Classes - + diff --git a/api_docs/kbn_shared_ux_utility.mdx b/api_docs/kbn_shared_ux_utility.mdx index 73945964108a28..98cf7e49109261 100644 --- a/api_docs/kbn_shared_ux_utility.mdx +++ b/api_docs/kbn_shared_ux_utility.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-utility title: "@kbn/shared-ux-utility" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-utility plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-utility'] --- import kbnSharedUxUtilityObj from './kbn_shared_ux_utility.devdocs.json'; diff --git a/api_docs/kbn_some_dev_log.mdx b/api_docs/kbn_some_dev_log.mdx index b40b1cd4107547..9cb21f776be429 100644 --- a/api_docs/kbn_some_dev_log.mdx +++ b/api_docs/kbn_some_dev_log.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-some-dev-log title: "@kbn/some-dev-log" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/some-dev-log plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/some-dev-log'] --- import kbnSomeDevLogObj from './kbn_some_dev_log.devdocs.json'; diff --git a/api_docs/kbn_sort_package_json.mdx b/api_docs/kbn_sort_package_json.mdx index 166a5bd2a52170..e06b757a8db8cc 100644 --- a/api_docs/kbn_sort_package_json.mdx +++ b/api_docs/kbn_sort_package_json.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-sort-package-json title: "@kbn/sort-package-json" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/sort-package-json plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/sort-package-json'] --- import kbnSortPackageJsonObj from './kbn_sort_package_json.devdocs.json'; diff --git a/api_docs/kbn_std.mdx b/api_docs/kbn_std.mdx index 350c7565a3cf65..e025dc2ee22de4 100644 --- a/api_docs/kbn_std.mdx +++ b/api_docs/kbn_std.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-std title: "@kbn/std" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/std plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/std'] --- import kbnStdObj from './kbn_std.devdocs.json'; diff --git a/api_docs/kbn_stdio_dev_helpers.mdx b/api_docs/kbn_stdio_dev_helpers.mdx index 61d5c3ac88da59..8ff84ef7dc65c6 100644 --- a/api_docs/kbn_stdio_dev_helpers.mdx +++ b/api_docs/kbn_stdio_dev_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-stdio-dev-helpers title: "@kbn/stdio-dev-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/stdio-dev-helpers plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/stdio-dev-helpers'] --- import kbnStdioDevHelpersObj from './kbn_stdio_dev_helpers.devdocs.json'; diff --git a/api_docs/kbn_storybook.mdx b/api_docs/kbn_storybook.mdx index 3a2fba071dc8a1..6b5d7922b3816c 100644 --- a/api_docs/kbn_storybook.mdx +++ b/api_docs/kbn_storybook.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-storybook title: "@kbn/storybook" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/storybook plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/storybook'] --- import kbnStorybookObj from './kbn_storybook.devdocs.json'; diff --git a/api_docs/kbn_telemetry_tools.mdx b/api_docs/kbn_telemetry_tools.mdx index f9ec20a4d2ce6b..4aa7271a305d47 100644 --- a/api_docs/kbn_telemetry_tools.mdx +++ b/api_docs/kbn_telemetry_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-telemetry-tools title: "@kbn/telemetry-tools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/telemetry-tools plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/telemetry-tools'] --- import kbnTelemetryToolsObj from './kbn_telemetry_tools.devdocs.json'; diff --git a/api_docs/kbn_test.mdx b/api_docs/kbn_test.mdx index 1311a8447e8d31..0e8febbc373ff7 100644 --- a/api_docs/kbn_test.mdx +++ b/api_docs/kbn_test.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-test title: "@kbn/test" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/test plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/test'] --- import kbnTestObj from './kbn_test.devdocs.json'; diff --git a/api_docs/kbn_test_jest_helpers.mdx b/api_docs/kbn_test_jest_helpers.mdx index d5cf0e604bd850..da3604b07673a3 100644 --- a/api_docs/kbn_test_jest_helpers.mdx +++ b/api_docs/kbn_test_jest_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-test-jest-helpers title: "@kbn/test-jest-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/test-jest-helpers plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/test-jest-helpers'] --- import kbnTestJestHelpersObj from './kbn_test_jest_helpers.devdocs.json'; diff --git a/api_docs/kbn_tooling_log.mdx b/api_docs/kbn_tooling_log.mdx index 3712685a4b432e..6320439efcfa6e 100644 --- a/api_docs/kbn_tooling_log.mdx +++ b/api_docs/kbn_tooling_log.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-tooling-log title: "@kbn/tooling-log" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/tooling-log plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/tooling-log'] --- import kbnToolingLogObj from './kbn_tooling_log.devdocs.json'; diff --git a/api_docs/kbn_type_summarizer.mdx b/api_docs/kbn_type_summarizer.mdx index 64fb42cc8137a2..3f8706a1270ae2 100644 --- a/api_docs/kbn_type_summarizer.mdx +++ b/api_docs/kbn_type_summarizer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-type-summarizer title: "@kbn/type-summarizer" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/type-summarizer plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/type-summarizer'] --- import kbnTypeSummarizerObj from './kbn_type_summarizer.devdocs.json'; diff --git a/api_docs/kbn_type_summarizer_core.mdx b/api_docs/kbn_type_summarizer_core.mdx index dd89364666363c..bf7a69a56df5d4 100644 --- a/api_docs/kbn_type_summarizer_core.mdx +++ b/api_docs/kbn_type_summarizer_core.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-type-summarizer-core title: "@kbn/type-summarizer-core" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/type-summarizer-core plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/type-summarizer-core'] --- import kbnTypeSummarizerCoreObj from './kbn_type_summarizer_core.devdocs.json'; diff --git a/api_docs/kbn_typed_react_router_config.mdx b/api_docs/kbn_typed_react_router_config.mdx index 23e9c96d0b6c3a..ad0bbd4d03f8e4 100644 --- a/api_docs/kbn_typed_react_router_config.mdx +++ b/api_docs/kbn_typed_react_router_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-typed-react-router-config title: "@kbn/typed-react-router-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/typed-react-router-config plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/typed-react-router-config'] --- import kbnTypedReactRouterConfigObj from './kbn_typed_react_router_config.devdocs.json'; diff --git a/api_docs/kbn_ui_theme.mdx b/api_docs/kbn_ui_theme.mdx index 19474f6670cef3..3b681d45d16fcc 100644 --- a/api_docs/kbn_ui_theme.mdx +++ b/api_docs/kbn_ui_theme.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ui-theme title: "@kbn/ui-theme" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ui-theme plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ui-theme'] --- import kbnUiThemeObj from './kbn_ui_theme.devdocs.json'; diff --git a/api_docs/kbn_user_profile_components.devdocs.json b/api_docs/kbn_user_profile_components.devdocs.json index ee6fa83b35cdff..5ef1677f7275b3 100644 --- a/api_docs/kbn_user_profile_components.devdocs.json +++ b/api_docs/kbn_user_profile_components.devdocs.json @@ -187,7 +187,7 @@ }, " extends Omit<", "EuiAvatarProps", - ", \"type\" | \"color\" | \"name\" | \"iconColor\" | \"iconType\" | \"iconSize\" | \"initials\" | \"initialsLength\" | \"imageUrl\">" + ", \"type\" | \"color\" | \"iconColor\" | \"name\" | \"iconType\" | \"iconSize\" | \"initials\" | \"initialsLength\" | \"imageUrl\">" ], "path": "packages/kbn-user-profile-components/src/user_avatar.tsx", "deprecated": false, diff --git a/api_docs/kbn_user_profile_components.mdx b/api_docs/kbn_user_profile_components.mdx index 75a28b8f9625ce..1c8f82930ce330 100644 --- a/api_docs/kbn_user_profile_components.mdx +++ b/api_docs/kbn_user_profile_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-user-profile-components title: "@kbn/user-profile-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/user-profile-components plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/user-profile-components'] --- import kbnUserProfileComponentsObj from './kbn_user_profile_components.devdocs.json'; diff --git a/api_docs/kbn_utility_types.mdx b/api_docs/kbn_utility_types.mdx index e78d2da1c8e98e..1f1ddd4c5d338b 100644 --- a/api_docs/kbn_utility_types.mdx +++ b/api_docs/kbn_utility_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-utility-types title: "@kbn/utility-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/utility-types plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/utility-types'] --- import kbnUtilityTypesObj from './kbn_utility_types.devdocs.json'; diff --git a/api_docs/kbn_utility_types_jest.mdx b/api_docs/kbn_utility_types_jest.mdx index a0485775e59f34..a5504922e01ab4 100644 --- a/api_docs/kbn_utility_types_jest.mdx +++ b/api_docs/kbn_utility_types_jest.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-utility-types-jest title: "@kbn/utility-types-jest" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/utility-types-jest plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/utility-types-jest'] --- import kbnUtilityTypesJestObj from './kbn_utility_types_jest.devdocs.json'; diff --git a/api_docs/kbn_utils.mdx b/api_docs/kbn_utils.mdx index af12e7271b0e20..4005e8e70ea951 100644 --- a/api_docs/kbn_utils.mdx +++ b/api_docs/kbn_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-utils title: "@kbn/utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/utils plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/utils'] --- import kbnUtilsObj from './kbn_utils.devdocs.json'; diff --git a/api_docs/kbn_yarn_lock_validator.mdx b/api_docs/kbn_yarn_lock_validator.mdx index 08a304f655c655..c5cd52ebd26061 100644 --- a/api_docs/kbn_yarn_lock_validator.mdx +++ b/api_docs/kbn_yarn_lock_validator.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-yarn-lock-validator title: "@kbn/yarn-lock-validator" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/yarn-lock-validator plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/yarn-lock-validator'] --- import kbnYarnLockValidatorObj from './kbn_yarn_lock_validator.devdocs.json'; diff --git a/api_docs/kibana_overview.mdx b/api_docs/kibana_overview.mdx index c79f2b844406ba..ea2606287ef980 100644 --- a/api_docs/kibana_overview.mdx +++ b/api_docs/kibana_overview.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kibanaOverview title: "kibanaOverview" image: https://source.unsplash.com/400x175/?github description: API docs for the kibanaOverview plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kibanaOverview'] --- import kibanaOverviewObj from './kibana_overview.devdocs.json'; diff --git a/api_docs/kibana_react.devdocs.json b/api_docs/kibana_react.devdocs.json index f435702cea48a8..f2c484815e9b2b 100644 --- a/api_docs/kibana_react.devdocs.json +++ b/api_docs/kibana_react.devdocs.json @@ -1723,8 +1723,7 @@ "id": "def-public.RedirectAppLinks", "type": "Function", "tags": [ - "deprecated", - "kbn-shared-ux-components" + "deprecated" ], "label": "RedirectAppLinks", "description": [ @@ -4010,7 +4009,7 @@ "signature": [ "Omit<", "EuiPageProps", - ", \"paddingSize\"> & { template?: \"default\" | \"empty\" | \"centeredBody\" | \"centeredContent\" | undefined; paddingSize?: \"none\" | \"s\" | \"m\" | \"l\" | undefined; pageSideBar?: React.ReactNode; pageSideBarProps?: ", + ", \"paddingSize\"> & { template?: \"default\" | \"empty\" | \"centeredBody\" | \"centeredContent\" | undefined; paddingSize?: \"none\" | \"m\" | \"s\" | \"l\" | undefined; pageSideBar?: React.ReactNode; pageSideBarProps?: ", "EuiPageSideBarProps", " | undefined; pageHeader?: ", "EuiPageHeaderProps", diff --git a/api_docs/kibana_react.mdx b/api_docs/kibana_react.mdx index 64f1f90d311d5d..4788026b584d1e 100644 --- a/api_docs/kibana_react.mdx +++ b/api_docs/kibana_react.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kibanaReact title: "kibanaReact" image: https://source.unsplash.com/400x175/?github description: API docs for the kibanaReact plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kibanaReact'] --- import kibanaReactObj from './kibana_react.devdocs.json'; diff --git a/api_docs/kibana_utils.mdx b/api_docs/kibana_utils.mdx index dd42a71d184f47..9a38795b043ef2 100644 --- a/api_docs/kibana_utils.mdx +++ b/api_docs/kibana_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kibanaUtils title: "kibanaUtils" image: https://source.unsplash.com/400x175/?github description: API docs for the kibanaUtils plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kibanaUtils'] --- import kibanaUtilsObj from './kibana_utils.devdocs.json'; diff --git a/api_docs/kubernetes_security.mdx b/api_docs/kubernetes_security.mdx index e7c79e92d4a775..1f9dfd2495c181 100644 --- a/api_docs/kubernetes_security.mdx +++ b/api_docs/kubernetes_security.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kubernetesSecurity title: "kubernetesSecurity" image: https://source.unsplash.com/400x175/?github description: API docs for the kubernetesSecurity plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kubernetesSecurity'] --- import kubernetesSecurityObj from './kubernetes_security.devdocs.json'; diff --git a/api_docs/lens.devdocs.json b/api_docs/lens.devdocs.json index edff001999c49c..ab0de890a8b3ce 100644 --- a/api_docs/lens.devdocs.json +++ b/api_docs/lens.devdocs.json @@ -1235,7 +1235,7 @@ "label": "xScaleType", "description": [], "signature": [ - "\"time\" | \"linear\" | \"ordinal\"" + "\"linear\" | \"time\" | \"ordinal\"" ], "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", "deprecated": false @@ -1302,7 +1302,13 @@ "label": "decorations", "description": [], "signature": [ - "DataDecorationConfigResult", + { + "pluginId": "expressionXY", + "scope": "common", + "docId": "kibExpressionXYPluginApi", + "section": "def-common.DataDecorationConfigResult", + "text": "DataDecorationConfigResult" + }, "[] | undefined" ], "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", @@ -3779,7 +3785,7 @@ "\nThe change type indicates what was changed in this table compared to the currently active table of this layer." ], "signature": [ - "\"initial\" | \"layers\" | \"unchanged\" | \"reduced\" | \"extended\" | \"reorder\"" + "\"layers\" | \"initial\" | \"unchanged\" | \"reduced\" | \"extended\" | \"reorder\"" ], "path": "x-pack/plugins/lens/public/types.ts", "deprecated": false @@ -7921,7 +7927,7 @@ "label": "XScaleType", "description": [], "signature": [ - "\"time\" | \"linear\" | \"ordinal\"" + "\"linear\" | \"time\" | \"ordinal\"" ], "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", "deprecated": false, @@ -7999,7 +8005,7 @@ "label": "YScaleType", "description": [], "signature": [ - "\"log\" | \"time\" | \"linear\" | \"sqrt\"" + "\"linear\" | \"log\" | \"time\" | \"sqrt\"" ], "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", "deprecated": false, @@ -9115,7 +9121,7 @@ "label": "OperationTypePost712", "description": [], "signature": [ - "\"range\" | \"min\" | \"max\" | \"sum\" | \"filters\" | \"count\" | \"date_histogram\" | \"percentile\" | \"average\" | \"terms\" | \"median\" | \"cumulative_sum\" | \"moving_average\" | \"unique_count\" | \"last_value\" | \"counter_rate\" | \"differences\"" + "\"range\" | \"min\" | \"max\" | \"filters\" | \"count\" | \"date_histogram\" | \"percentile\" | \"sum\" | \"average\" | \"terms\" | \"median\" | \"cumulative_sum\" | \"moving_average\" | \"unique_count\" | \"last_value\" | \"counter_rate\" | \"differences\"" ], "path": "x-pack/plugins/lens/server/migrations/types.ts", "deprecated": false, @@ -9129,7 +9135,7 @@ "label": "OperationTypePre712", "description": [], "signature": [ - "\"range\" | \"min\" | \"max\" | \"sum\" | \"filters\" | \"count\" | \"date_histogram\" | \"percentile\" | \"terms\" | \"avg\" | \"median\" | \"cumulative_sum\" | \"derivative\" | \"moving_average\" | \"last_value\" | \"counter_rate\" | \"cardinality\"" + "\"range\" | \"min\" | \"max\" | \"filters\" | \"count\" | \"date_histogram\" | \"percentile\" | \"sum\" | \"terms\" | \"avg\" | \"median\" | \"cumulative_sum\" | \"derivative\" | \"moving_average\" | \"last_value\" | \"counter_rate\" | \"cardinality\"" ], "path": "x-pack/plugins/lens/server/migrations/types.ts", "deprecated": false, @@ -9448,42 +9454,6 @@ } ], "interfaces": [ - { - "parentPluginId": "lens", - "id": "def-common.BucketedAggregation", - "type": "Interface", - "tags": [], - "label": "BucketedAggregation", - "description": [], - "signature": [ - { - "pluginId": "lens", - "scope": "common", - "docId": "kibLensPluginApi", - "section": "def-common.BucketedAggregation", - "text": "BucketedAggregation" - }, - "" - ], - "path": "x-pack/plugins/lens/common/api.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "lens", - "id": "def-common.BucketedAggregation.buckets", - "type": "Array", - "tags": [], - "label": "buckets", - "description": [], - "signature": [ - "{ key: KeyType; count: number; }[]" - ], - "path": "x-pack/plugins/lens/common/api.ts", - "deprecated": false - } - ], - "initialIsOpen": false - }, { "parentPluginId": "lens", "id": "def-common.DateRange", @@ -9553,108 +9523,6 @@ ], "initialIsOpen": false }, - { - "parentPluginId": "lens", - "id": "def-common.FieldStatsResponse", - "type": "Interface", - "tags": [], - "label": "FieldStatsResponse", - "description": [], - "signature": [ - { - "pluginId": "lens", - "scope": "common", - "docId": "kibLensPluginApi", - "section": "def-common.FieldStatsResponse", - "text": "FieldStatsResponse" - }, - "" - ], - "path": "x-pack/plugins/lens/common/api.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "lens", - "id": "def-common.FieldStatsResponse.totalDocuments", - "type": "number", - "tags": [], - "label": "totalDocuments", - "description": [], - "signature": [ - "number | undefined" - ], - "path": "x-pack/plugins/lens/common/api.ts", - "deprecated": false - }, - { - "parentPluginId": "lens", - "id": "def-common.FieldStatsResponse.sampledDocuments", - "type": "number", - "tags": [], - "label": "sampledDocuments", - "description": [], - "signature": [ - "number | undefined" - ], - "path": "x-pack/plugins/lens/common/api.ts", - "deprecated": false - }, - { - "parentPluginId": "lens", - "id": "def-common.FieldStatsResponse.sampledValues", - "type": "number", - "tags": [], - "label": "sampledValues", - "description": [], - "signature": [ - "number | undefined" - ], - "path": "x-pack/plugins/lens/common/api.ts", - "deprecated": false - }, - { - "parentPluginId": "lens", - "id": "def-common.FieldStatsResponse.histogram", - "type": "Object", - "tags": [], - "label": "histogram", - "description": [], - "signature": [ - { - "pluginId": "lens", - "scope": "common", - "docId": "kibLensPluginApi", - "section": "def-common.BucketedAggregation", - "text": "BucketedAggregation" - }, - " | undefined" - ], - "path": "x-pack/plugins/lens/common/api.ts", - "deprecated": false - }, - { - "parentPluginId": "lens", - "id": "def-common.FieldStatsResponse.topValues", - "type": "Object", - "tags": [], - "label": "topValues", - "description": [], - "signature": [ - { - "pluginId": "lens", - "scope": "common", - "docId": "kibLensPluginApi", - "section": "def-common.BucketedAggregation", - "text": "BucketedAggregation" - }, - " | undefined" - ], - "path": "x-pack/plugins/lens/common/api.ts", - "deprecated": false - } - ], - "initialIsOpen": false - }, { "parentPluginId": "lens", "id": "def-common.MetricState", @@ -9779,69 +9647,6 @@ ], "initialIsOpen": false }, - { - "parentPluginId": "lens", - "id": "def-common.NumberStatsResult", - "type": "Interface", - "tags": [], - "label": "NumberStatsResult", - "description": [], - "path": "x-pack/plugins/lens/common/api.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "lens", - "id": "def-common.NumberStatsResult.count", - "type": "number", - "tags": [], - "label": "count", - "description": [], - "path": "x-pack/plugins/lens/common/api.ts", - "deprecated": false - }, - { - "parentPluginId": "lens", - "id": "def-common.NumberStatsResult.histogram", - "type": "Object", - "tags": [], - "label": "histogram", - "description": [], - "signature": [ - { - "pluginId": "lens", - "scope": "common", - "docId": "kibLensPluginApi", - "section": "def-common.BucketedAggregation", - "text": "BucketedAggregation" - }, - "" - ], - "path": "x-pack/plugins/lens/common/api.ts", - "deprecated": false - }, - { - "parentPluginId": "lens", - "id": "def-common.NumberStatsResult.topValues", - "type": "Object", - "tags": [], - "label": "topValues", - "description": [], - "signature": [ - { - "pluginId": "lens", - "scope": "common", - "docId": "kibLensPluginApi", - "section": "def-common.BucketedAggregation", - "text": "BucketedAggregation" - }, - "" - ], - "path": "x-pack/plugins/lens/common/api.ts", - "deprecated": false - } - ], - "initialIsOpen": false - }, { "parentPluginId": "lens", "id": "def-common.PersistableFilter", @@ -10171,49 +9976,6 @@ } ], "initialIsOpen": false - }, - { - "parentPluginId": "lens", - "id": "def-common.TopValuesResult", - "type": "Interface", - "tags": [], - "label": "TopValuesResult", - "description": [], - "path": "x-pack/plugins/lens/common/api.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "lens", - "id": "def-common.TopValuesResult.count", - "type": "number", - "tags": [], - "label": "count", - "description": [], - "path": "x-pack/plugins/lens/common/api.ts", - "deprecated": false - }, - { - "parentPluginId": "lens", - "id": "def-common.TopValuesResult.topValues", - "type": "Object", - "tags": [], - "label": "topValues", - "description": [], - "signature": [ - { - "pluginId": "lens", - "scope": "common", - "docId": "kibLensPluginApi", - "section": "def-common.BucketedAggregation", - "text": "BucketedAggregation" - }, - "" - ], - "path": "x-pack/plugins/lens/common/api.ts", - "deprecated": false - } - ], - "initialIsOpen": false } ], "enums": [ diff --git a/api_docs/lens.mdx b/api_docs/lens.mdx index 56b5c9d5321104..a508b3d7d9c49a 100644 --- a/api_docs/lens.mdx +++ b/api_docs/lens.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/lens title: "lens" image: https://source.unsplash.com/400x175/?github description: API docs for the lens plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'lens'] --- import lensObj from './lens.devdocs.json'; @@ -21,7 +21,7 @@ Contact [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 621 | 0 | 535 | 40 | +| 606 | 0 | 520 | 40 | ## Client diff --git a/api_docs/license_api_guard.mdx b/api_docs/license_api_guard.mdx index bf8e34055ac922..97d8bfb9407bde 100644 --- a/api_docs/license_api_guard.mdx +++ b/api_docs/license_api_guard.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/licenseApiGuard title: "licenseApiGuard" image: https://source.unsplash.com/400x175/?github description: API docs for the licenseApiGuard plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'licenseApiGuard'] --- import licenseApiGuardObj from './license_api_guard.devdocs.json'; diff --git a/api_docs/license_management.mdx b/api_docs/license_management.mdx index da18f57b1e6ee7..8d179a53946f92 100644 --- a/api_docs/license_management.mdx +++ b/api_docs/license_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/licenseManagement title: "licenseManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the licenseManagement plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'licenseManagement'] --- import licenseManagementObj from './license_management.devdocs.json'; diff --git a/api_docs/licensing.mdx b/api_docs/licensing.mdx index 7d9d1d400a2046..629be729f60653 100644 --- a/api_docs/licensing.mdx +++ b/api_docs/licensing.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/licensing title: "licensing" image: https://source.unsplash.com/400x175/?github description: API docs for the licensing plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'licensing'] --- import licensingObj from './licensing.devdocs.json'; diff --git a/api_docs/lists.devdocs.json b/api_docs/lists.devdocs.json index f861be8fb6b2f0..5d10e9c1761df5 100644 --- a/api_docs/lists.devdocs.json +++ b/api_docs/lists.devdocs.json @@ -311,7 +311,7 @@ "label": "exceptionItems", "description": [], "signature": [ - "({ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | ({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }))[]" + "({ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | ({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }))[]" ], "path": "x-pack/plugins/lists/public/exceptions/components/builder/exception_items_renderer.tsx", "deprecated": false @@ -324,7 +324,7 @@ "label": "exceptionsToDelete", "description": [], "signature": [ - "{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }[]" + "{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }[]" ], "path": "x-pack/plugins/lists/public/exceptions/components/builder/exception_items_renderer.tsx", "deprecated": false @@ -585,7 +585,7 @@ "signature": [ "({ itemId, id, namespaceType, }: ", "GetExceptionListItemOptions", - ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | null>" + ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | null>" ], "path": "x-pack/plugins/lists/server/services/exception_lists/exception_list_client.ts", "deprecated": false, @@ -659,7 +659,7 @@ "signature": [ "({ comments, description, entries, itemId, meta, name, osTypes, tags, type, }: ", "CreateEndpointListItemOptions", - ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }>" + ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }>" ], "path": "x-pack/plugins/lists/server/services/exception_lists/exception_list_client.ts", "deprecated": false, @@ -695,7 +695,7 @@ "signature": [ "({ _version, comments, description, entries, id, itemId, meta, name, osTypes, tags, type, }: ", "UpdateEndpointListItemOptions", - ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | null>" + ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | null>" ], "path": "x-pack/plugins/lists/server/services/exception_lists/exception_list_client.ts", "deprecated": false, @@ -731,7 +731,7 @@ "signature": [ "({ itemId, id, }: ", "GetEndpointListItemOptions", - ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | null>" + ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | null>" ], "path": "x-pack/plugins/lists/server/services/exception_lists/exception_list_client.ts", "deprecated": false, @@ -881,7 +881,7 @@ "section": "def-server.CreateExceptionListItemOptions", "text": "CreateExceptionListItemOptions" }, - ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }>" + ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }>" ], "path": "x-pack/plugins/lists/server/services/exception_lists/exception_list_client.ts", "deprecated": false, @@ -929,7 +929,7 @@ "section": "def-server.UpdateExceptionListItemOptions", "text": "UpdateExceptionListItemOptions" }, - ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | null>" + ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | null>" ], "path": "x-pack/plugins/lists/server/services/exception_lists/exception_list_client.ts", "deprecated": false, @@ -971,7 +971,7 @@ "signature": [ "({ id, itemId, namespaceType, }: ", "DeleteExceptionListItemOptions", - ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | null>" + ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | null>" ], "path": "x-pack/plugins/lists/server/services/exception_lists/exception_list_client.ts", "deprecated": false, @@ -1041,7 +1041,7 @@ "signature": [ "({ id, itemId, }: ", "DeleteEndpointListItemOptions", - ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | null>" + ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | null>" ], "path": "x-pack/plugins/lists/server/services/exception_lists/exception_list_client.ts", "deprecated": false, @@ -1075,7 +1075,7 @@ "signature": [ "({ listId, filter, perPage, pit, page, searchAfter, sortField, sortOrder, namespaceType, }: ", "FindExceptionListItemOptions", - ") => Promise<({ data: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }[]; page: number; per_page: number; total: number; } & { pit?: string | undefined; }) | null>" + ") => Promise<({ data: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }[]; page: number; per_page: number; total: number; } & { pit?: string | undefined; }) | null>" ], "path": "x-pack/plugins/lists/server/services/exception_lists/exception_list_client.ts", "deprecated": false, @@ -1111,7 +1111,7 @@ "signature": [ "({ listId, filter, perPage, pit, page, searchAfter, sortField, sortOrder, namespaceType, }: ", "FindExceptionListsItemOptions", - ") => Promise<({ data: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }[]; page: number; per_page: number; total: number; } & { pit?: string | undefined; }) | null>" + ") => Promise<({ data: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }[]; page: number; per_page: number; total: number; } & { pit?: string | undefined; }) | null>" ], "path": "x-pack/plugins/lists/server/services/exception_lists/exception_list_client.ts", "deprecated": false, @@ -1147,7 +1147,7 @@ "signature": [ "({ perPage, pit, page, searchAfter, sortField, sortOrder, valueListId, }: ", "FindValueListExceptionListsItems", - ") => Promise<({ data: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }[]; page: number; per_page: number; total: number; } & { pit?: string | undefined; }) | null>" + ") => Promise<({ data: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }[]; page: number; per_page: number; total: number; } & { pit?: string | undefined; }) | null>" ], "path": "x-pack/plugins/lists/server/services/exception_lists/exception_list_client.ts", "deprecated": false, @@ -1219,7 +1219,7 @@ "signature": [ "({ filter, perPage, page, pit, searchAfter, sortField, sortOrder, }: ", "FindEndpointListItemOptions", - ") => Promise<({ data: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }[]; page: number; per_page: number; total: number; } & { pit?: string | undefined; }) | null>" + ") => Promise<({ data: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }[]; page: number; per_page: number; total: number; } & { pit?: string | undefined; }) | null>" ], "path": "x-pack/plugins/lists/server/services/exception_lists/exception_list_client.ts", "deprecated": false, @@ -1668,7 +1668,7 @@ "signature": [ "({ id }: ", "GetListOptions", - ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; version: number; } | null>" + ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; version: number; } | null>" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, @@ -1704,7 +1704,7 @@ "signature": [ "({ id, deserializer, immutable, serializer, name, description, type, meta, version, }: ", "CreateListOptions", - ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; version: number; }>" + ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; version: number; }>" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, @@ -1740,7 +1740,7 @@ "signature": [ "({ id, deserializer, serializer, name, description, immutable, type, meta, version, }: ", "CreateListIfItDoesNotExistOptions", - ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; version: number; }>" + ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; version: number; }>" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, @@ -2232,7 +2232,7 @@ "signature": [ "({ id }: ", "DeleteListItemOptions", - ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; value: string; } | null>" + ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; value: string; } | null>" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, @@ -2268,7 +2268,7 @@ "signature": [ "({ listId, value, type, }: ", "DeleteListItemByValueOptions", - ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; value: string; }[]>" + ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; value: string; }[]>" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, @@ -2304,7 +2304,7 @@ "signature": [ "({ id }: ", "DeleteListOptions", - ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; version: number; } | null>" + ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; version: number; } | null>" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, @@ -2374,7 +2374,7 @@ "signature": [ "({ deserializer, serializer, type, listId, stream, meta, version, }: ", "ImportListItemsToStreamOptions", - ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; version: number; } | null>" + ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; version: number; } | null>" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, @@ -2408,7 +2408,7 @@ "signature": [ "({ listId, value, type, }: ", "GetListItemByValueOptions", - ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; value: string; }[]>" + ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; value: string; }[]>" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, @@ -2444,7 +2444,7 @@ "signature": [ "({ id, deserializer, serializer, listId, value, type, meta, }: ", "CreateListItemOptions", - ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; value: string; } | null>" + ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; value: string; } | null>" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, @@ -2478,7 +2478,7 @@ "signature": [ "({ _version, id, value, meta, }: ", "UpdateListItemOptions", - ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; value: string; } | null>" + ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; value: string; } | null>" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, @@ -2512,7 +2512,7 @@ "signature": [ "({ _version, id, name, description, meta, version, }: ", "UpdateListOptions", - ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; version: number; } | null>" + ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; version: number; } | null>" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, @@ -2546,7 +2546,7 @@ "signature": [ "({ id }: ", "GetListItemOptions", - ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; value: string; } | null>" + ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; value: string; } | null>" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, @@ -2582,7 +2582,7 @@ "signature": [ "({ type, listId, value, }: ", "GetListItemsByValueOptions", - ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; value: string; }[]>" + ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; value: string; }[]>" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, @@ -2618,7 +2618,7 @@ "signature": [ "({ type, listId, value, }: ", "SearchListItemByValuesOptions", - ") => Promise<{ items: { _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; value: string; }[]; value: unknown; }[]>" + ") => Promise<{ items: { _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; value: string; }[]; value: unknown; }[]>" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, @@ -2654,7 +2654,7 @@ "signature": [ "({ filter, currentIndexPosition, perPage, page, sortField, sortOrder, searchAfter, }: ", "FindListOptions", - ") => Promise<{ cursor: string; data: { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; version: number; }[]; page: number; per_page: number; total: number; }>" + ") => Promise<{ cursor: string; data: { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; version: number; }[]; page: number; per_page: number; total: number; }>" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, @@ -2690,7 +2690,7 @@ "signature": [ "({ listId, filter, currentIndexPosition, perPage, page, sortField, sortOrder, searchAfter, }: ", "FindListItemOptions", - ") => Promise<{ cursor: string; data: { _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; value: string; }[]; page: number; per_page: number; total: number; } | null>" + ") => Promise<{ cursor: string; data: { _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; updated_at: string; updated_by: string; value: string; }[]; page: number; per_page: number; total: number; } | null>" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, @@ -2757,7 +2757,7 @@ "an array with the exception list item entries" ], "signature": [ - "({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]" + "({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]" ], "path": "x-pack/plugins/lists/server/services/exception_lists/exception_list_client_types.ts", "deprecated": false @@ -3049,7 +3049,7 @@ "item exception entries logic" ], "signature": [ - "({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"text\" | \"keyword\" | \"ip\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]" + "({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"float\" | \"half_float\" | \"integer\" | \"byte\" | \"long_range\" | \"integer_range\" | \"float_range\" | \"double_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]" ], "path": "x-pack/plugins/lists/server/services/exception_lists/exception_list_client_types.ts", "deprecated": false @@ -3749,7 +3749,9 @@ "TransportRequestOptions", " | undefined): Promise<", "WriteResponseBase", - ">; }; name: string | symbol; transform: ", + ">; }; cluster: ", + "default", + "; eql: ", "default", "; search: { >; }; cluster: ", - "default", - "; eql: ", - "default", - "; create: { (this: That, params: ", + ">; }; create: { (this: That, params: ", "CreateRequest", " | ", "CreateRequest", @@ -3817,7 +3815,7 @@ "default", "; security: ", "default", - "; index: { (this: That, params: ", + "; name: string | symbol; index: { (this: That, params: ", "IndexRequest", " | ", "IndexRequest", @@ -4829,6 +4827,8 @@ "TermvectorsResponse", ">; }; textStructure: ", "default", + "; transform: ", + "default", "; updateByQuery: { (this: That, params: ", "UpdateByQueryRequest", " | ", diff --git a/api_docs/lists.mdx b/api_docs/lists.mdx index 65eeff9f44d3b6..d30affa0d659cb 100644 --- a/api_docs/lists.mdx +++ b/api_docs/lists.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/lists title: "lists" image: https://source.unsplash.com/400x175/?github description: API docs for the lists plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'lists'] --- import listsObj from './lists.devdocs.json'; diff --git a/api_docs/management.mdx b/api_docs/management.mdx index fdfb51696697c4..4148fc542685a5 100644 --- a/api_docs/management.mdx +++ b/api_docs/management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/management title: "management" image: https://source.unsplash.com/400x175/?github description: API docs for the management plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'management'] --- import managementObj from './management.devdocs.json'; diff --git a/api_docs/maps.devdocs.json b/api_docs/maps.devdocs.json index 3ec66d75cdeca4..b5d295cb11f7a5 100644 --- a/api_docs/maps.devdocs.json +++ b/api_docs/maps.devdocs.json @@ -4003,7 +4003,7 @@ "AbstractSourceDescriptor", " & { id: string; indexPatternId: string; geoField?: string | undefined; applyGlobalQuery: boolean; applyGlobalTime: boolean; applyForceRefresh: boolean; } & { metrics: ", "AggDescriptor", - "[]; } & { indexPatternTitle?: string | undefined; term: string; whereQuery?: ", + "[]; } & { term: string; whereQuery?: ", "Query", " | undefined; size?: number | undefined; type: ", { @@ -4212,7 +4212,7 @@ "section": "def-common.VectorStyleDescriptor", "text": "VectorStyleDescriptor" }, - "; }" + "; disableTooltips?: boolean | undefined; }" ], "path": "x-pack/plugins/maps/common/descriptor_types/layer_descriptor_types.ts", "deprecated": false, diff --git a/api_docs/maps.mdx b/api_docs/maps.mdx index 89f2ef7e251489..7bd44726137965 100644 --- a/api_docs/maps.mdx +++ b/api_docs/maps.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/maps title: "maps" image: https://source.unsplash.com/400x175/?github description: API docs for the maps plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'maps'] --- import mapsObj from './maps.devdocs.json'; diff --git a/api_docs/maps_ems.mdx b/api_docs/maps_ems.mdx index 870839d9b98403..39685ce837195d 100644 --- a/api_docs/maps_ems.mdx +++ b/api_docs/maps_ems.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/mapsEms title: "mapsEms" image: https://source.unsplash.com/400x175/?github description: API docs for the mapsEms plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'mapsEms'] --- import mapsEmsObj from './maps_ems.devdocs.json'; diff --git a/api_docs/ml.devdocs.json b/api_docs/ml.devdocs.json index 234dc00a385fc3..2e5a2b35f7c3a4 100644 --- a/api_docs/ml.devdocs.json +++ b/api_docs/ml.devdocs.json @@ -1262,7 +1262,7 @@ }, " extends Pick<", "UseDataGridReturnType", - ", \"status\" | \"baseline\" | \"rowCount\" | \"errorMessage\" | \"chartsVisible\" | \"chartsButtonVisible\" | \"ccsWarning\" | \"columnsWithCharts\" | \"invalidSortingColumnns\" | \"noDataMessage\" | \"onChangeItemsPerPage\" | \"onChangePage\" | \"onSort\" | \"pagination\" | \"setPagination\" | \"setVisibleColumns\" | \"rowCountRelation\" | \"sortingColumns\" | \"tableItems\" | \"toggleChartVisibility\" | \"visibleColumns\" | \"predictionFieldName\" | \"resultsField\">" + ", \"status\" | \"rowCount\" | \"errorMessage\" | \"baseline\" | \"chartsVisible\" | \"chartsButtonVisible\" | \"ccsWarning\" | \"columnsWithCharts\" | \"invalidSortingColumnns\" | \"noDataMessage\" | \"onChangeItemsPerPage\" | \"onChangePage\" | \"onSort\" | \"pagination\" | \"setPagination\" | \"setVisibleColumns\" | \"rowCountRelation\" | \"sortingColumns\" | \"tableItems\" | \"toggleChartVisibility\" | \"visibleColumns\" | \"predictionFieldName\" | \"resultsField\">" ], "path": "x-pack/plugins/ml/public/application/components/data_grid/types.ts", "deprecated": false, diff --git a/api_docs/ml.mdx b/api_docs/ml.mdx index 19d8deb7d8c3f9..6b22753e7ff825 100644 --- a/api_docs/ml.mdx +++ b/api_docs/ml.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ml title: "ml" image: https://source.unsplash.com/400x175/?github description: API docs for the ml plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ml'] --- import mlObj from './ml.devdocs.json'; diff --git a/api_docs/monitoring.mdx b/api_docs/monitoring.mdx index 5f03c903a09e54..010bf62297910d 100644 --- a/api_docs/monitoring.mdx +++ b/api_docs/monitoring.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/monitoring title: "monitoring" image: https://source.unsplash.com/400x175/?github description: API docs for the monitoring plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'monitoring'] --- import monitoringObj from './monitoring.devdocs.json'; diff --git a/api_docs/monitoring_collection.mdx b/api_docs/monitoring_collection.mdx index 5e58137d24868b..dfe39c1bb2698b 100644 --- a/api_docs/monitoring_collection.mdx +++ b/api_docs/monitoring_collection.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/monitoringCollection title: "monitoringCollection" image: https://source.unsplash.com/400x175/?github description: API docs for the monitoringCollection plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'monitoringCollection'] --- import monitoringCollectionObj from './monitoring_collection.devdocs.json'; diff --git a/api_docs/navigation.devdocs.json b/api_docs/navigation.devdocs.json index 5e8590af0ad154..2e6c408e26acab 100644 --- a/api_docs/navigation.devdocs.json +++ b/api_docs/navigation.devdocs.json @@ -411,13 +411,13 @@ "DisambiguateSet", "<(", "DisambiguateSet", - " & { href: string; target?: string | undefined; rel?: string | undefined; } & Omit, \"color\" | \"href\" | \"onClick\">) | (", + " & { href: string; target?: string | undefined; rel?: string | undefined; } & Omit, \"color\" | \"onClick\" | \"href\">) | (", "DisambiguateSet", " & { onClick?: React.MouseEventHandler | undefined; onClickAriaLabel?: string | undefined; } & Omit, \"color\" | \"onClick\">), WithSpanProps> & WithSpanProps & { iconType?: ", "IconType", " | undefined; label: React.ReactNode; tooltipContent?: React.ReactNode; tooltipPosition?: ", "ToolTipPositions", - " | undefined; title?: string | undefined; color?: \"accent\" | \"subdued\" | \"hollow\" | undefined; size?: ", + " | undefined; title?: string | undefined; color?: \"subdued\" | \"accent\" | \"hollow\" | undefined; size?: ", "BetaBadgeSize", " | undefined; } & ", "DisambiguateSet", @@ -427,13 +427,13 @@ "DisambiguateSet", "<(", "DisambiguateSet", - " & { href: string; target?: string | undefined; rel?: string | undefined; } & Omit, \"color\" | \"href\" | \"onClick\">) | (", + " & { href: string; target?: string | undefined; rel?: string | undefined; } & Omit, \"color\" | \"onClick\" | \"href\">) | (", "DisambiguateSet", " & { onClick?: React.MouseEventHandler | undefined; onClickAriaLabel?: string | undefined; } & Omit, \"color\" | \"onClick\">), WithSpanProps> & WithSpanProps & { iconType?: ", "IconType", " | undefined; label: React.ReactNode; tooltipContent?: React.ReactNode; tooltipPosition?: ", "ToolTipPositions", - " | undefined; title?: string | undefined; color?: \"accent\" | \"subdued\" | \"hollow\" | undefined; size?: ", + " | undefined; title?: string | undefined; color?: \"subdued\" | \"accent\" | \"hollow\" | undefined; size?: ", "BetaBadgeSize", " | undefined; } & ", "DisambiguateSet", @@ -445,15 +445,15 @@ "DisambiguateSet", " & { href: string; target?: string | undefined; rel?: string | undefined; } & Omit, \"color\" | \"href\" | \"onClick\">) | (", + " & { href: string; target?: string | undefined; rel?: string | undefined; } & Omit, \"color\" | \"onClick\" | \"href\">) | (", "DisambiguateSet", " & { onClick?: React.MouseEventHandler | undefined; onClickAriaLabel?: string | undefined; } & Omit, \"color\" | \"onClick\">)> & ", "DisambiguateSet", - " & { href: string; target?: string | undefined; rel?: string | undefined; } & Omit, \"color\" | \"href\" | \"onClick\"> & { iconType?: ", + " & { href: string; target?: string | undefined; rel?: string | undefined; } & Omit, \"color\" | \"onClick\" | \"href\"> & { iconType?: ", "IconType", " | undefined; label: React.ReactNode; tooltipContent?: React.ReactNode; tooltipPosition?: ", "ToolTipPositions", - " | undefined; title?: string | undefined; color?: \"accent\" | \"subdued\" | \"hollow\" | undefined; size?: ", + " | undefined; title?: string | undefined; color?: \"subdued\" | \"accent\" | \"hollow\" | undefined; size?: ", "BetaBadgeSize", " | undefined; } & ", "DisambiguateSet", @@ -463,15 +463,15 @@ "DisambiguateSet", " & { href: string; target?: string | undefined; rel?: string | undefined; } & Omit, \"color\" | \"href\" | \"onClick\">) | (", + " & { href: string; target?: string | undefined; rel?: string | undefined; } & Omit, \"color\" | \"onClick\" | \"href\">) | (", "DisambiguateSet", " & { onClick?: React.MouseEventHandler | undefined; onClickAriaLabel?: string | undefined; } & Omit, \"color\" | \"onClick\">)> & ", "DisambiguateSet", - " & { href: string; target?: string | undefined; rel?: string | undefined; } & Omit, \"color\" | \"href\" | \"onClick\"> & { iconType?: ", + " & { href: string; target?: string | undefined; rel?: string | undefined; } & Omit, \"color\" | \"onClick\" | \"href\"> & { iconType?: ", "IconType", " | undefined; label: React.ReactNode; tooltipContent?: React.ReactNode; tooltipPosition?: ", "ToolTipPositions", - " | undefined; title?: string | undefined; color?: \"accent\" | \"subdued\" | \"hollow\" | undefined; size?: ", + " | undefined; title?: string | undefined; color?: \"subdued\" | \"accent\" | \"hollow\" | undefined; size?: ", "BetaBadgeSize", " | undefined; } & ", "DisambiguateSet", @@ -483,15 +483,15 @@ "DisambiguateSet", " & { href: string; target?: string | undefined; rel?: string | undefined; } & Omit, \"color\" | \"href\" | \"onClick\">) | (", + " & { href: string; target?: string | undefined; rel?: string | undefined; } & Omit, \"color\" | \"onClick\" | \"href\">) | (", "DisambiguateSet", " & { onClick?: React.MouseEventHandler | undefined; onClickAriaLabel?: string | undefined; } & Omit, \"color\" | \"onClick\">)> & ", "DisambiguateSet", - " & { href: string; target?: string | undefined; rel?: string | undefined; } & Omit, \"color\" | \"href\" | \"onClick\"> & { iconType?: ", + " & { href: string; target?: string | undefined; rel?: string | undefined; } & Omit, \"color\" | \"onClick\" | \"href\"> & { iconType?: ", "IconType", " | undefined; label: React.ReactNode; tooltipContent?: React.ReactNode; tooltipPosition?: ", "ToolTipPositions", - " | undefined; title?: string | undefined; color?: \"accent\" | \"subdued\" | \"hollow\" | undefined; size?: ", + " | undefined; title?: string | undefined; color?: \"subdued\" | \"accent\" | \"hollow\" | undefined; size?: ", "BetaBadgeSize", " | undefined; } & ", "DisambiguateSet", @@ -503,7 +503,7 @@ "DisambiguateSet", " & { href: string; target?: string | undefined; rel?: string | undefined; } & Omit, \"color\" | \"href\" | \"onClick\">) | (", + " & { href: string; target?: string | undefined; rel?: string | undefined; } & Omit, \"color\" | \"onClick\" | \"href\">) | (", "DisambiguateSet", " & { onClick?: React.MouseEventHandler | undefined; onClickAriaLabel?: string | undefined; } & Omit, \"color\" | \"onClick\">)> & ", "DisambiguateSet", @@ -511,7 +511,7 @@ "IconType", " | undefined; label: React.ReactNode; tooltipContent?: React.ReactNode; tooltipPosition?: ", "ToolTipPositions", - " | undefined; title?: string | undefined; color?: \"accent\" | \"subdued\" | \"hollow\" | undefined; size?: ", + " | undefined; title?: string | undefined; color?: \"subdued\" | \"accent\" | \"hollow\" | undefined; size?: ", "BetaBadgeSize", " | undefined; } & ", "DisambiguateSet", @@ -521,7 +521,7 @@ "DisambiguateSet", " & { href: string; target?: string | undefined; rel?: string | undefined; } & Omit, \"color\" | \"href\" | \"onClick\">) | (", + " & { href: string; target?: string | undefined; rel?: string | undefined; } & Omit, \"color\" | \"onClick\" | \"href\">) | (", "DisambiguateSet", " & { onClick?: React.MouseEventHandler | undefined; onClickAriaLabel?: string | undefined; } & Omit, \"color\" | \"onClick\">)> & ", "DisambiguateSet", @@ -529,7 +529,7 @@ "IconType", " | undefined; label: React.ReactNode; tooltipContent?: React.ReactNode; tooltipPosition?: ", "ToolTipPositions", - " | undefined; title?: string | undefined; color?: \"accent\" | \"subdued\" | \"hollow\" | undefined; size?: ", + " | undefined; title?: string | undefined; color?: \"subdued\" | \"accent\" | \"hollow\" | undefined; size?: ", "BetaBadgeSize", " | undefined; } & ", "DisambiguateSet", @@ -541,7 +541,7 @@ "DisambiguateSet", " & { href: string; target?: string | undefined; rel?: string | undefined; } & Omit, \"color\" | \"href\" | \"onClick\">) | (", + " & { href: string; target?: string | undefined; rel?: string | undefined; } & Omit, \"color\" | \"onClick\" | \"href\">) | (", "DisambiguateSet", " & { onClick?: React.MouseEventHandler | undefined; onClickAriaLabel?: string | undefined; } & Omit, \"color\" | \"onClick\">)> & ", "DisambiguateSet", @@ -549,7 +549,7 @@ "IconType", " | undefined; label: React.ReactNode; tooltipContent?: React.ReactNode; tooltipPosition?: ", "ToolTipPositions", - " | undefined; title?: string | undefined; color?: \"accent\" | \"subdued\" | \"hollow\" | undefined; size?: ", + " | undefined; title?: string | undefined; color?: \"subdued\" | \"accent\" | \"hollow\" | undefined; size?: ", "BetaBadgeSize", " | undefined; } & ", "DisambiguateSet", diff --git a/api_docs/navigation.mdx b/api_docs/navigation.mdx index 9f614a7d89534d..8b42d413477f11 100644 --- a/api_docs/navigation.mdx +++ b/api_docs/navigation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/navigation title: "navigation" image: https://source.unsplash.com/400x175/?github description: API docs for the navigation plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'navigation'] --- import navigationObj from './navigation.devdocs.json'; diff --git a/api_docs/newsfeed.mdx b/api_docs/newsfeed.mdx index 4ae290ed9edcbf..45323757533465 100644 --- a/api_docs/newsfeed.mdx +++ b/api_docs/newsfeed.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/newsfeed title: "newsfeed" image: https://source.unsplash.com/400x175/?github description: API docs for the newsfeed plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'newsfeed'] --- import newsfeedObj from './newsfeed.devdocs.json'; diff --git a/api_docs/observability.devdocs.json b/api_docs/observability.devdocs.json index 3de0f18c8e0872..704fcd389865d9 100644 --- a/api_docs/observability.devdocs.json +++ b/api_docs/observability.devdocs.json @@ -696,11 +696,11 @@ }, " | undefined; list: () => string[]; }; selectedAlertId?: string | undefined; } & ", "CommonProps", - " & { as?: \"div\" | undefined; } & _EuiFlyoutProps & Omit, HTMLDivElement>, keyof _EuiFlyoutProps> & Omit, HTMLDivElement>, \"key\" | \"css\" | keyof React.HTMLAttributes> & { ref?: React.RefObject | ((instance: HTMLDivElement | null) => void) | null | undefined; }, \"children\" | \"onError\" | \"color\" | \"id\" | \"lang\" | \"tabIndex\" | \"aria-activedescendant\" | \"aria-atomic\" | \"aria-autocomplete\" | \"aria-busy\" | \"aria-checked\" | \"aria-colcount\" | \"aria-colindex\" | \"aria-colspan\" | \"aria-controls\" | \"aria-current\" | \"aria-describedby\" | \"aria-details\" | \"aria-disabled\" | \"aria-dropeffect\" | \"aria-errormessage\" | \"aria-expanded\" | \"aria-flowto\" | \"aria-grabbed\" | \"aria-haspopup\" | \"aria-hidden\" | \"aria-invalid\" | \"aria-keyshortcuts\" | \"aria-labelledby\" | \"aria-level\" | \"aria-live\" | \"aria-modal\" | \"aria-multiline\" | \"aria-multiselectable\" | \"aria-orientation\" | \"aria-owns\" | \"aria-placeholder\" | \"aria-posinset\" | \"aria-pressed\" | \"aria-readonly\" | \"aria-relevant\" | \"aria-required\" | \"aria-roledescription\" | \"aria-rowcount\" | \"aria-rowindex\" | \"aria-rowspan\" | \"aria-selected\" | \"aria-setsize\" | \"aria-sort\" | \"aria-valuemax\" | \"aria-valuemin\" | \"aria-valuenow\" | \"aria-valuetext\" | \"dangerouslySetInnerHTML\" | \"onCopy\" | \"onCopyCapture\" | \"onCut\" | \"onCutCapture\" | \"onPaste\" | \"onPasteCapture\" | \"onCompositionEnd\" | \"onCompositionEndCapture\" | \"onCompositionStart\" | \"onCompositionStartCapture\" | \"onCompositionUpdate\" | \"onCompositionUpdateCapture\" | \"onFocus\" | \"onFocusCapture\" | \"onBlur\" | \"onBlurCapture\" | \"onChange\" | \"onChangeCapture\" | \"onBeforeInput\" | \"onBeforeInputCapture\" | \"onInput\" | \"onInputCapture\" | \"onReset\" | \"onResetCapture\" | \"onSubmit\" | \"onSubmitCapture\" | \"onInvalid\" | \"onInvalidCapture\" | \"onLoad\" | \"onLoadCapture\" | \"onErrorCapture\" | \"onKeyDown\" | \"onKeyDownCapture\" | \"onKeyPress\" | \"onKeyPressCapture\" | \"onKeyUp\" | \"onKeyUpCapture\" | \"onAbort\" | \"onAbortCapture\" | \"onCanPlay\" | \"onCanPlayCapture\" | \"onCanPlayThrough\" | \"onCanPlayThroughCapture\" | \"onDurationChange\" | \"onDurationChangeCapture\" | \"onEmptied\" | \"onEmptiedCapture\" | \"onEncrypted\" | \"onEncryptedCapture\" | \"onEnded\" | \"onEndedCapture\" | \"onLoadedData\" | \"onLoadedDataCapture\" | \"onLoadedMetadata\" | \"onLoadedMetadataCapture\" | \"onLoadStart\" | \"onLoadStartCapture\" | \"onPause\" | \"onPauseCapture\" | \"onPlay\" | \"onPlayCapture\" | \"onPlaying\" | \"onPlayingCapture\" | \"onProgress\" | \"onProgressCapture\" | \"onRateChange\" | \"onRateChangeCapture\" | \"onSeeked\" | \"onSeekedCapture\" | \"onSeeking\" | \"onSeekingCapture\" | \"onStalled\" | \"onStalledCapture\" | \"onSuspend\" | \"onSuspendCapture\" | \"onTimeUpdate\" | \"onTimeUpdateCapture\" | \"onVolumeChange\" | \"onVolumeChangeCapture\" | \"onWaiting\" | \"onWaitingCapture\" | \"onAuxClick\" | \"onAuxClickCapture\" | \"onClick\" | \"onClickCapture\" | \"onContextMenu\" | \"onContextMenuCapture\" | \"onDoubleClick\" | \"onDoubleClickCapture\" | \"onDrag\" | \"onDragCapture\" | \"onDragEnd\" | \"onDragEndCapture\" | \"onDragEnter\" | \"onDragEnterCapture\" | \"onDragExit\" | \"onDragExitCapture\" | \"onDragLeave\" | \"onDragLeaveCapture\" | \"onDragOver\" | \"onDragOverCapture\" | \"onDragStart\" | \"onDragStartCapture\" | \"onDrop\" | \"onDropCapture\" | \"onMouseDown\" | \"onMouseDownCapture\" | \"onMouseEnter\" | \"onMouseLeave\" | \"onMouseMove\" | \"onMouseMoveCapture\" | \"onMouseOut\" | \"onMouseOutCapture\" | \"onMouseOver\" | \"onMouseOverCapture\" | \"onMouseUp\" | \"onMouseUpCapture\" | \"onSelect\" | \"onSelectCapture\" | \"onTouchCancel\" | \"onTouchCancelCapture\" | \"onTouchEnd\" | \"onTouchEndCapture\" | \"onTouchMove\" | \"onTouchMoveCapture\" | \"onTouchStart\" | \"onTouchStartCapture\" | \"onPointerDown\" | \"onPointerDownCapture\" | \"onPointerMove\" | \"onPointerMoveCapture\" | \"onPointerUp\" | \"onPointerUpCapture\" | \"onPointerCancel\" | \"onPointerCancelCapture\" | \"onPointerEnter\" | \"onPointerEnterCapture\" | \"onPointerLeave\" | \"onPointerLeaveCapture\" | \"onPointerOver\" | \"onPointerOverCapture\" | \"onPointerOut\" | \"onPointerOutCapture\" | \"onGotPointerCapture\" | \"onGotPointerCaptureCapture\" | \"onLostPointerCapture\" | \"onLostPointerCaptureCapture\" | \"onScroll\" | \"onScrollCapture\" | \"onWheel\" | \"onWheelCapture\" | \"onAnimationStart\" | \"onAnimationStartCapture\" | \"onAnimationEnd\" | \"onAnimationEndCapture\" | \"onAnimationIteration\" | \"onAnimationIterationCapture\" | \"onTransitionEnd\" | \"onTransitionEndCapture\" | keyof ", + " & { as?: \"div\" | undefined; } & _EuiFlyoutProps & Omit, HTMLDivElement>, keyof _EuiFlyoutProps> & Omit, HTMLDivElement>, \"key\" | keyof React.HTMLAttributes | \"css\"> & { ref?: React.RefObject | ((instance: HTMLDivElement | null) => void) | null | undefined; }, \"children\" | \"onError\" | \"hidden\" | \"color\" | \"title\" | \"onChange\" | \"onKeyDown\" | \"onClick\" | \"id\" | \"security\" | \"defaultValue\" | \"lang\" | \"defaultChecked\" | \"suppressContentEditableWarning\" | \"suppressHydrationWarning\" | \"accessKey\" | \"contentEditable\" | \"contextMenu\" | \"dir\" | \"draggable\" | \"placeholder\" | \"slot\" | \"spellCheck\" | \"tabIndex\" | \"translate\" | \"radioGroup\" | \"about\" | \"datatype\" | \"inlist\" | \"prefix\" | \"property\" | \"resource\" | \"typeof\" | \"vocab\" | \"autoCapitalize\" | \"autoCorrect\" | \"autoSave\" | \"itemProp\" | \"itemScope\" | \"itemType\" | \"itemID\" | \"itemRef\" | \"results\" | \"unselectable\" | \"inputMode\" | \"is\" | \"aria-activedescendant\" | \"aria-atomic\" | \"aria-autocomplete\" | \"aria-busy\" | \"aria-checked\" | \"aria-colcount\" | \"aria-colindex\" | \"aria-colspan\" | \"aria-controls\" | \"aria-current\" | \"aria-describedby\" | \"aria-details\" | \"aria-disabled\" | \"aria-dropeffect\" | \"aria-errormessage\" | \"aria-expanded\" | \"aria-flowto\" | \"aria-grabbed\" | \"aria-haspopup\" | \"aria-hidden\" | \"aria-invalid\" | \"aria-keyshortcuts\" | \"aria-labelledby\" | \"aria-level\" | \"aria-live\" | \"aria-modal\" | \"aria-multiline\" | \"aria-multiselectable\" | \"aria-orientation\" | \"aria-owns\" | \"aria-placeholder\" | \"aria-posinset\" | \"aria-pressed\" | \"aria-readonly\" | \"aria-relevant\" | \"aria-required\" | \"aria-roledescription\" | \"aria-rowcount\" | \"aria-rowindex\" | \"aria-rowspan\" | \"aria-selected\" | \"aria-setsize\" | \"aria-sort\" | \"aria-valuemax\" | \"aria-valuemin\" | \"aria-valuenow\" | \"aria-valuetext\" | \"dangerouslySetInnerHTML\" | \"onCopy\" | \"onCopyCapture\" | \"onCut\" | \"onCutCapture\" | \"onPaste\" | \"onPasteCapture\" | \"onCompositionEnd\" | \"onCompositionEndCapture\" | \"onCompositionStart\" | \"onCompositionStartCapture\" | \"onCompositionUpdate\" | \"onCompositionUpdateCapture\" | \"onFocus\" | \"onFocusCapture\" | \"onBlur\" | \"onBlurCapture\" | \"onChangeCapture\" | \"onBeforeInput\" | \"onBeforeInputCapture\" | \"onInput\" | \"onInputCapture\" | \"onReset\" | \"onResetCapture\" | \"onSubmit\" | \"onSubmitCapture\" | \"onInvalid\" | \"onInvalidCapture\" | \"onLoad\" | \"onLoadCapture\" | \"onErrorCapture\" | \"onKeyDownCapture\" | \"onKeyPress\" | \"onKeyPressCapture\" | \"onKeyUp\" | \"onKeyUpCapture\" | \"onAbort\" | \"onAbortCapture\" | \"onCanPlay\" | \"onCanPlayCapture\" | \"onCanPlayThrough\" | \"onCanPlayThroughCapture\" | \"onDurationChange\" | \"onDurationChangeCapture\" | \"onEmptied\" | \"onEmptiedCapture\" | \"onEncrypted\" | \"onEncryptedCapture\" | \"onEnded\" | \"onEndedCapture\" | \"onLoadedData\" | \"onLoadedDataCapture\" | \"onLoadedMetadata\" | \"onLoadedMetadataCapture\" | \"onLoadStart\" | \"onLoadStartCapture\" | \"onPause\" | \"onPauseCapture\" | \"onPlay\" | \"onPlayCapture\" | \"onPlaying\" | \"onPlayingCapture\" | \"onProgress\" | \"onProgressCapture\" | \"onRateChange\" | \"onRateChangeCapture\" | \"onSeeked\" | \"onSeekedCapture\" | \"onSeeking\" | \"onSeekingCapture\" | \"onStalled\" | \"onStalledCapture\" | \"onSuspend\" | \"onSuspendCapture\" | \"onTimeUpdate\" | \"onTimeUpdateCapture\" | \"onVolumeChange\" | \"onVolumeChangeCapture\" | \"onWaiting\" | \"onWaitingCapture\" | \"onAuxClick\" | \"onAuxClickCapture\" | \"onClickCapture\" | \"onContextMenu\" | \"onContextMenuCapture\" | \"onDoubleClick\" | \"onDoubleClickCapture\" | \"onDrag\" | \"onDragCapture\" | \"onDragEnd\" | \"onDragEndCapture\" | \"onDragEnter\" | \"onDragEnterCapture\" | \"onDragExit\" | \"onDragExitCapture\" | \"onDragLeave\" | \"onDragLeaveCapture\" | \"onDragOver\" | \"onDragOverCapture\" | \"onDragStart\" | \"onDragStartCapture\" | \"onDrop\" | \"onDropCapture\" | \"onMouseDown\" | \"onMouseDownCapture\" | \"onMouseEnter\" | \"onMouseLeave\" | \"onMouseMove\" | \"onMouseMoveCapture\" | \"onMouseOut\" | \"onMouseOutCapture\" | \"onMouseOver\" | \"onMouseOverCapture\" | \"onMouseUp\" | \"onMouseUpCapture\" | \"onSelect\" | \"onSelectCapture\" | \"onTouchCancel\" | \"onTouchCancelCapture\" | \"onTouchEnd\" | \"onTouchEndCapture\" | \"onTouchMove\" | \"onTouchMoveCapture\" | \"onTouchStart\" | \"onTouchStartCapture\" | \"onPointerDown\" | \"onPointerDownCapture\" | \"onPointerMove\" | \"onPointerMoveCapture\" | \"onPointerUp\" | \"onPointerUpCapture\" | \"onPointerCancel\" | \"onPointerCancelCapture\" | \"onPointerEnter\" | \"onPointerEnterCapture\" | \"onPointerLeave\" | \"onPointerLeaveCapture\" | \"onPointerOver\" | \"onPointerOverCapture\" | \"onPointerOut\" | \"onPointerOutCapture\" | \"onGotPointerCapture\" | \"onGotPointerCaptureCapture\" | \"onLostPointerCapture\" | \"onLostPointerCaptureCapture\" | \"onScroll\" | \"onScrollCapture\" | \"onWheel\" | \"onWheelCapture\" | \"onAnimationStart\" | \"onAnimationStartCapture\" | \"onAnimationEnd\" | \"onAnimationEndCapture\" | \"onAnimationIteration\" | \"onAnimationIterationCapture\" | \"onTransitionEnd\" | \"onTransitionEndCapture\" | \"as\" | keyof ", "CommonProps", - " | \"title\" | \"hidden\" | \"security\" | \"defaultValue\" | \"defaultChecked\" | \"suppressContentEditableWarning\" | \"suppressHydrationWarning\" | \"accessKey\" | \"contentEditable\" | \"contextMenu\" | \"dir\" | \"draggable\" | \"placeholder\" | \"slot\" | \"spellCheck\" | \"translate\" | \"radioGroup\" | \"about\" | \"datatype\" | \"inlist\" | \"prefix\" | \"property\" | \"resource\" | \"typeof\" | \"vocab\" | \"autoCapitalize\" | \"autoCorrect\" | \"autoSave\" | \"itemProp\" | \"itemScope\" | \"itemType\" | \"itemID\" | \"itemRef\" | \"results\" | \"unselectable\" | \"inputMode\" | \"is\" | \"as\" | keyof React.ClassAttributes | keyof _EuiFlyoutProps>, \"children\" | \"onError\" | \"color\" | \"id\" | \"lang\" | \"tabIndex\" | \"aria-activedescendant\" | \"aria-atomic\" | \"aria-autocomplete\" | \"aria-busy\" | \"aria-checked\" | \"aria-colcount\" | \"aria-colindex\" | \"aria-colspan\" | \"aria-controls\" | \"aria-current\" | \"aria-describedby\" | \"aria-details\" | \"aria-disabled\" | \"aria-dropeffect\" | \"aria-errormessage\" | \"aria-expanded\" | \"aria-flowto\" | \"aria-grabbed\" | \"aria-haspopup\" | \"aria-hidden\" | \"aria-invalid\" | \"aria-keyshortcuts\" | \"aria-labelledby\" | \"aria-level\" | \"aria-live\" | \"aria-modal\" | \"aria-multiline\" | \"aria-multiselectable\" | \"aria-orientation\" | \"aria-owns\" | \"aria-placeholder\" | \"aria-posinset\" | \"aria-pressed\" | \"aria-readonly\" | \"aria-relevant\" | \"aria-required\" | \"aria-roledescription\" | \"aria-rowcount\" | \"aria-rowindex\" | \"aria-rowspan\" | \"aria-selected\" | \"aria-setsize\" | \"aria-sort\" | \"aria-valuemax\" | \"aria-valuemin\" | \"aria-valuenow\" | \"aria-valuetext\" | \"dangerouslySetInnerHTML\" | \"onCopy\" | \"onCopyCapture\" | \"onCut\" | \"onCutCapture\" | \"onPaste\" | \"onPasteCapture\" | \"onCompositionEnd\" | \"onCompositionEndCapture\" | \"onCompositionStart\" | \"onCompositionStartCapture\" | \"onCompositionUpdate\" | \"onCompositionUpdateCapture\" | \"onFocus\" | \"onFocusCapture\" | \"onBlur\" | \"onBlurCapture\" | \"onChange\" | \"onChangeCapture\" | \"onBeforeInput\" | \"onBeforeInputCapture\" | \"onInput\" | \"onInputCapture\" | \"onReset\" | \"onResetCapture\" | \"onSubmit\" | \"onSubmitCapture\" | \"onInvalid\" | \"onInvalidCapture\" | \"onLoad\" | \"onLoadCapture\" | \"onErrorCapture\" | \"onKeyDown\" | \"onKeyDownCapture\" | \"onKeyPress\" | \"onKeyPressCapture\" | \"onKeyUp\" | \"onKeyUpCapture\" | \"onAbort\" | \"onAbortCapture\" | \"onCanPlay\" | \"onCanPlayCapture\" | \"onCanPlayThrough\" | \"onCanPlayThroughCapture\" | \"onDurationChange\" | \"onDurationChangeCapture\" | \"onEmptied\" | \"onEmptiedCapture\" | \"onEncrypted\" | \"onEncryptedCapture\" | \"onEnded\" | \"onEndedCapture\" | \"onLoadedData\" | \"onLoadedDataCapture\" | \"onLoadedMetadata\" | \"onLoadedMetadataCapture\" | \"onLoadStart\" | \"onLoadStartCapture\" | \"onPause\" | \"onPauseCapture\" | \"onPlay\" | \"onPlayCapture\" | \"onPlaying\" | \"onPlayingCapture\" | \"onProgress\" | \"onProgressCapture\" | \"onRateChange\" | \"onRateChangeCapture\" | \"onSeeked\" | \"onSeekedCapture\" | \"onSeeking\" | \"onSeekingCapture\" | \"onStalled\" | \"onStalledCapture\" | \"onSuspend\" | \"onSuspendCapture\" | \"onTimeUpdate\" | \"onTimeUpdateCapture\" | \"onVolumeChange\" | \"onVolumeChangeCapture\" | \"onWaiting\" | \"onWaitingCapture\" | \"onAuxClick\" | \"onAuxClickCapture\" | \"onClick\" | \"onClickCapture\" | \"onContextMenu\" | \"onContextMenuCapture\" | \"onDoubleClick\" | \"onDoubleClickCapture\" | \"onDrag\" | \"onDragCapture\" | \"onDragEnd\" | \"onDragEndCapture\" | \"onDragEnter\" | \"onDragEnterCapture\" | \"onDragExit\" | \"onDragExitCapture\" | \"onDragLeave\" | \"onDragLeaveCapture\" | \"onDragOver\" | \"onDragOverCapture\" | \"onDragStart\" | \"onDragStartCapture\" | \"onDrop\" | \"onDropCapture\" | \"onMouseDown\" | \"onMouseDownCapture\" | \"onMouseEnter\" | \"onMouseLeave\" | \"onMouseMove\" | \"onMouseMoveCapture\" | \"onMouseOut\" | \"onMouseOutCapture\" | \"onMouseOver\" | \"onMouseOverCapture\" | \"onMouseUp\" | \"onMouseUpCapture\" | \"onSelect\" | \"onSelectCapture\" | \"onTouchCancel\" | \"onTouchCancelCapture\" | \"onTouchEnd\" | \"onTouchEndCapture\" | \"onTouchMove\" | \"onTouchMoveCapture\" | \"onTouchStart\" | \"onTouchStartCapture\" | \"onPointerDown\" | \"onPointerDownCapture\" | \"onPointerMove\" | \"onPointerMoveCapture\" | \"onPointerUp\" | \"onPointerUpCapture\" | \"onPointerCancel\" | \"onPointerCancelCapture\" | \"onPointerEnter\" | \"onPointerEnterCapture\" | \"onPointerLeave\" | \"onPointerLeaveCapture\" | \"onPointerOver\" | \"onPointerOverCapture\" | \"onPointerOut\" | \"onPointerOutCapture\" | \"onGotPointerCapture\" | \"onGotPointerCaptureCapture\" | \"onLostPointerCapture\" | \"onLostPointerCaptureCapture\" | \"onScroll\" | \"onScrollCapture\" | \"onWheel\" | \"onWheelCapture\" | \"onAnimationStart\" | \"onAnimationStartCapture\" | \"onAnimationEnd\" | \"onAnimationEndCapture\" | \"onAnimationIteration\" | \"onAnimationIterationCapture\" | \"onTransitionEnd\" | \"onTransitionEndCapture\" | keyof ", + " | keyof React.ClassAttributes | keyof _EuiFlyoutProps>, \"children\" | \"onError\" | \"hidden\" | \"color\" | \"alert\" | \"title\" | \"onChange\" | \"onKeyDown\" | \"onClick\" | \"id\" | \"security\" | \"key\" | \"defaultValue\" | \"lang\" | \"defaultChecked\" | \"suppressContentEditableWarning\" | \"suppressHydrationWarning\" | \"accessKey\" | \"contentEditable\" | \"contextMenu\" | \"dir\" | \"draggable\" | \"placeholder\" | \"slot\" | \"spellCheck\" | \"tabIndex\" | \"translate\" | \"radioGroup\" | \"about\" | \"datatype\" | \"inlist\" | \"prefix\" | \"property\" | \"resource\" | \"typeof\" | \"vocab\" | \"autoCapitalize\" | \"autoCorrect\" | \"autoSave\" | \"itemProp\" | \"itemScope\" | \"itemType\" | \"itemID\" | \"itemRef\" | \"results\" | \"unselectable\" | \"inputMode\" | \"is\" | \"aria-activedescendant\" | \"aria-atomic\" | \"aria-autocomplete\" | \"aria-busy\" | \"aria-checked\" | \"aria-colcount\" | \"aria-colindex\" | \"aria-colspan\" | \"aria-controls\" | \"aria-current\" | \"aria-describedby\" | \"aria-details\" | \"aria-disabled\" | \"aria-dropeffect\" | \"aria-errormessage\" | \"aria-expanded\" | \"aria-flowto\" | \"aria-grabbed\" | \"aria-haspopup\" | \"aria-hidden\" | \"aria-invalid\" | \"aria-keyshortcuts\" | \"aria-labelledby\" | \"aria-level\" | \"aria-live\" | \"aria-modal\" | \"aria-multiline\" | \"aria-multiselectable\" | \"aria-orientation\" | \"aria-owns\" | \"aria-placeholder\" | \"aria-posinset\" | \"aria-pressed\" | \"aria-readonly\" | \"aria-relevant\" | \"aria-required\" | \"aria-roledescription\" | \"aria-rowcount\" | \"aria-rowindex\" | \"aria-rowspan\" | \"aria-selected\" | \"aria-setsize\" | \"aria-sort\" | \"aria-valuemax\" | \"aria-valuemin\" | \"aria-valuenow\" | \"aria-valuetext\" | \"dangerouslySetInnerHTML\" | \"onCopy\" | \"onCopyCapture\" | \"onCut\" | \"onCutCapture\" | \"onPaste\" | \"onPasteCapture\" | \"onCompositionEnd\" | \"onCompositionEndCapture\" | \"onCompositionStart\" | \"onCompositionStartCapture\" | \"onCompositionUpdate\" | \"onCompositionUpdateCapture\" | \"onFocus\" | \"onFocusCapture\" | \"onBlur\" | \"onBlurCapture\" | \"onChangeCapture\" | \"onBeforeInput\" | \"onBeforeInputCapture\" | \"onInput\" | \"onInputCapture\" | \"onReset\" | \"onResetCapture\" | \"onSubmit\" | \"onSubmitCapture\" | \"onInvalid\" | \"onInvalidCapture\" | \"onLoad\" | \"onLoadCapture\" | \"onErrorCapture\" | \"onKeyDownCapture\" | \"onKeyPress\" | \"onKeyPressCapture\" | \"onKeyUp\" | \"onKeyUpCapture\" | \"onAbort\" | \"onAbortCapture\" | \"onCanPlay\" | \"onCanPlayCapture\" | \"onCanPlayThrough\" | \"onCanPlayThroughCapture\" | \"onDurationChange\" | \"onDurationChangeCapture\" | \"onEmptied\" | \"onEmptiedCapture\" | \"onEncrypted\" | \"onEncryptedCapture\" | \"onEnded\" | \"onEndedCapture\" | \"onLoadedData\" | \"onLoadedDataCapture\" | \"onLoadedMetadata\" | \"onLoadedMetadataCapture\" | \"onLoadStart\" | \"onLoadStartCapture\" | \"onPause\" | \"onPauseCapture\" | \"onPlay\" | \"onPlayCapture\" | \"onPlaying\" | \"onPlayingCapture\" | \"onProgress\" | \"onProgressCapture\" | \"onRateChange\" | \"onRateChangeCapture\" | \"onSeeked\" | \"onSeekedCapture\" | \"onSeeking\" | \"onSeekingCapture\" | \"onStalled\" | \"onStalledCapture\" | \"onSuspend\" | \"onSuspendCapture\" | \"onTimeUpdate\" | \"onTimeUpdateCapture\" | \"onVolumeChange\" | \"onVolumeChangeCapture\" | \"onWaiting\" | \"onWaitingCapture\" | \"onAuxClick\" | \"onAuxClickCapture\" | \"onClickCapture\" | \"onContextMenu\" | \"onContextMenuCapture\" | \"onDoubleClick\" | \"onDoubleClickCapture\" | \"onDrag\" | \"onDragCapture\" | \"onDragEnd\" | \"onDragEndCapture\" | \"onDragEnter\" | \"onDragEnterCapture\" | \"onDragExit\" | \"onDragExitCapture\" | \"onDragLeave\" | \"onDragLeaveCapture\" | \"onDragOver\" | \"onDragOverCapture\" | \"onDragStart\" | \"onDragStartCapture\" | \"onDrop\" | \"onDropCapture\" | \"onMouseDown\" | \"onMouseDownCapture\" | \"onMouseEnter\" | \"onMouseLeave\" | \"onMouseMove\" | \"onMouseMoveCapture\" | \"onMouseOut\" | \"onMouseOutCapture\" | \"onMouseOver\" | \"onMouseOverCapture\" | \"onMouseUp\" | \"onMouseUpCapture\" | \"onSelect\" | \"onSelectCapture\" | \"onTouchCancel\" | \"onTouchCancelCapture\" | \"onTouchEnd\" | \"onTouchEndCapture\" | \"onTouchMove\" | \"onTouchMoveCapture\" | \"onTouchStart\" | \"onTouchStartCapture\" | \"onPointerDown\" | \"onPointerDownCapture\" | \"onPointerMove\" | \"onPointerMoveCapture\" | \"onPointerUp\" | \"onPointerUpCapture\" | \"onPointerCancel\" | \"onPointerCancelCapture\" | \"onPointerEnter\" | \"onPointerEnterCapture\" | \"onPointerLeave\" | \"onPointerLeaveCapture\" | \"onPointerOver\" | \"onPointerOverCapture\" | \"onPointerOut\" | \"onPointerOutCapture\" | \"onGotPointerCapture\" | \"onGotPointerCaptureCapture\" | \"onLostPointerCapture\" | \"onLostPointerCaptureCapture\" | \"onScroll\" | \"onScrollCapture\" | \"onWheel\" | \"onWheelCapture\" | \"onAnimationStart\" | \"onAnimationStartCapture\" | \"onAnimationEnd\" | \"onAnimationEndCapture\" | \"onAnimationIteration\" | \"onAnimationIterationCapture\" | \"onTransitionEnd\" | \"onTransitionEndCapture\" | \"as\" | \"css\" | keyof ", "CommonProps", - " | \"title\" | \"alert\" | \"hidden\" | \"key\" | \"css\" | \"security\" | \"defaultValue\" | \"defaultChecked\" | \"suppressContentEditableWarning\" | \"suppressHydrationWarning\" | \"accessKey\" | \"contentEditable\" | \"contextMenu\" | \"dir\" | \"draggable\" | \"placeholder\" | \"slot\" | \"spellCheck\" | \"translate\" | \"radioGroup\" | \"about\" | \"datatype\" | \"inlist\" | \"prefix\" | \"property\" | \"resource\" | \"typeof\" | \"vocab\" | \"autoCapitalize\" | \"autoCorrect\" | \"autoSave\" | \"itemProp\" | \"itemScope\" | \"itemType\" | \"itemID\" | \"itemRef\" | \"results\" | \"unselectable\" | \"inputMode\" | \"is\" | \"as\" | \"alerts\" | keyof _EuiFlyoutProps | \"isInApp\" | \"observabilityRuleTypeRegistry\" | \"selectedAlertId\"> & { ref?: React.RefObject | ((instance: HTMLDivElement | null) => void) | null | undefined; }> & { readonly _result: ({ alert, alerts, isInApp, observabilityRuleTypeRegistry, onClose, selectedAlertId, }: AlertsFlyoutProps) => JSX.Element | null; }" + " | \"alerts\" | keyof _EuiFlyoutProps | \"isInApp\" | \"observabilityRuleTypeRegistry\" | \"selectedAlertId\"> & { ref?: React.RefObject | ((instance: HTMLDivElement | null) => void) | null | undefined; }> & { readonly _result: ({ alert, alerts, isInApp, observabilityRuleTypeRegistry, onClose, selectedAlertId, }: AlertsFlyoutProps) => JSX.Element | null; }" ], "path": "x-pack/plugins/observability/public/index.ts", "deprecated": false, @@ -3375,25 +3375,6 @@ "path": "x-pack/plugins/observability/public/plugin.ts", "deprecated": false }, - { - "parentPluginId": "observability", - "id": "def-public.ObservabilityPublicPluginsStart.sharedUX", - "type": "Object", - "tags": [], - "label": "sharedUX", - "description": [], - "signature": [ - { - "pluginId": "sharedUX", - "scope": "public", - "docId": "kibSharedUXPluginApi", - "section": "def-public.SharedUXPluginStart", - "text": "SharedUXPluginStart" - } - ], - "path": "x-pack/plugins/observability/public/plugin.ts", - "deprecated": false - }, { "parentPluginId": "observability", "id": "def-public.ObservabilityPublicPluginsStart.ruleTypeRegistry", @@ -4733,20 +4714,6 @@ "deprecated": false, "initialIsOpen": false }, - { - "parentPluginId": "observability", - "id": "def-public.enableInfrastructureView", - "type": "string", - "tags": [], - "label": "enableInfrastructureView", - "description": [], - "signature": [ - "\"observability:enableInfrastructureView\"" - ], - "path": "x-pack/plugins/observability/common/ui_settings_keys.ts", - "deprecated": false, - "initialIsOpen": false - }, { "parentPluginId": "observability", "id": "def-public.enableInspectEsQueries", @@ -5107,11 +5074,11 @@ "DisambiguateSet", ", Omit, \"href\">> & Omit, \"href\">) | (", "DisambiguateSet", - ", \"href\">, React.ButtonHTMLAttributes> & React.ButtonHTMLAttributes))), \"color\" | \"target\" | \"onClick\" | \"rel\"> & { size?: ItemSize | undefined; color?: Color | undefined; label: React.ReactNode; isActive?: boolean | undefined; isDisabled?: boolean | undefined; href?: string | undefined; target?: string | undefined; rel?: string | undefined; iconType?: ", + ", \"href\">, React.ButtonHTMLAttributes> & React.ButtonHTMLAttributes))), \"color\" | \"onClick\" | \"rel\" | \"target\"> & { size?: ItemSize | undefined; color?: Color | undefined; label: React.ReactNode; isActive?: boolean | undefined; isDisabled?: boolean | undefined; href?: string | undefined; target?: string | undefined; rel?: string | undefined; iconType?: ", "IconType", " | undefined; iconProps?: Omit<", "EuiIconProps", - ", \"type\"> | undefined; icon?: React.ReactElement> | undefined; showToolTip?: boolean | undefined; extraAction?: ({ type?: \"button\" | \"reset\" | \"submit\" | undefined; } & ", + ", \"type\"> | undefined; icon?: React.ReactElement> | undefined; showToolTip?: boolean | undefined; extraAction?: ({ type?: \"reset\" | \"button\" | \"submit\" | undefined; } & ", "EuiButtonIconProps", " & { onClick?: React.MouseEventHandler | undefined; } & React.ButtonHTMLAttributes & { buttonRef?: React.Ref | undefined; } & { alwaysShow?: boolean | undefined; }) | undefined; onClick?: React.MouseEventHandler | undefined; wrapText?: boolean | undefined; buttonRef?: React.Ref | undefined; }" ], @@ -5547,7 +5514,9 @@ "TransportRequestOptions", " | undefined): Promise<", "WriteResponseBase", - ">; }; name: string | symbol; transform: ", + ">; }; cluster: ", + "default", + "; eql: ", "default", "; search: { >; }; cluster: ", - "default", - "; eql: ", - "default", - "; create: { (this: That, params: ", + ">; }; create: { (this: That, params: ", "CreateRequest", " | ", "CreateRequest", @@ -5615,7 +5580,7 @@ "default", "; security: ", "default", - "; index: { (this: That, params: ", + "; name: string | symbol; index: { (this: That, params: ", "IndexRequest", " | ", "IndexRequest", @@ -6627,6 +6592,8 @@ "TermvectorsResponse", ">; }; textStructure: ", "default", + "; transform: ", + "default", "; updateByQuery: { (this: That, params: ", "UpdateByQueryRequest", " | ", @@ -7799,20 +7766,6 @@ "deprecated": false, "initialIsOpen": false }, - { - "parentPluginId": "observability", - "id": "def-common.enableInfrastructureView", - "type": "string", - "tags": [], - "label": "enableInfrastructureView", - "description": [], - "signature": [ - "\"observability:enableInfrastructureView\"" - ], - "path": "x-pack/plugins/observability/common/ui_settings_keys.ts", - "deprecated": false, - "initialIsOpen": false - }, { "parentPluginId": "observability", "id": "def-common.enableInspectEsQueries", @@ -7905,7 +7858,7 @@ "label": "TimeUnitChar", "description": [], "signature": [ - "\"d\" | \"s\" | \"m\" | \"h\"" + "\"d\" | \"h\" | \"m\" | \"s\"" ], "path": "x-pack/plugins/observability/common/utils/formatters/duration.ts", "deprecated": false, diff --git a/api_docs/observability.mdx b/api_docs/observability.mdx index 7e8bb1e2775ddb..3dc4b425bf7adb 100644 --- a/api_docs/observability.mdx +++ b/api_docs/observability.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observability title: "observability" image: https://source.unsplash.com/400x175/?github description: API docs for the observability plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observability'] --- import observabilityObj from './observability.devdocs.json'; @@ -21,7 +21,7 @@ Contact [Observability UI](https://github.com/orgs/elastic/teams/observability-u | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 399 | 2 | 396 | 30 | +| 396 | 2 | 393 | 30 | ## Client diff --git a/api_docs/osquery.mdx b/api_docs/osquery.mdx index 9619e0cc930088..ba8c285f8fd1d1 100644 --- a/api_docs/osquery.mdx +++ b/api_docs/osquery.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/osquery title: "osquery" image: https://source.unsplash.com/400x175/?github description: API docs for the osquery plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'osquery'] --- import osqueryObj from './osquery.devdocs.json'; diff --git a/api_docs/plugin_directory.mdx b/api_docs/plugin_directory.mdx index 27cea92b0973bb..340a6e84b46ed6 100644 --- a/api_docs/plugin_directory.mdx +++ b/api_docs/plugin_directory.mdx @@ -7,7 +7,7 @@ id: kibDevDocsPluginDirectory slug: /kibana-dev-docs/api-meta/plugin-api-directory title: Directory description: Directory of public APIs available through plugins or packages. -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- @@ -15,13 +15,13 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | Count | Plugins or Packages with a
public API | Number of teams | |--------------|----------|------------------------| -| 403 | 337 | 37 | +| 414 | 343 | 36 | ### Public API health stats | API Count | Any Count | Missing comments | Missing exports | |--------------|----------|-----------------|--------| -| 29233 | 175 | 19674 | 911 | +| 29506 | 180 | 19896 | 920 | ## Plugin Directory @@ -36,35 +36,35 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Considering using bfetch capabilities when fetching large amounts of data. This services supports batching HTTP requests and streaming responses back. | 80 | 1 | 71 | 2 | | | [Kibana Presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Adds Canvas application to Kibana | 9 | 0 | 8 | 3 | | | [ResponseOps](https://github.com/orgs/elastic/teams/response-ops) | The Case management system in Kibana | 82 | 0 | 66 | 29 | -| | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | - | 272 | 2 | 253 | 9 | +| | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | - | 261 | 2 | 246 | 9 | | | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 29 | 0 | 24 | 0 | | | [Cloud Security Posture](https://github.com/orgs/elastic/teams/cloud-posture-security) | The cloud security posture plugin | 18 | 0 | 2 | 3 | | | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 13 | 0 | 13 | 1 | -| | [Kibana Presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | The Controls Plugin contains embeddable components intended to create a simple query interface for end users, and a powerful editing suite that allows dashboard authors to build controls | 207 | 0 | 199 | 7 | -| | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 2524 | 2 | 296 | 6 | +| | [Kibana Presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | The Controls Plugin contains embeddable components intended to create a simple query interface for end users, and a powerful editing suite that allows dashboard authors to build controls | 204 | 0 | 196 | 7 | +| | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 2524 | 1 | 216 | 5 | | crossClusterReplication | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 0 | 0 | 0 | 0 | | | [Fleet](https://github.com/orgs/elastic/teams/fleet) | Add custom data integrations so they can be displayed in the Fleet integrations app | 102 | 0 | 83 | 1 | | | [Kibana Presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Adds the Dashboard app to Kibana | 146 | 0 | 141 | 12 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | - | 52 | 0 | 51 | 0 | -| | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Data services are useful for searching and querying data from Elasticsearch. Helpful utilities include: a re-usable react query bar, KQL autocomplete, async search, Data Views (Index Patterns) and field formatters. | 3114 | 34 | 2428 | 22 | +| | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Data services are useful for searching and querying data from Elasticsearch. Helpful utilities include: a re-usable react query bar, KQL autocomplete, async search, Data Views (Index Patterns) and field formatters. | 3117 | 34 | 2431 | 22 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | This plugin provides the ability to create data views via a modal flyout inside Kibana apps | 15 | 0 | 7 | 0 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Reusable data view field editor across Kibana | 49 | 0 | 29 | 3 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Data view management app | 2 | 0 | 2 | 0 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Data services are useful for searching and querying data from Elasticsearch. Helpful utilities include: a re-usable react query bar, KQL autocomplete, async search, Data Views (Index Patterns) and field formatters. | 960 | 0 | 203 | 0 | | | [Machine Learning UI](https://github.com/orgs/elastic/teams/ml-ui) | The Data Visualizer tools help you understand your data, by analyzing the metrics and fields in a log file or an existing Elasticsearch index. | 28 | 3 | 24 | 1 | | | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 10 | 0 | 8 | 2 | -| | [Data Discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | This plugin contains the Discover application and the saved search embeddable. | 90 | 0 | 73 | 5 | +| | [Data Discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | This plugin contains the Discover application and the saved search embeddable. | 93 | 0 | 76 | 4 | | | [Data Discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | - | 37 | 0 | 35 | 2 | -| | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Adds embeddables service to Kibana | 512 | 0 | 413 | 4 | +| | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Adds embeddables service to Kibana | 514 | 0 | 414 | 4 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Extends embeddable plugin with more functionality | 14 | 0 | 14 | 0 | | | [Platform Security](https://github.com/orgs/elastic/teams/kibana-security) | This plugin provides encryption and decryption utilities for saved objects containing sensitive information. | 51 | 0 | 42 | 0 | -| | [Enterprise Search](https://github.com/orgs/elastic/teams/enterprise-search-frontend) | Adds dashboards for discovering and managing Enterprise Search products. | 6 | 0 | 6 | 0 | +| | [Enterprise Search](https://github.com/orgs/elastic/teams/enterprise-search-frontend) | Adds dashboards for discovering and managing Enterprise Search products. | 8 | 0 | 8 | 0 | | | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 114 | 3 | 110 | 3 | | | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | The Event Annotation service contains expressions for event annotations | 95 | 0 | 95 | 6 | | | [Response Ops](https://github.com/orgs/elastic/teams/response-ops) | - | 100 | 0 | 100 | 9 | | | [Kibana Presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Adds 'error' renderer to expressions | 17 | 0 | 15 | 2 | -| | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Expression Gauge plugin adds a `gauge` renderer and function to the expression plugin. The renderer will display the `gauge` chart. | 61 | 0 | 61 | 2 | -| | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Expression Heatmap plugin adds a `heatmap` renderer and function to the expression plugin. The renderer will display the `heatmap` chart. | 107 | 0 | 103 | 3 | +| | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Expression Gauge plugin adds a `gauge` renderer and function to the expression plugin. The renderer will display the `gauge` chart. | 57 | 0 | 57 | 2 | +| | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Expression Heatmap plugin adds a `heatmap` renderer and function to the expression plugin. The renderer will display the `heatmap` chart. | 105 | 0 | 101 | 3 | | | [Kibana Presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Adds 'image' function and renderer to expressions | 26 | 0 | 26 | 0 | | | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Adds a `metric` renderer and function to the expression plugin. The renderer will display the `legacy metric` chart. | 48 | 0 | 48 | 1 | | | [Kibana Presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Adds 'metric' function and renderer to expressions | 32 | 0 | 27 | 0 | @@ -74,13 +74,13 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [Kibana Presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Adds 'revealImage' function and renderer to expressions | 14 | 0 | 14 | 3 | | | [Kibana Presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Adds 'shape' function and renderer to expressions | 148 | 0 | 146 | 0 | | | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Expression Tagcloud plugin adds a `tagcloud` renderer and function to the expression plugin. The renderer will display the `Wordcloud` chart. | 7 | 0 | 7 | 0 | -| | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Expression XY plugin adds a `xy` renderer and function to the expression plugin. The renderer will display the `xy` chart. | 151 | 0 | 141 | 12 | +| | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Expression XY plugin adds a `xy` renderer and function to the expression plugin. The renderer will display the `xy` chart. | 152 | 0 | 142 | 11 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Adds expression runtime to Kibana | 2183 | 17 | 1729 | 5 | | | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 222 | 0 | 95 | 2 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Index pattern fields and ambiguous values formatters | 288 | 5 | 249 | 3 | | | [Machine Learning UI](https://github.com/orgs/elastic/teams/ml-ui) | The file upload plugin contains components and services for uploading a file, analyzing its data, and then importing the data into an Elasticsearch index. Supported file types include CSV, TSV, newline-delimited JSON and GeoJSON. | 62 | 0 | 62 | 2 | -| | [@elastic/kibana-app-services](https://github.com/orgs/elastic/teams/team:AppServicesUx) | File upload, download, sharing, and serving over HTTP implementation in Kibana. | 236 | 0 | 3 | 2 | -| | [Fleet](https://github.com/orgs/elastic/teams/fleet) | - | 957 | 3 | 862 | 9 | +| | [@elastic/kibana-app-services](https://github.com/orgs/elastic/teams/team:AppServicesUx) | File upload, download, sharing, and serving over HTTP implementation in Kibana. | 243 | 0 | 6 | 2 | +| | [Fleet](https://github.com/orgs/elastic/teams/fleet) | - | 967 | 3 | 872 | 10 | | | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 68 | 0 | 14 | 5 | | globalSearchBar | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 0 | 0 | 0 | 0 | | globalSearchProviders | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 0 | 0 | 0 | 0 | @@ -99,7 +99,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | kibanaUsageCollection | [Kibana Telemetry](https://github.com/orgs/elastic/teams/kibana-telemetry) | - | 0 | 0 | 0 | 0 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | - | 615 | 3 | 420 | 9 | | | [Security Team](https://github.com/orgs/elastic/teams/security-team) | - | 3 | 0 | 3 | 1 | -| | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Visualization editor allowing to quickly and easily configure compelling visualizations to use on dashboards and canvas workpads. Exposes components to embed visualizations and link into the Lens editor from within other apps in Kibana. | 621 | 0 | 535 | 40 | +| | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Visualization editor allowing to quickly and easily configure compelling visualizations to use on dashboards and canvas workpads. Exposes components to embed visualizations and link into the Lens editor from within other apps in Kibana. | 606 | 0 | 520 | 40 | | | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 8 | 0 | 8 | 0 | | | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 3 | 0 | 3 | 0 | | | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 117 | 0 | 42 | 10 | @@ -113,7 +113,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [Stack Monitoring](https://github.com/orgs/elastic/teams/stack-monitoring-ui) | - | 9 | 0 | 9 | 0 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | - | 34 | 0 | 34 | 2 | | | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 17 | 0 | 17 | 0 | -| | [Observability UI](https://github.com/orgs/elastic/teams/observability-ui) | - | 399 | 2 | 396 | 30 | +| | [Observability UI](https://github.com/orgs/elastic/teams/observability-ui) | - | 396 | 2 | 393 | 30 | | | [Security asset management](https://github.com/orgs/elastic/teams/security-asset-management) | - | 13 | 0 | 13 | 0 | | painlessLab | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 0 | 0 | 0 | 0 | | | [Kibana Presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | The Presentation Utility Plugin is a set of common, shared components and toolkits for solutions within the Presentation space, (e.g. Dashboards, Canvas). | 243 | 2 | 187 | 12 | @@ -126,7 +126,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 125 | 0 | 112 | 0 | | | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 78 | 0 | 72 | 3 | | | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 91 | 0 | 46 | 1 | -| | [Data Discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | This plugin contains the definition and helper methods around saved searches, used by discover and visualizations. | 39 | 0 | 39 | 1 | +| | [Data Discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | This plugin contains the definition and helper methods around saved searches, used by discover and visualizations. | 42 | 0 | 42 | 1 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | - | 32 | 0 | 13 | 0 | | | [Kibana Reporting Services](https://github.com/orgs/elastic/teams/kibana-reporting-services) | Kibana Screenshotting Plugin | 27 | 0 | 8 | 4 | | searchprofiler | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 0 | 0 | 0 | 0 | @@ -134,7 +134,6 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [Security solution](https://github.com/orgs/elastic/teams/security-solution) | - | 54 | 0 | 53 | 22 | | | [Security Team](https://github.com/orgs/elastic/teams/security-team) | - | 3 | 0 | 3 | 1 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Adds URL Service and sharing capabilities to Kibana | 114 | 0 | 55 | 10 | -| | [Shared UX](https://github.com/orgs/elastic/teams/shared-ux) | A plugin providing components and services for shared user experiences in Kibana. | 4 | 0 | 0 | 0 | | | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 22 | 1 | 22 | 1 | | | [Platform Security](https://github.com/orgs/elastic/teams/kibana-security) | This plugin provides the Spaces feature, which allows saved objects to be organized into meaningful categories. | 260 | 0 | 64 | 0 | | | [Response Ops](https://github.com/orgs/elastic/teams/response-ops) | - | 4 | 0 | 4 | 0 | @@ -144,13 +143,14 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [Kibana Telemetry](https://github.com/orgs/elastic/teams/kibana-telemetry) | - | 31 | 0 | 26 | 6 | | | [Kibana Telemetry](https://github.com/orgs/elastic/teams/kibana-telemetry) | - | 1 | 0 | 1 | 0 | | | [Kibana Telemetry](https://github.com/orgs/elastic/teams/kibana-telemetry) | - | 11 | 0 | 10 | 0 | -| | [Protections Experience Team](https://github.com/orgs/elastic/teams/protections-experience) | Elastic threat intelligence helps you see if you are open to or have been subject to current or historical known threats | 15 | 0 | 3 | 1 | -| | [Security solution](https://github.com/orgs/elastic/teams/security-solution) | - | 447 | 1 | 342 | 32 | +| | [Protections Experience Team](https://github.com/orgs/elastic/teams/protections-experience) | Elastic threat intelligence helps you see if you are open to or have been subject to current or historical known threats | 16 | 0 | 4 | 2 | +| | [Security solution](https://github.com/orgs/elastic/teams/security-solution) | - | 445 | 1 | 340 | 32 | | | [Machine Learning UI](https://github.com/orgs/elastic/teams/ml-ui) | This plugin provides access to the transforms features provided by Elastic. Transforms enable you to convert existing Elasticsearch indices into summarized indices, which provide opportunities for new insights and analytics. | 4 | 0 | 4 | 1 | | translations | [Kibana Localization](https://github.com/orgs/elastic/teams/kibana-localization) | - | 0 | 0 | 0 | 0 | | | [Response Ops](https://github.com/orgs/elastic/teams/response-ops) | - | 428 | 0 | 407 | 46 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Adds UI Actions service to Kibana | 132 | 0 | 91 | 11 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Extends UI Actions plugin with more functionality | 205 | 0 | 142 | 9 | +| | [Data Discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | Contains functionality for the field list which can be integrated into apps | 51 | 0 | 49 | 2 | | | [Unified Search](https://github.com/orgs/elastic/teams/kibana-app-services) | Contains all the key functionality of Kibana's unified search experience.Contains all the key functionality of Kibana's unified search experience. | 108 | 2 | 84 | 16 | | upgradeAssistant | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 0 | 0 | 0 | 0 | | urlDrilldown | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Adds drilldown implementations to Kibana | 0 | 0 | 0 | 0 | @@ -169,15 +169,14 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Registers the TSVB visualization. TSVB has its one editor, works with index patterns and index strings and contains 6 types of charts: timeseries, topN, table. markdown, metric and gauge. | 10 | 1 | 10 | 3 | | | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Registers the vega visualization. Is the elastic version of vega and vega-lite libraries. | 2 | 0 | 2 | 0 | | | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Contains the vislib visualizations. These are the classical area/line/bar, pie, gauge/goal and heatmap charts. We want to replace them with elastic-charts. | 26 | 0 | 25 | 1 | -| | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Contains the new xy-axis chart using the elastic-charts library, which will eventually replace the vislib xy-axis charts including bar, area, and line. | 57 | 0 | 51 | 5 | -| | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Contains the shared architecture among all the legacy visualizations, e.g. the visualization type registry or the visualization embeddable. | 380 | 12 | 356 | 14 | +| | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Contains the new xy-axis chart using the elastic-charts library, which will eventually replace the vislib xy-axis charts including bar, area, and line. | 53 | 0 | 50 | 5 | +| | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Contains the shared architecture among all the legacy visualizations, e.g. the visualization type registry or the visualization embeddable. | 416 | 12 | 388 | 15 | | watcher | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 0 | 0 | 0 | 0 | ## Package Directory | Package name           | Maintaining team | Description | API Cnt | Any Cnt | Missing
comments | Missing
exports | |--------------|----------------|-----------|--------------|----------|---------------|--------| -| | [Owner missing] | Elastic APM trace data generator | 74 | 0 | 74 | 11 | | | [Owner missing] | - | 11 | 5 | 11 | 0 | | | Machine Learning UI | React components for AIOps related efforts. | 6 | 0 | 6 | 0 | | | Machine Learning UI | Static utilities for AIOps related efforts. | 49 | 0 | 24 | 0 | @@ -189,9 +188,10 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | Kibana Core | - | 18 | 0 | 0 | 0 | | | Kibana Core | - | 20 | 0 | 0 | 0 | | | [Owner missing] | - | 16 | 0 | 16 | 0 | +| | [Owner missing] | Elastic APM trace data generator | 75 | 0 | 75 | 12 | | | [Owner missing] | - | 11 | 0 | 11 | 0 | | | [Owner missing] | - | 10 | 0 | 10 | 0 | -| | [Owner missing] | - | 18 | 0 | 9 | 1 | +| | [Owner missing] | - | 76 | 0 | 76 | 0 | | | [Owner missing] | - | 7 | 0 | 2 | 0 | | | [Owner missing] | - | 3 | 0 | 3 | 0 | | | [Owner missing] | - | 62 | 0 | 17 | 1 | @@ -277,11 +277,14 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | Kibana Core | - | 6 | 0 | 6 | 0 | | | Kibana Core | - | 94 | 1 | 66 | 0 | | | Kibana Core | - | 288 | 1 | 125 | 0 | +| | [Owner missing] | - | 35 | 0 | 29 | 1 | +| | [Owner missing] | - | 4 | 0 | 4 | 0 | | | Kibana Core | - | 2 | 0 | 1 | 0 | | | Kibana Core | - | 6 | 0 | 6 | 0 | | | Kibana Core | - | 7 | 0 | 7 | 0 | | | Kibana Core | - | 82 | 0 | 41 | 0 | | | Kibana Core | - | 225 | 0 | 82 | 0 | +| | [Owner missing] | - | 99 | 1 | 86 | 0 | | | Kibana Core | - | 11 | 0 | 9 | 0 | | | Kibana Core | - | 5 | 0 | 5 | 0 | | | Kibana Core | - | 6 | 0 | 4 | 0 | @@ -357,17 +360,20 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [Owner missing] | - | 20 | 0 | 6 | 0 | | | [Owner missing] | - | 10 | 0 | 4 | 0 | | | [Owner missing] | - | 32 | 0 | 28 | 0 | -| | [Owner missing] | - | 11 | 0 | 6 | 0 | -| | [Owner missing] | - | 8 | 0 | 7 | 0 | +| | [Owner missing] | - | 10 | 0 | 9 | 0 | | | [Owner missing] | - | 13 | 0 | 4 | 1 | | | [Owner missing] | - | 12 | 0 | 12 | 0 | -| | [Owner missing] | - | 26 | 0 | 3 | 0 | +| | [Owner missing] | - | 8 | 0 | 3 | 0 | | | [Owner missing] | - | 25 | 0 | 24 | 0 | +| | [Owner missing] | - | 10 | 0 | 4 | 0 | +| | [Owner missing] | - | 43 | 5 | 43 | 2 | +| | [Owner missing] | - | 13 | 0 | 4 | 0 | +| | [Owner missing] | - | 11 | 0 | 5 | 0 | +| | [Owner missing] | - | 24 | 0 | 24 | 0 | +| | [Owner missing] | - | 27 | 0 | 26 | 0 | | | [Owner missing] | - | 5 | 0 | 3 | 0 | | | [Owner missing] | - | 24 | 0 | 4 | 0 | | | [Owner missing] | - | 17 | 0 | 16 | 0 | -| | [Owner missing] | - | 80 | 0 | 51 | 1 | -| | [Owner missing] | - | 16 | 0 | 7 | 0 | | | [Owner missing] | - | 14 | 0 | 4 | 1 | | | [Owner missing] | - | 9 | 0 | 3 | 0 | | | [Owner missing] | - | 20 | 0 | 12 | 0 | diff --git a/api_docs/presentation_util.devdocs.json b/api_docs/presentation_util.devdocs.json index 07de3fd6995759..c7d62fa7d26613 100644 --- a/api_docs/presentation_util.devdocs.json +++ b/api_docs/presentation_util.devdocs.json @@ -2264,7 +2264,7 @@ "label": "getProjects", "description": [], "signature": [ - "(solutions?: (\"presentation\" | \"dashboard\" | \"canvas\")[] | undefined) => Record<\"labs:dashboard:deferBelowFold\" | \"labs:dashboard:dashboardControls\" | \"labs:canvas:byValueEmbeddable\", ", + "(solutions?: (\"dashboard\" | \"canvas\" | \"presentation\")[] | undefined) => Record<\"labs:dashboard:deferBelowFold\" | \"labs:dashboard:dashboardControls\" | \"labs:canvas:byValueEmbeddable\", ", { "pluginId": "presentationUtil", "scope": "common", @@ -2285,7 +2285,7 @@ "label": "solutions", "description": [], "signature": [ - "(\"presentation\" | \"dashboard\" | \"canvas\")[] | undefined" + "(\"dashboard\" | \"canvas\" | \"presentation\")[] | undefined" ], "path": "src/plugins/presentation_util/public/services/labs.ts", "deprecated": false, @@ -3650,7 +3650,7 @@ "label": "solutions", "description": [], "signature": [ - "(\"presentation\" | \"dashboard\" | \"canvas\")[]" + "(\"dashboard\" | \"canvas\" | \"presentation\")[]" ], "path": "src/plugins/presentation_util/common/labs.ts", "deprecated": false @@ -3861,7 +3861,7 @@ "label": "SolutionName", "description": [], "signature": [ - "\"presentation\" | \"dashboard\" | \"canvas\"" + "\"dashboard\" | \"canvas\" | \"presentation\"" ], "path": "src/plugins/presentation_util/common/labs.ts", "deprecated": false, diff --git a/api_docs/presentation_util.mdx b/api_docs/presentation_util.mdx index 1349fd76232149..8bce2303499655 100644 --- a/api_docs/presentation_util.mdx +++ b/api_docs/presentation_util.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/presentationUtil title: "presentationUtil" image: https://source.unsplash.com/400x175/?github description: API docs for the presentationUtil plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'presentationUtil'] --- import presentationUtilObj from './presentation_util.devdocs.json'; diff --git a/api_docs/remote_clusters.mdx b/api_docs/remote_clusters.mdx index c7e9764f327f32..b349030a92494f 100644 --- a/api_docs/remote_clusters.mdx +++ b/api_docs/remote_clusters.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/remoteClusters title: "remoteClusters" image: https://source.unsplash.com/400x175/?github description: API docs for the remoteClusters plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'remoteClusters'] --- import remoteClustersObj from './remote_clusters.devdocs.json'; diff --git a/api_docs/reporting.mdx b/api_docs/reporting.mdx index bebe46d1d5640c..efd2aeef3fe58a 100644 --- a/api_docs/reporting.mdx +++ b/api_docs/reporting.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/reporting title: "reporting" image: https://source.unsplash.com/400x175/?github description: API docs for the reporting plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'reporting'] --- import reportingObj from './reporting.devdocs.json'; diff --git a/api_docs/rollup.mdx b/api_docs/rollup.mdx index 4e850d8461c88d..e8a3aca41d6724 100644 --- a/api_docs/rollup.mdx +++ b/api_docs/rollup.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/rollup title: "rollup" image: https://source.unsplash.com/400x175/?github description: API docs for the rollup plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'rollup'] --- import rollupObj from './rollup.devdocs.json'; diff --git a/api_docs/rule_registry.mdx b/api_docs/rule_registry.mdx index cee287db85b384..a0c38d1aeffc5b 100644 --- a/api_docs/rule_registry.mdx +++ b/api_docs/rule_registry.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ruleRegistry title: "ruleRegistry" image: https://source.unsplash.com/400x175/?github description: API docs for the ruleRegistry plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ruleRegistry'] --- import ruleRegistryObj from './rule_registry.devdocs.json'; diff --git a/api_docs/runtime_fields.mdx b/api_docs/runtime_fields.mdx index 78bb2d936dc7d5..187a9242f7f2f1 100644 --- a/api_docs/runtime_fields.mdx +++ b/api_docs/runtime_fields.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/runtimeFields title: "runtimeFields" image: https://source.unsplash.com/400x175/?github description: API docs for the runtimeFields plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'runtimeFields'] --- import runtimeFieldsObj from './runtime_fields.devdocs.json'; diff --git a/api_docs/saved_objects.devdocs.json b/api_docs/saved_objects.devdocs.json index fba13f71ed1cc2..03027ee4ba3a39 100644 --- a/api_docs/saved_objects.devdocs.json +++ b/api_docs/saved_objects.devdocs.json @@ -735,7 +735,7 @@ "section": "def-public.SavedObject", "text": "SavedObject" }, - ", \"id\" | \"title\" | \"getDisplayName\" | \"lastSavedTitle\" | \"copyOnSave\" | \"getEsType\">, isTitleDuplicateConfirmed: boolean, onTitleDuplicate: (() => void) | undefined, services: Pick<", + ", \"title\" | \"id\" | \"getDisplayName\" | \"lastSavedTitle\" | \"copyOnSave\" | \"getEsType\">, isTitleDuplicateConfirmed: boolean, onTitleDuplicate: (() => void) | undefined, services: Pick<", "SavedObjectKibanaServices", ", \"overlays\" | \"savedObjectsClient\">) => Promise" ], @@ -758,7 +758,7 @@ "section": "def-public.SavedObject", "text": "SavedObject" }, - ", \"id\" | \"title\" | \"getDisplayName\" | \"lastSavedTitle\" | \"copyOnSave\" | \"getEsType\">" + ", \"title\" | \"id\" | \"getDisplayName\" | \"lastSavedTitle\" | \"copyOnSave\" | \"getEsType\">" ], "path": "src/plugins/saved_objects/public/saved_object/helpers/check_for_duplicate_title.ts", "deprecated": false, @@ -1449,22 +1449,6 @@ "plugin": "savedObjectsTaggingOss", "path": "src/plugins/saved_objects_tagging_oss/public/api.ts" }, - { - "plugin": "visualizations", - "path": "src/plugins/visualizations/public/utils/saved_objects_utils/display_duplicate_title_confirm_modal.ts" - }, - { - "plugin": "visualizations", - "path": "src/plugins/visualizations/public/utils/saved_objects_utils/display_duplicate_title_confirm_modal.ts" - }, - { - "plugin": "visualizations", - "path": "src/plugins/visualizations/public/utils/saved_objects_utils/check_for_duplicate_title.ts" - }, - { - "plugin": "visualizations", - "path": "src/plugins/visualizations/public/utils/saved_objects_utils/check_for_duplicate_title.ts" - }, { "plugin": "dashboard", "path": "src/plugins/dashboard/public/services/saved_object_loader.ts" @@ -1508,22 +1492,6 @@ { "plugin": "dashboard", "path": "src/plugins/dashboard/public/application/actions/clone_panel_action.tsx" - }, - { - "plugin": "lens", - "path": "x-pack/plugins/lens/public/persistence/saved_objects_utils/display_duplicate_title_confirm_modal.ts" - }, - { - "plugin": "lens", - "path": "x-pack/plugins/lens/public/persistence/saved_objects_utils/display_duplicate_title_confirm_modal.ts" - }, - { - "plugin": "lens", - "path": "x-pack/plugins/lens/public/persistence/saved_objects_utils/check_for_duplicate_title.ts" - }, - { - "plugin": "lens", - "path": "x-pack/plugins/lens/public/persistence/saved_objects_utils/check_for_duplicate_title.ts" } ], "children": [ diff --git a/api_docs/saved_objects.mdx b/api_docs/saved_objects.mdx index 85cea28d320361..23f3edcca2e8b0 100644 --- a/api_docs/saved_objects.mdx +++ b/api_docs/saved_objects.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjects title: "savedObjects" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjects plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjects'] --- import savedObjectsObj from './saved_objects.devdocs.json'; diff --git a/api_docs/saved_objects_management.devdocs.json b/api_docs/saved_objects_management.devdocs.json index 9dbe29aa8207fe..ad24e523693441 100644 --- a/api_docs/saved_objects_management.devdocs.json +++ b/api_docs/saved_objects_management.devdocs.json @@ -278,7 +278,7 @@ "label": "euiColumn", "description": [], "signature": [ - "{ children?: React.ReactNode; onError?: React.ReactEventHandler | undefined; color?: string | undefined; className?: string | undefined; height?: string | number | undefined; id?: string | undefined; lang?: string | undefined; name: React.ReactNode; style?: React.CSSProperties | undefined; width?: string | undefined; role?: React.AriaRole | undefined; tabIndex?: number | undefined; 'aria-activedescendant'?: string | undefined; 'aria-atomic'?: boolean | \"true\" | \"false\" | undefined; 'aria-autocomplete'?: \"none\" | \"list\" | \"inline\" | \"both\" | undefined; 'aria-busy'?: boolean | \"true\" | \"false\" | undefined; 'aria-checked'?: boolean | \"true\" | \"false\" | \"mixed\" | undefined; 'aria-colcount'?: number | undefined; 'aria-colindex'?: number | undefined; 'aria-colspan'?: number | undefined; 'aria-controls'?: string | undefined; 'aria-current'?: boolean | \"date\" | \"location\" | \"true\" | \"false\" | \"page\" | \"step\" | \"time\" | undefined; 'aria-describedby'?: string | undefined; 'aria-details'?: string | undefined; 'aria-disabled'?: boolean | \"true\" | \"false\" | undefined; 'aria-dropeffect'?: \"none\" | \"link\" | \"copy\" | \"execute\" | \"move\" | \"popup\" | undefined; 'aria-errormessage'?: string | undefined; 'aria-expanded'?: boolean | \"true\" | \"false\" | undefined; 'aria-flowto'?: string | undefined; 'aria-grabbed'?: boolean | \"true\" | \"false\" | undefined; 'aria-haspopup'?: boolean | \"dialog\" | \"grid\" | \"listbox\" | \"menu\" | \"tree\" | \"true\" | \"false\" | undefined; 'aria-hidden'?: boolean | \"true\" | \"false\" | undefined; 'aria-invalid'?: boolean | \"true\" | \"false\" | \"grammar\" | \"spelling\" | undefined; 'aria-keyshortcuts'?: string | undefined; 'aria-label'?: string | undefined; 'aria-labelledby'?: string | undefined; 'aria-level'?: number | undefined; 'aria-live'?: \"off\" | \"assertive\" | \"polite\" | undefined; 'aria-modal'?: boolean | \"true\" | \"false\" | undefined; 'aria-multiline'?: boolean | \"true\" | \"false\" | undefined; 'aria-multiselectable'?: boolean | \"true\" | \"false\" | undefined; 'aria-orientation'?: \"horizontal\" | \"vertical\" | undefined; 'aria-owns'?: string | undefined; 'aria-placeholder'?: string | undefined; 'aria-posinset'?: number | undefined; 'aria-pressed'?: boolean | \"true\" | \"false\" | \"mixed\" | undefined; 'aria-readonly'?: boolean | \"true\" | \"false\" | undefined; 'aria-relevant'?: \"all\" | \"text\" | \"additions\" | \"additions removals\" | \"additions text\" | \"removals\" | \"removals additions\" | \"removals text\" | \"text additions\" | \"text removals\" | undefined; 'aria-required'?: boolean | \"true\" | \"false\" | undefined; 'aria-roledescription'?: string | undefined; 'aria-rowcount'?: number | undefined; 'aria-rowindex'?: number | undefined; 'aria-rowspan'?: number | undefined; 'aria-selected'?: boolean | \"true\" | \"false\" | undefined; 'aria-setsize'?: number | undefined; 'aria-sort'?: \"none\" | \"ascending\" | \"descending\" | \"other\" | undefined; 'aria-valuemax'?: number | undefined; 'aria-valuemin'?: number | undefined; 'aria-valuenow'?: number | undefined; 'aria-valuetext'?: string | undefined; dangerouslySetInnerHTML?: { __html: string; } | undefined; onCopy?: React.ClipboardEventHandler | undefined; onCopyCapture?: React.ClipboardEventHandler | undefined; onCut?: React.ClipboardEventHandler | undefined; onCutCapture?: React.ClipboardEventHandler | undefined; onPaste?: React.ClipboardEventHandler | undefined; onPasteCapture?: React.ClipboardEventHandler | undefined; onCompositionEnd?: React.CompositionEventHandler | undefined; onCompositionEndCapture?: React.CompositionEventHandler | undefined; onCompositionStart?: React.CompositionEventHandler | undefined; onCompositionStartCapture?: React.CompositionEventHandler | undefined; onCompositionUpdate?: React.CompositionEventHandler | undefined; onCompositionUpdateCapture?: React.CompositionEventHandler | undefined; onFocus?: React.FocusEventHandler | undefined; onFocusCapture?: React.FocusEventHandler | undefined; onBlur?: React.FocusEventHandler | undefined; onBlurCapture?: React.FocusEventHandler | undefined; onChange?: React.FormEventHandler | undefined; onChangeCapture?: React.FormEventHandler | undefined; onBeforeInput?: React.FormEventHandler | undefined; onBeforeInputCapture?: React.FormEventHandler | undefined; onInput?: React.FormEventHandler | undefined; onInputCapture?: React.FormEventHandler | undefined; onReset?: React.FormEventHandler | undefined; onResetCapture?: React.FormEventHandler | undefined; onSubmit?: React.FormEventHandler | undefined; onSubmitCapture?: React.FormEventHandler | undefined; onInvalid?: React.FormEventHandler | undefined; onInvalidCapture?: React.FormEventHandler | undefined; onLoad?: React.ReactEventHandler | undefined; onLoadCapture?: React.ReactEventHandler | undefined; onErrorCapture?: React.ReactEventHandler | undefined; onKeyDown?: React.KeyboardEventHandler | undefined; onKeyDownCapture?: React.KeyboardEventHandler | undefined; onKeyPress?: React.KeyboardEventHandler | undefined; onKeyPressCapture?: React.KeyboardEventHandler | undefined; onKeyUp?: React.KeyboardEventHandler | undefined; onKeyUpCapture?: React.KeyboardEventHandler | undefined; onAbort?: React.ReactEventHandler | undefined; onAbortCapture?: React.ReactEventHandler | undefined; onCanPlay?: React.ReactEventHandler | undefined; onCanPlayCapture?: React.ReactEventHandler | undefined; onCanPlayThrough?: React.ReactEventHandler | undefined; onCanPlayThroughCapture?: React.ReactEventHandler | undefined; onDurationChange?: React.ReactEventHandler | undefined; onDurationChangeCapture?: React.ReactEventHandler | undefined; onEmptied?: React.ReactEventHandler | undefined; onEmptiedCapture?: React.ReactEventHandler | undefined; onEncrypted?: React.ReactEventHandler | undefined; onEncryptedCapture?: React.ReactEventHandler | undefined; onEnded?: React.ReactEventHandler | undefined; onEndedCapture?: React.ReactEventHandler | undefined; onLoadedData?: React.ReactEventHandler | undefined; onLoadedDataCapture?: React.ReactEventHandler | undefined; onLoadedMetadata?: React.ReactEventHandler | undefined; onLoadedMetadataCapture?: React.ReactEventHandler | undefined; onLoadStart?: React.ReactEventHandler | undefined; onLoadStartCapture?: React.ReactEventHandler | undefined; onPause?: React.ReactEventHandler | undefined; onPauseCapture?: React.ReactEventHandler | undefined; onPlay?: React.ReactEventHandler | undefined; onPlayCapture?: React.ReactEventHandler | undefined; onPlaying?: React.ReactEventHandler | undefined; onPlayingCapture?: React.ReactEventHandler | undefined; onProgress?: React.ReactEventHandler | undefined; onProgressCapture?: React.ReactEventHandler | undefined; onRateChange?: React.ReactEventHandler | undefined; onRateChangeCapture?: React.ReactEventHandler | undefined; onSeeked?: React.ReactEventHandler | undefined; onSeekedCapture?: React.ReactEventHandler | undefined; onSeeking?: React.ReactEventHandler | undefined; onSeekingCapture?: React.ReactEventHandler | undefined; onStalled?: React.ReactEventHandler | undefined; onStalledCapture?: React.ReactEventHandler | undefined; onSuspend?: React.ReactEventHandler | undefined; onSuspendCapture?: React.ReactEventHandler | undefined; onTimeUpdate?: React.ReactEventHandler | undefined; onTimeUpdateCapture?: React.ReactEventHandler | undefined; onVolumeChange?: React.ReactEventHandler | undefined; onVolumeChangeCapture?: React.ReactEventHandler | undefined; onWaiting?: React.ReactEventHandler | undefined; onWaitingCapture?: React.ReactEventHandler | undefined; onAuxClick?: React.MouseEventHandler | undefined; onAuxClickCapture?: React.MouseEventHandler | undefined; onClick?: React.MouseEventHandler | undefined; onClickCapture?: React.MouseEventHandler | undefined; onContextMenu?: React.MouseEventHandler | undefined; onContextMenuCapture?: React.MouseEventHandler | undefined; onDoubleClick?: React.MouseEventHandler | undefined; onDoubleClickCapture?: React.MouseEventHandler | undefined; onDrag?: React.DragEventHandler | undefined; onDragCapture?: React.DragEventHandler | undefined; onDragEnd?: React.DragEventHandler | undefined; onDragEndCapture?: React.DragEventHandler | undefined; onDragEnter?: React.DragEventHandler | undefined; onDragEnterCapture?: React.DragEventHandler | undefined; onDragExit?: React.DragEventHandler | undefined; onDragExitCapture?: React.DragEventHandler | undefined; onDragLeave?: React.DragEventHandler | undefined; onDragLeaveCapture?: React.DragEventHandler | undefined; onDragOver?: React.DragEventHandler | undefined; onDragOverCapture?: React.DragEventHandler | undefined; onDragStart?: React.DragEventHandler | undefined; onDragStartCapture?: React.DragEventHandler | undefined; onDrop?: React.DragEventHandler | undefined; onDropCapture?: React.DragEventHandler | undefined; onMouseDown?: React.MouseEventHandler | undefined; onMouseDownCapture?: React.MouseEventHandler | undefined; onMouseEnter?: React.MouseEventHandler | undefined; onMouseLeave?: React.MouseEventHandler | undefined; onMouseMove?: React.MouseEventHandler | undefined; onMouseMoveCapture?: React.MouseEventHandler | undefined; onMouseOut?: React.MouseEventHandler | undefined; onMouseOutCapture?: React.MouseEventHandler | undefined; onMouseOver?: React.MouseEventHandler | undefined; onMouseOverCapture?: React.MouseEventHandler | undefined; onMouseUp?: React.MouseEventHandler | undefined; onMouseUpCapture?: React.MouseEventHandler | undefined; onSelect?: React.ReactEventHandler | undefined; onSelectCapture?: React.ReactEventHandler | undefined; onTouchCancel?: React.TouchEventHandler | undefined; onTouchCancelCapture?: React.TouchEventHandler | undefined; onTouchEnd?: React.TouchEventHandler | undefined; onTouchEndCapture?: React.TouchEventHandler | undefined; onTouchMove?: React.TouchEventHandler | undefined; onTouchMoveCapture?: React.TouchEventHandler | undefined; onTouchStart?: React.TouchEventHandler | undefined; onTouchStartCapture?: React.TouchEventHandler | undefined; onPointerDown?: React.PointerEventHandler | undefined; onPointerDownCapture?: React.PointerEventHandler | undefined; onPointerMove?: React.PointerEventHandler | undefined; onPointerMoveCapture?: React.PointerEventHandler | undefined; onPointerUp?: React.PointerEventHandler | undefined; onPointerUpCapture?: React.PointerEventHandler | undefined; onPointerCancel?: React.PointerEventHandler | undefined; onPointerCancelCapture?: React.PointerEventHandler | undefined; onPointerEnter?: React.PointerEventHandler | undefined; onPointerEnterCapture?: React.PointerEventHandler | undefined; onPointerLeave?: React.PointerEventHandler | undefined; onPointerLeaveCapture?: React.PointerEventHandler | undefined; onPointerOver?: React.PointerEventHandler | undefined; onPointerOverCapture?: React.PointerEventHandler | undefined; onPointerOut?: React.PointerEventHandler | undefined; onPointerOutCapture?: React.PointerEventHandler | undefined; onGotPointerCapture?: React.PointerEventHandler | undefined; onGotPointerCaptureCapture?: React.PointerEventHandler | undefined; onLostPointerCapture?: React.PointerEventHandler | undefined; onLostPointerCaptureCapture?: React.PointerEventHandler | undefined; onScroll?: React.UIEventHandler | undefined; onScrollCapture?: React.UIEventHandler | undefined; onWheel?: React.WheelEventHandler | undefined; onWheelCapture?: React.WheelEventHandler | undefined; onAnimationStart?: React.AnimationEventHandler | undefined; onAnimationStartCapture?: React.AnimationEventHandler | undefined; onAnimationEnd?: React.AnimationEventHandler | undefined; onAnimationEndCapture?: React.AnimationEventHandler | undefined; onAnimationIteration?: React.AnimationEventHandler | undefined; onAnimationIterationCapture?: React.AnimationEventHandler | undefined; onTransitionEnd?: React.TransitionEventHandler | undefined; onTransitionEndCapture?: React.TransitionEventHandler | undefined; 'data-test-subj'?: string | undefined; title?: string | undefined; render?: ((value: any, record: ", + "{ children?: React.ReactNode; onError?: React.ReactEventHandler | undefined; render?: ((value: any, record: ", { "pluginId": "savedObjectsManagement", "scope": "public", @@ -286,7 +286,7 @@ "section": "def-public.SavedObjectsManagementRecord", "text": "SavedObjectsManagementRecord" }, - ") => React.ReactNode) | undefined; hidden?: boolean | undefined; description?: string | undefined; security?: string | undefined; field: (string & {}) | keyof ", + ") => React.ReactNode) | undefined; hidden?: boolean | undefined; color?: string | undefined; className?: string | undefined; title?: string | undefined; onChange?: React.FormEventHandler | undefined; onKeyDown?: React.KeyboardEventHandler | undefined; onClick?: React.MouseEventHandler | undefined; id?: string | undefined; description?: string | undefined; security?: string | undefined; name: React.ReactNode; field: (string & {}) | keyof ", { "pluginId": "savedObjectsManagement", "scope": "public", @@ -294,7 +294,7 @@ "section": "def-public.SavedObjectsManagementRecord", "text": "SavedObjectsManagementRecord" }, - "; defaultValue?: string | number | readonly string[] | undefined; defaultChecked?: boolean | undefined; suppressContentEditableWarning?: boolean | undefined; suppressHydrationWarning?: boolean | undefined; accessKey?: string | undefined; contentEditable?: \"inherit\" | Booleanish | undefined; contextMenu?: string | undefined; dir?: string | undefined; draggable?: Booleanish | undefined; placeholder?: string | undefined; slot?: string | undefined; spellCheck?: Booleanish | undefined; translate?: \"no\" | \"yes\" | undefined; radioGroup?: string | undefined; about?: string | undefined; datatype?: string | undefined; inlist?: any; prefix?: string | undefined; property?: string | undefined; resource?: string | undefined; typeof?: string | undefined; vocab?: string | undefined; autoCapitalize?: string | undefined; autoCorrect?: string | undefined; autoSave?: string | undefined; itemProp?: string | undefined; itemScope?: boolean | undefined; itemType?: string | undefined; itemID?: string | undefined; itemRef?: string | undefined; results?: number | undefined; unselectable?: \"off\" | \"on\" | undefined; inputMode?: \"none\" | \"text\" | \"search\" | \"email\" | \"tel\" | \"url\" | \"numeric\" | \"decimal\" | undefined; is?: string | undefined; readOnly?: boolean | undefined; align?: ", + "; defaultValue?: string | number | readonly string[] | undefined; lang?: string | undefined; defaultChecked?: boolean | undefined; suppressContentEditableWarning?: boolean | undefined; suppressHydrationWarning?: boolean | undefined; accessKey?: string | undefined; contentEditable?: \"inherit\" | Booleanish | undefined; contextMenu?: string | undefined; dir?: string | undefined; draggable?: Booleanish | undefined; placeholder?: string | undefined; slot?: string | undefined; spellCheck?: Booleanish | undefined; style?: React.CSSProperties | undefined; tabIndex?: number | undefined; translate?: \"no\" | \"yes\" | undefined; radioGroup?: string | undefined; role?: React.AriaRole | undefined; about?: string | undefined; datatype?: string | undefined; inlist?: any; prefix?: string | undefined; property?: string | undefined; resource?: string | undefined; typeof?: string | undefined; vocab?: string | undefined; autoCapitalize?: string | undefined; autoCorrect?: string | undefined; autoSave?: string | undefined; itemProp?: string | undefined; itemScope?: boolean | undefined; itemType?: string | undefined; itemID?: string | undefined; itemRef?: string | undefined; results?: number | undefined; unselectable?: \"on\" | \"off\" | undefined; inputMode?: \"none\" | \"email\" | \"search\" | \"text\" | \"tel\" | \"url\" | \"numeric\" | \"decimal\" | undefined; is?: string | undefined; 'aria-activedescendant'?: string | undefined; 'aria-atomic'?: Booleanish | undefined; 'aria-autocomplete'?: \"none\" | \"list\" | \"inline\" | \"both\" | undefined; 'aria-busy'?: Booleanish | undefined; 'aria-checked'?: boolean | \"mixed\" | \"false\" | \"true\" | undefined; 'aria-colcount'?: number | undefined; 'aria-colindex'?: number | undefined; 'aria-colspan'?: number | undefined; 'aria-controls'?: string | undefined; 'aria-current'?: boolean | \"date\" | \"location\" | \"time\" | \"page\" | \"false\" | \"true\" | \"step\" | undefined; 'aria-describedby'?: string | undefined; 'aria-details'?: string | undefined; 'aria-disabled'?: Booleanish | undefined; 'aria-dropeffect'?: \"none\" | \"copy\" | \"link\" | \"execute\" | \"move\" | \"popup\" | undefined; 'aria-errormessage'?: string | undefined; 'aria-expanded'?: Booleanish | undefined; 'aria-flowto'?: string | undefined; 'aria-grabbed'?: Booleanish | undefined; 'aria-haspopup'?: boolean | \"grid\" | \"menu\" | \"false\" | \"true\" | \"dialog\" | \"listbox\" | \"tree\" | undefined; 'aria-hidden'?: Booleanish | undefined; 'aria-invalid'?: boolean | \"false\" | \"true\" | \"grammar\" | \"spelling\" | undefined; 'aria-keyshortcuts'?: string | undefined; 'aria-label'?: string | undefined; 'aria-labelledby'?: string | undefined; 'aria-level'?: number | undefined; 'aria-live'?: \"off\" | \"assertive\" | \"polite\" | undefined; 'aria-modal'?: Booleanish | undefined; 'aria-multiline'?: Booleanish | undefined; 'aria-multiselectable'?: Booleanish | undefined; 'aria-orientation'?: \"horizontal\" | \"vertical\" | undefined; 'aria-owns'?: string | undefined; 'aria-placeholder'?: string | undefined; 'aria-posinset'?: number | undefined; 'aria-pressed'?: boolean | \"mixed\" | \"false\" | \"true\" | undefined; 'aria-readonly'?: Booleanish | undefined; 'aria-relevant'?: \"all\" | \"text\" | \"additions\" | \"additions removals\" | \"additions text\" | \"removals\" | \"removals additions\" | \"removals text\" | \"text additions\" | \"text removals\" | undefined; 'aria-required'?: Booleanish | undefined; 'aria-roledescription'?: string | undefined; 'aria-rowcount'?: number | undefined; 'aria-rowindex'?: number | undefined; 'aria-rowspan'?: number | undefined; 'aria-selected'?: Booleanish | undefined; 'aria-setsize'?: number | undefined; 'aria-sort'?: \"none\" | \"other\" | \"ascending\" | \"descending\" | undefined; 'aria-valuemax'?: number | undefined; 'aria-valuemin'?: number | undefined; 'aria-valuenow'?: number | undefined; 'aria-valuetext'?: string | undefined; dangerouslySetInnerHTML?: { __html: string; } | undefined; onCopy?: React.ClipboardEventHandler | undefined; onCopyCapture?: React.ClipboardEventHandler | undefined; onCut?: React.ClipboardEventHandler | undefined; onCutCapture?: React.ClipboardEventHandler | undefined; onPaste?: React.ClipboardEventHandler | undefined; onPasteCapture?: React.ClipboardEventHandler | undefined; onCompositionEnd?: React.CompositionEventHandler | undefined; onCompositionEndCapture?: React.CompositionEventHandler | undefined; onCompositionStart?: React.CompositionEventHandler | undefined; onCompositionStartCapture?: React.CompositionEventHandler | undefined; onCompositionUpdate?: React.CompositionEventHandler | undefined; onCompositionUpdateCapture?: React.CompositionEventHandler | undefined; onFocus?: React.FocusEventHandler | undefined; onFocusCapture?: React.FocusEventHandler | undefined; onBlur?: React.FocusEventHandler | undefined; onBlurCapture?: React.FocusEventHandler | undefined; onChangeCapture?: React.FormEventHandler | undefined; onBeforeInput?: React.FormEventHandler | undefined; onBeforeInputCapture?: React.FormEventHandler | undefined; onInput?: React.FormEventHandler | undefined; onInputCapture?: React.FormEventHandler | undefined; onReset?: React.FormEventHandler | undefined; onResetCapture?: React.FormEventHandler | undefined; onSubmit?: React.FormEventHandler | undefined; onSubmitCapture?: React.FormEventHandler | undefined; onInvalid?: React.FormEventHandler | undefined; onInvalidCapture?: React.FormEventHandler | undefined; onLoad?: React.ReactEventHandler | undefined; onLoadCapture?: React.ReactEventHandler | undefined; onErrorCapture?: React.ReactEventHandler | undefined; onKeyDownCapture?: React.KeyboardEventHandler | undefined; onKeyPress?: React.KeyboardEventHandler | undefined; onKeyPressCapture?: React.KeyboardEventHandler | undefined; onKeyUp?: React.KeyboardEventHandler | undefined; onKeyUpCapture?: React.KeyboardEventHandler | undefined; onAbort?: React.ReactEventHandler | undefined; onAbortCapture?: React.ReactEventHandler | undefined; onCanPlay?: React.ReactEventHandler | undefined; onCanPlayCapture?: React.ReactEventHandler | undefined; onCanPlayThrough?: React.ReactEventHandler | undefined; onCanPlayThroughCapture?: React.ReactEventHandler | undefined; onDurationChange?: React.ReactEventHandler | undefined; onDurationChangeCapture?: React.ReactEventHandler | undefined; onEmptied?: React.ReactEventHandler | undefined; onEmptiedCapture?: React.ReactEventHandler | undefined; onEncrypted?: React.ReactEventHandler | undefined; onEncryptedCapture?: React.ReactEventHandler | undefined; onEnded?: React.ReactEventHandler | undefined; onEndedCapture?: React.ReactEventHandler | undefined; onLoadedData?: React.ReactEventHandler | undefined; onLoadedDataCapture?: React.ReactEventHandler | undefined; onLoadedMetadata?: React.ReactEventHandler | undefined; onLoadedMetadataCapture?: React.ReactEventHandler | undefined; onLoadStart?: React.ReactEventHandler | undefined; onLoadStartCapture?: React.ReactEventHandler | undefined; onPause?: React.ReactEventHandler | undefined; onPauseCapture?: React.ReactEventHandler | undefined; onPlay?: React.ReactEventHandler | undefined; onPlayCapture?: React.ReactEventHandler | undefined; onPlaying?: React.ReactEventHandler | undefined; onPlayingCapture?: React.ReactEventHandler | undefined; onProgress?: React.ReactEventHandler | undefined; onProgressCapture?: React.ReactEventHandler | undefined; onRateChange?: React.ReactEventHandler | undefined; onRateChangeCapture?: React.ReactEventHandler | undefined; onSeeked?: React.ReactEventHandler | undefined; onSeekedCapture?: React.ReactEventHandler | undefined; onSeeking?: React.ReactEventHandler | undefined; onSeekingCapture?: React.ReactEventHandler | undefined; onStalled?: React.ReactEventHandler | undefined; onStalledCapture?: React.ReactEventHandler | undefined; onSuspend?: React.ReactEventHandler | undefined; onSuspendCapture?: React.ReactEventHandler | undefined; onTimeUpdate?: React.ReactEventHandler | undefined; onTimeUpdateCapture?: React.ReactEventHandler | undefined; onVolumeChange?: React.ReactEventHandler | undefined; onVolumeChangeCapture?: React.ReactEventHandler | undefined; onWaiting?: React.ReactEventHandler | undefined; onWaitingCapture?: React.ReactEventHandler | undefined; onAuxClick?: React.MouseEventHandler | undefined; onAuxClickCapture?: React.MouseEventHandler | undefined; onClickCapture?: React.MouseEventHandler | undefined; onContextMenu?: React.MouseEventHandler | undefined; onContextMenuCapture?: React.MouseEventHandler | undefined; onDoubleClick?: React.MouseEventHandler | undefined; onDoubleClickCapture?: React.MouseEventHandler | undefined; onDrag?: React.DragEventHandler | undefined; onDragCapture?: React.DragEventHandler | undefined; onDragEnd?: React.DragEventHandler | undefined; onDragEndCapture?: React.DragEventHandler | undefined; onDragEnter?: React.DragEventHandler | undefined; onDragEnterCapture?: React.DragEventHandler | undefined; onDragExit?: React.DragEventHandler | undefined; onDragExitCapture?: React.DragEventHandler | undefined; onDragLeave?: React.DragEventHandler | undefined; onDragLeaveCapture?: React.DragEventHandler | undefined; onDragOver?: React.DragEventHandler | undefined; onDragOverCapture?: React.DragEventHandler | undefined; onDragStart?: React.DragEventHandler | undefined; onDragStartCapture?: React.DragEventHandler | undefined; onDrop?: React.DragEventHandler | undefined; onDropCapture?: React.DragEventHandler | undefined; onMouseDown?: React.MouseEventHandler | undefined; onMouseDownCapture?: React.MouseEventHandler | undefined; onMouseEnter?: React.MouseEventHandler | undefined; onMouseLeave?: React.MouseEventHandler | undefined; onMouseMove?: React.MouseEventHandler | undefined; onMouseMoveCapture?: React.MouseEventHandler | undefined; onMouseOut?: React.MouseEventHandler | undefined; onMouseOutCapture?: React.MouseEventHandler | undefined; onMouseOver?: React.MouseEventHandler | undefined; onMouseOverCapture?: React.MouseEventHandler | undefined; onMouseUp?: React.MouseEventHandler | undefined; onMouseUpCapture?: React.MouseEventHandler | undefined; onSelect?: React.ReactEventHandler | undefined; onSelectCapture?: React.ReactEventHandler | undefined; onTouchCancel?: React.TouchEventHandler | undefined; onTouchCancelCapture?: React.TouchEventHandler | undefined; onTouchEnd?: React.TouchEventHandler | undefined; onTouchEndCapture?: React.TouchEventHandler | undefined; onTouchMove?: React.TouchEventHandler | undefined; onTouchMoveCapture?: React.TouchEventHandler | undefined; onTouchStart?: React.TouchEventHandler | undefined; onTouchStartCapture?: React.TouchEventHandler | undefined; onPointerDown?: React.PointerEventHandler | undefined; onPointerDownCapture?: React.PointerEventHandler | undefined; onPointerMove?: React.PointerEventHandler | undefined; onPointerMoveCapture?: React.PointerEventHandler | undefined; onPointerUp?: React.PointerEventHandler | undefined; onPointerUpCapture?: React.PointerEventHandler | undefined; onPointerCancel?: React.PointerEventHandler | undefined; onPointerCancelCapture?: React.PointerEventHandler | undefined; onPointerEnter?: React.PointerEventHandler | undefined; onPointerEnterCapture?: React.PointerEventHandler | undefined; onPointerLeave?: React.PointerEventHandler | undefined; onPointerLeaveCapture?: React.PointerEventHandler | undefined; onPointerOver?: React.PointerEventHandler | undefined; onPointerOverCapture?: React.PointerEventHandler | undefined; onPointerOut?: React.PointerEventHandler | undefined; onPointerOutCapture?: React.PointerEventHandler | undefined; onGotPointerCapture?: React.PointerEventHandler | undefined; onGotPointerCaptureCapture?: React.PointerEventHandler | undefined; onLostPointerCapture?: React.PointerEventHandler | undefined; onLostPointerCaptureCapture?: React.PointerEventHandler | undefined; onScroll?: React.UIEventHandler | undefined; onScrollCapture?: React.UIEventHandler | undefined; onWheel?: React.WheelEventHandler | undefined; onWheelCapture?: React.WheelEventHandler | undefined; onAnimationStart?: React.AnimationEventHandler | undefined; onAnimationStartCapture?: React.AnimationEventHandler | undefined; onAnimationEnd?: React.AnimationEventHandler | undefined; onAnimationEndCapture?: React.AnimationEventHandler | undefined; onAnimationIteration?: React.AnimationEventHandler | undefined; onAnimationIterationCapture?: React.AnimationEventHandler | undefined; onTransitionEnd?: React.TransitionEventHandler | undefined; onTransitionEndCapture?: React.TransitionEventHandler | undefined; 'data-test-subj'?: string | undefined; height?: string | number | undefined; width?: string | undefined; readOnly?: boolean | undefined; align?: ", "HorizontalAlignment", " | undefined; abbr?: string | undefined; footer?: string | React.ReactElement> | ((props: ", "EuiTableFooterProps", @@ -306,7 +306,7 @@ "section": "def-public.SavedObjectsManagementRecord", "text": "SavedObjectsManagementRecord" }, - ">) => React.ReactNode) | undefined; colSpan?: number | undefined; headers?: string | undefined; rowSpan?: number | undefined; scope?: string | undefined; valign?: \"baseline\" | \"middle\" | \"top\" | \"bottom\" | undefined; dataType?: ", + ">) => React.ReactNode) | undefined; colSpan?: number | undefined; headers?: string | undefined; rowSpan?: number | undefined; scope?: string | undefined; valign?: \"top\" | \"bottom\" | \"middle\" | \"baseline\" | undefined; dataType?: ", "EuiTableDataType", " | undefined; isExpander?: boolean | undefined; textOnly?: boolean | undefined; truncateText?: boolean | undefined; mobileOptions?: (Omit<", "EuiTableRowCellMobileOptionsShape", diff --git a/api_docs/saved_objects_management.mdx b/api_docs/saved_objects_management.mdx index 263533b99fcc60..8acf0b6dbbe359 100644 --- a/api_docs/saved_objects_management.mdx +++ b/api_docs/saved_objects_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsManagement title: "savedObjectsManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsManagement plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjectsManagement'] --- import savedObjectsManagementObj from './saved_objects_management.devdocs.json'; diff --git a/api_docs/saved_objects_tagging.devdocs.json b/api_docs/saved_objects_tagging.devdocs.json index 2cc307c5a8bb8e..0ed05dcb1409e2 100644 --- a/api_docs/saved_objects_tagging.devdocs.json +++ b/api_docs/saved_objects_tagging.devdocs.json @@ -1173,7 +1173,7 @@ "label": "errors", "description": [], "signature": [ - "{ color?: string | undefined; id?: string | undefined; name?: string | undefined; description?: string | undefined; }" + "{ color?: string | undefined; id?: string | undefined; description?: string | undefined; name?: string | undefined; }" ], "path": "x-pack/plugins/saved_objects_tagging/common/validation.ts", "deprecated": false diff --git a/api_docs/saved_objects_tagging.mdx b/api_docs/saved_objects_tagging.mdx index e1f1e2d66747a2..3cf2170cb00fa7 100644 --- a/api_docs/saved_objects_tagging.mdx +++ b/api_docs/saved_objects_tagging.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsTagging title: "savedObjectsTagging" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsTagging plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjectsTagging'] --- import savedObjectsTaggingObj from './saved_objects_tagging.devdocs.json'; diff --git a/api_docs/saved_objects_tagging_oss.mdx b/api_docs/saved_objects_tagging_oss.mdx index 423245cbcf65a3..69ecda2919d1bc 100644 --- a/api_docs/saved_objects_tagging_oss.mdx +++ b/api_docs/saved_objects_tagging_oss.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsTaggingOss title: "savedObjectsTaggingOss" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsTaggingOss plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjectsTaggingOss'] --- import savedObjectsTaggingOssObj from './saved_objects_tagging_oss.devdocs.json'; diff --git a/api_docs/saved_search.devdocs.json b/api_docs/saved_search.devdocs.json index d06c57ab18a202..4e3b1bb38f2617 100644 --- a/api_docs/saved_search.devdocs.json +++ b/api_docs/saved_search.devdocs.json @@ -687,6 +687,59 @@ "path": "src/plugins/saved_search/public/services/saved_searches/types.ts", "deprecated": false }, + { + "parentPluginId": "savedSearch", + "id": "def-public.SavedSearch.timeRestore", + "type": "CompoundType", + "tags": [], + "label": "timeRestore", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "src/plugins/saved_search/public/services/saved_searches/types.ts", + "deprecated": false + }, + { + "parentPluginId": "savedSearch", + "id": "def-public.SavedSearch.timeRange", + "type": "Object", + "tags": [], + "label": "timeRange", + "description": [], + "signature": [ + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataQueryPluginApi", + "section": "def-common.TimeRange", + "text": "TimeRange" + }, + " | undefined" + ], + "path": "src/plugins/saved_search/public/services/saved_searches/types.ts", + "deprecated": false + }, + { + "parentPluginId": "savedSearch", + "id": "def-public.SavedSearch.refreshInterval", + "type": "Object", + "tags": [], + "label": "refreshInterval", + "description": [], + "signature": [ + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataQueryPluginApi", + "section": "def-common.RefreshInterval", + "text": "RefreshInterval" + }, + " | undefined" + ], + "path": "src/plugins/saved_search/public/services/saved_searches/types.ts", + "deprecated": false + }, { "parentPluginId": "savedSearch", "id": "def-public.SavedSearch.rowsPerPage", diff --git a/api_docs/saved_search.mdx b/api_docs/saved_search.mdx index 642dcb1fcd37ba..3091be4a8d13af 100644 --- a/api_docs/saved_search.mdx +++ b/api_docs/saved_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedSearch title: "savedSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the savedSearch plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedSearch'] --- import savedSearchObj from './saved_search.devdocs.json'; @@ -21,7 +21,7 @@ Contact [Data Discovery](https://github.com/orgs/elastic/teams/kibana-data-disco | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 39 | 0 | 39 | 1 | +| 42 | 0 | 42 | 1 | ## Client diff --git a/api_docs/screenshot_mode.mdx b/api_docs/screenshot_mode.mdx index 458b9ec0c641a7..9b20d487f3329c 100644 --- a/api_docs/screenshot_mode.mdx +++ b/api_docs/screenshot_mode.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/screenshotMode title: "screenshotMode" image: https://source.unsplash.com/400x175/?github description: API docs for the screenshotMode plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'screenshotMode'] --- import screenshotModeObj from './screenshot_mode.devdocs.json'; diff --git a/api_docs/screenshotting.mdx b/api_docs/screenshotting.mdx index eba7d9d498f971..7acf530b372694 100644 --- a/api_docs/screenshotting.mdx +++ b/api_docs/screenshotting.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/screenshotting title: "screenshotting" image: https://source.unsplash.com/400x175/?github description: API docs for the screenshotting plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'screenshotting'] --- import screenshottingObj from './screenshotting.devdocs.json'; diff --git a/api_docs/security.mdx b/api_docs/security.mdx index 0f16d238a74003..8ca56e6d463af6 100644 --- a/api_docs/security.mdx +++ b/api_docs/security.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/security title: "security" image: https://source.unsplash.com/400x175/?github description: API docs for the security plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'security'] --- import securityObj from './security.devdocs.json'; diff --git a/api_docs/security_solution.mdx b/api_docs/security_solution.mdx index a051b08a595469..7f3496c005b00a 100644 --- a/api_docs/security_solution.mdx +++ b/api_docs/security_solution.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/securitySolution title: "securitySolution" image: https://source.unsplash.com/400x175/?github description: API docs for the securitySolution plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'securitySolution'] --- import securitySolutionObj from './security_solution.devdocs.json'; diff --git a/api_docs/session_view.mdx b/api_docs/session_view.mdx index 4e4f14fb1b0c07..1cba63e8707fcb 100644 --- a/api_docs/session_view.mdx +++ b/api_docs/session_view.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/sessionView title: "sessionView" image: https://source.unsplash.com/400x175/?github description: API docs for the sessionView plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'sessionView'] --- import sessionViewObj from './session_view.devdocs.json'; diff --git a/api_docs/share.mdx b/api_docs/share.mdx index 15f3b3c4b736bc..acee75ebcf13f4 100644 --- a/api_docs/share.mdx +++ b/api_docs/share.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/share title: "share" image: https://source.unsplash.com/400x175/?github description: API docs for the share plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'share'] --- import shareObj from './share.devdocs.json'; diff --git a/api_docs/shared_u_x.devdocs.json b/api_docs/shared_u_x.devdocs.json deleted file mode 100644 index 948d6b212ebf87..00000000000000 --- a/api_docs/shared_u_x.devdocs.json +++ /dev/null @@ -1,94 +0,0 @@ -{ - "id": "sharedUX", - "client": { - "classes": [], - "functions": [], - "interfaces": [], - "enums": [], - "misc": [], - "objects": [], - "start": { - "parentPluginId": "sharedUX", - "id": "def-public.SharedUXPluginStart", - "type": "Interface", - "tags": [], - "label": "SharedUXPluginStart", - "description": [ - "\nThe Shared UX plugin public contract, containing prewired components, services, and\nother constructs useful to consumers." - ], - "path": "src/plugins/shared_ux/public/types/index.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "sharedUX", - "id": "def-public.SharedUXPluginStart.getContextServices", - "type": "Function", - "tags": [], - "label": "getContextServices", - "description": [ - "\nA set of pre-wired services for use with `SharedUxServicesProvider`.\n\n```\nimport { SharedUxServicesProvider } from '@kbn/shared-ux-services';\n\npublic start(coreStart: CoreStart, startPlugins: MyPluginStartDeps): MyPluginStart {\n const services = startPlugins.sharedUX.getContextServices();\n return {\n ServicesContext: ({ children }) => {children},\n };\n}\n```\n\nor\n\n```\nimport { SharedUxServicesProvider } from '@kbn/shared-ux-services';\n\npublic setup(coreSetup: CoreSetup, setupPlugins: MyPluginSetupDeps): MyPluginSetup {\n const [coreStart, startPlugins] = await coreSetup.getStartServices();\n coreSetup.application.register({\n mount: async (params: AppMountParameters) => {\n ReactDOM.render(\n \n \n ,\n params.element\n );\n }\n );\n}\n```" - ], - "signature": [ - "() => ", - "SharedUxServices" - ], - "path": "src/plugins/shared_ux/public/types/index.ts", - "deprecated": false, - "children": [], - "returnComment": [] - } - ], - "lifecycle": "start", - "initialIsOpen": true - } - }, - "server": { - "classes": [], - "functions": [], - "interfaces": [], - "enums": [], - "misc": [], - "objects": [] - }, - "common": { - "classes": [], - "functions": [], - "interfaces": [], - "enums": [], - "misc": [ - { - "parentPluginId": "sharedUX", - "id": "def-common.PLUGIN_ID", - "type": "string", - "tags": [], - "label": "PLUGIN_ID", - "description": [ - "The ID of the Shared UX plugin." - ], - "signature": [ - "\"sharedUX\"" - ], - "path": "src/plugins/shared_ux/common/index.ts", - "deprecated": false, - "initialIsOpen": false - }, - { - "parentPluginId": "sharedUX", - "id": "def-common.PLUGIN_NAME", - "type": "string", - "tags": [], - "label": "PLUGIN_NAME", - "description": [ - "The name of the Shared UX plugin." - ], - "signature": [ - "\"sharedUX\"" - ], - "path": "src/plugins/shared_ux/common/index.ts", - "deprecated": false, - "initialIsOpen": false - } - ], - "objects": [] - } -} \ No newline at end of file diff --git a/api_docs/shared_u_x.mdx b/api_docs/shared_u_x.mdx deleted file mode 100644 index 6ffe23f15c8acc..00000000000000 --- a/api_docs/shared_u_x.mdx +++ /dev/null @@ -1,35 +0,0 @@ ---- -#### -#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system. -#### Reach out in #docs-engineering for more info. -#### -id: kibSharedUXPluginApi -slug: /kibana-dev-docs/api/sharedUX -title: "sharedUX" -image: https://source.unsplash.com/400x175/?github -description: API docs for the sharedUX plugin -date: 2022-08-17 -tags: ['contributor', 'dev', 'apidocs', 'kibana', 'sharedUX'] ---- -import sharedUXObj from './shared_u_x.devdocs.json'; - -A plugin providing components and services for shared user experiences in Kibana. - -Contact [Shared UX](https://github.com/orgs/elastic/teams/shared-ux) for questions regarding this plugin. - -**Code health stats** - -| Public API count | Any count | Items lacking comments | Missing exports | -|-------------------|-----------|------------------------|-----------------| -| 4 | 0 | 0 | 0 | - -## Client - -### Start - - -## Common - -### Consts, variables and types - - diff --git a/api_docs/snapshot_restore.mdx b/api_docs/snapshot_restore.mdx index dc5ea5be15efff..bc4cc27f96c166 100644 --- a/api_docs/snapshot_restore.mdx +++ b/api_docs/snapshot_restore.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/snapshotRestore title: "snapshotRestore" image: https://source.unsplash.com/400x175/?github description: API docs for the snapshotRestore plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'snapshotRestore'] --- import snapshotRestoreObj from './snapshot_restore.devdocs.json'; diff --git a/api_docs/spaces.devdocs.json b/api_docs/spaces.devdocs.json index b9471fcdf12a35..16599343be1d9d 100644 --- a/api_docs/spaces.devdocs.json +++ b/api_docs/spaces.devdocs.json @@ -1706,7 +1706,7 @@ "The size of the avatar." ], "signature": [ - "\"s\" | \"m\" | \"l\" | \"xl\" | undefined" + "\"m\" | \"s\" | \"l\" | \"xl\" | undefined" ], "path": "x-pack/plugins/spaces/public/space_avatar/types.ts", "deprecated": false diff --git a/api_docs/spaces.mdx b/api_docs/spaces.mdx index 619bc9943c4126..49e3e498bdd148 100644 --- a/api_docs/spaces.mdx +++ b/api_docs/spaces.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/spaces title: "spaces" image: https://source.unsplash.com/400x175/?github description: API docs for the spaces plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'spaces'] --- import spacesObj from './spaces.devdocs.json'; diff --git a/api_docs/stack_alerts.mdx b/api_docs/stack_alerts.mdx index 557528cb18826a..11cd82bbeb79d7 100644 --- a/api_docs/stack_alerts.mdx +++ b/api_docs/stack_alerts.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/stackAlerts title: "stackAlerts" image: https://source.unsplash.com/400x175/?github description: API docs for the stackAlerts plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'stackAlerts'] --- import stackAlertsObj from './stack_alerts.devdocs.json'; diff --git a/api_docs/task_manager.mdx b/api_docs/task_manager.mdx index 1cefdfc7d15e24..fe824bffc5f8ba 100644 --- a/api_docs/task_manager.mdx +++ b/api_docs/task_manager.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/taskManager title: "taskManager" image: https://source.unsplash.com/400x175/?github description: API docs for the taskManager plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'taskManager'] --- import taskManagerObj from './task_manager.devdocs.json'; diff --git a/api_docs/telemetry.mdx b/api_docs/telemetry.mdx index e636b96e796303..92b8c9c63ed6c8 100644 --- a/api_docs/telemetry.mdx +++ b/api_docs/telemetry.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetry title: "telemetry" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetry plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetry'] --- import telemetryObj from './telemetry.devdocs.json'; diff --git a/api_docs/telemetry_collection_manager.devdocs.json b/api_docs/telemetry_collection_manager.devdocs.json index 4db23391334f08..5d4bfd39478e64 100644 --- a/api_docs/telemetry_collection_manager.devdocs.json +++ b/api_docs/telemetry_collection_manager.devdocs.json @@ -124,7 +124,9 @@ "TransportRequestOptions", " | undefined): Promise<", "WriteResponseBase", - ">; }; name: string | symbol; transform: ", + ">; }; cluster: ", + "default", + "; eql: ", "default", "; search: { >; }; cluster: ", - "default", - "; eql: ", - "default", - "; create: { (this: That, params: ", + ">; }; create: { (this: That, params: ", "CreateRequest", " | ", "CreateRequest", @@ -192,7 +190,7 @@ "default", "; security: ", "default", - "; index: { (this: That, params: ", + "; name: string | symbol; index: { (this: That, params: ", "IndexRequest", " | ", "IndexRequest", @@ -1204,6 +1202,8 @@ "TermvectorsResponse", ">; }; textStructure: ", "default", + "; transform: ", + "default", "; updateByQuery: { (this: That, params: ", "UpdateByQueryRequest", " | ", diff --git a/api_docs/telemetry_collection_manager.mdx b/api_docs/telemetry_collection_manager.mdx index 3c4b0846798e6f..5d03032b41c0b3 100644 --- a/api_docs/telemetry_collection_manager.mdx +++ b/api_docs/telemetry_collection_manager.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetryCollectionManager title: "telemetryCollectionManager" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetryCollectionManager plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetryCollectionManager'] --- import telemetryCollectionManagerObj from './telemetry_collection_manager.devdocs.json'; diff --git a/api_docs/telemetry_collection_xpack.mdx b/api_docs/telemetry_collection_xpack.mdx index 9df85fefda611e..04fac139521fc0 100644 --- a/api_docs/telemetry_collection_xpack.mdx +++ b/api_docs/telemetry_collection_xpack.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetryCollectionXpack title: "telemetryCollectionXpack" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetryCollectionXpack plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetryCollectionXpack'] --- import telemetryCollectionXpackObj from './telemetry_collection_xpack.devdocs.json'; diff --git a/api_docs/telemetry_management_section.mdx b/api_docs/telemetry_management_section.mdx index 0401ffcb1e21db..0739a3d240084f 100644 --- a/api_docs/telemetry_management_section.mdx +++ b/api_docs/telemetry_management_section.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetryManagementSection title: "telemetryManagementSection" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetryManagementSection plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetryManagementSection'] --- import telemetryManagementSectionObj from './telemetry_management_section.devdocs.json'; diff --git a/api_docs/threat_intelligence.devdocs.json b/api_docs/threat_intelligence.devdocs.json index 380afebb238bfb..cc29bb35841110 100644 --- a/api_docs/threat_intelligence.devdocs.json +++ b/api_docs/threat_intelligence.devdocs.json @@ -132,6 +132,66 @@ } ], "interfaces": [ + { + "parentPluginId": "threatIntelligence", + "id": "def-public.SecuritySolutionPluginContext", + "type": "Interface", + "tags": [], + "label": "SecuritySolutionPluginContext", + "description": [ + "\nMethods exposed from the security solution to the threat intelligence application." + ], + "path": "x-pack/plugins/threat_intelligence/public/types.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "threatIntelligence", + "id": "def-public.SecuritySolutionPluginContext.getFiltersGlobalComponent", + "type": "Function", + "tags": [], + "label": "getFiltersGlobalComponent", + "description": [ + "\nGets the `FiltersGlobal` component for embedding a filter bar in the security solution application." + ], + "signature": [ + "() => React.ComponentType<{ children: React.ReactNode; }>" + ], + "path": "x-pack/plugins/threat_intelligence/public/types.ts", + "deprecated": false, + "children": [], + "returnComment": [] + }, + { + "parentPluginId": "threatIntelligence", + "id": "def-public.SecuritySolutionPluginContext.licenseService", + "type": "Object", + "tags": [], + "label": "licenseService", + "description": [ + "\nGet the user's license to drive the Threat Intelligence plugin's visibility." + ], + "signature": [ + "LicenseAware" + ], + "path": "x-pack/plugins/threat_intelligence/public/types.ts", + "deprecated": false + }, + { + "parentPluginId": "threatIntelligence", + "id": "def-public.SecuritySolutionPluginContext.sourcererDataView", + "type": "Object", + "tags": [], + "label": "sourcererDataView", + "description": [], + "signature": [ + "SourcererDataView" + ], + "path": "x-pack/plugins/threat_intelligence/public/types.ts", + "deprecated": false + } + ], + "initialIsOpen": false + }, { "parentPluginId": "threatIntelligence", "id": "def-public.ThreatIntelligencePluginSetup", @@ -167,8 +227,8 @@ "pluginId": "threatIntelligence", "scope": "public", "docId": "kibThreatIntelligencePluginApi", - "section": "def-public.ThreatIntelligenceSecuritySolutionContext", - "text": "ThreatIntelligenceSecuritySolutionContext" + "section": "def-public.SecuritySolutionPluginContext", + "text": "SecuritySolutionPluginContext" }, "; }) => React.ReactElement>" ], @@ -179,53 +239,6 @@ } ], "initialIsOpen": false - }, - { - "parentPluginId": "threatIntelligence", - "id": "def-public.ThreatIntelligenceSecuritySolutionContext", - "type": "Interface", - "tags": [], - "label": "ThreatIntelligenceSecuritySolutionContext", - "description": [ - "\nMethods exposed from the security solution to the threat intelligence application." - ], - "path": "x-pack/plugins/threat_intelligence/public/types.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "threatIntelligence", - "id": "def-public.ThreatIntelligenceSecuritySolutionContext.getFiltersGlobalComponent", - "type": "Function", - "tags": [], - "label": "getFiltersGlobalComponent", - "description": [ - "\nGets the `FiltersGlobal` component for embedding a filter bar in the security solution application." - ], - "signature": [ - "() => React.ComponentType<{ children: React.ReactNode; }>" - ], - "path": "x-pack/plugins/threat_intelligence/public/types.ts", - "deprecated": false, - "children": [], - "returnComment": [] - }, - { - "parentPluginId": "threatIntelligence", - "id": "def-public.ThreatIntelligenceSecuritySolutionContext.licenseService", - "type": "Object", - "tags": [], - "label": "licenseService", - "description": [ - "\nGet the user's license to drive the Threat Intelligence plugin's visibility." - ], - "signature": [ - "LicenseAware" - ], - "path": "x-pack/plugins/threat_intelligence/public/types.ts", - "deprecated": false - } - ], - "initialIsOpen": false } ], "enums": [], diff --git a/api_docs/threat_intelligence.mdx b/api_docs/threat_intelligence.mdx index f72511fe1369f0..53cf25c0a25ca6 100644 --- a/api_docs/threat_intelligence.mdx +++ b/api_docs/threat_intelligence.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/threatIntelligence title: "threatIntelligence" image: https://source.unsplash.com/400x175/?github description: API docs for the threatIntelligence plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'threatIntelligence'] --- import threatIntelligenceObj from './threat_intelligence.devdocs.json'; @@ -21,7 +21,7 @@ Contact [Protections Experience Team](https://github.com/orgs/elastic/teams/prot | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 15 | 0 | 3 | 1 | +| 16 | 0 | 4 | 2 | ## Client diff --git a/api_docs/timelines.devdocs.json b/api_docs/timelines.devdocs.json index 907c3864fb24dc..6132f131597c61 100644 --- a/api_docs/timelines.devdocs.json +++ b/api_docs/timelines.devdocs.json @@ -772,7 +772,7 @@ "EuiDataGridColumn", ", \"id\" | \"display\" | \"displayAsText\" | \"initialWidth\"> & Pick<", "EuiDataGridColumn", - ", \"id\" | \"display\" | \"schema\" | \"actions\" | \"defaultSortDirection\" | \"displayAsText\" | \"initialWidth\" | \"isSortable\"> & { aggregatable?: boolean | undefined; tGridCellActions?: ", + ", \"id\" | \"schema\" | \"actions\" | \"display\" | \"defaultSortDirection\" | \"displayAsText\" | \"initialWidth\" | \"isSortable\"> & { aggregatable?: boolean | undefined; tGridCellActions?: ", "TGridCellAction", "[] | undefined; category?: string | undefined; columnHeaderType: ", { @@ -804,7 +804,7 @@ "EuiDataGridColumn", ", \"id\" | \"display\" | \"displayAsText\" | \"initialWidth\"> & Pick<", "EuiDataGridColumn", - ", \"id\" | \"display\" | \"schema\" | \"actions\" | \"defaultSortDirection\" | \"displayAsText\" | \"initialWidth\" | \"isSortable\"> & { aggregatable?: boolean | undefined; tGridCellActions?: ", + ", \"id\" | \"schema\" | \"actions\" | \"display\" | \"defaultSortDirection\" | \"displayAsText\" | \"initialWidth\" | \"isSortable\"> & { aggregatable?: boolean | undefined; tGridCellActions?: ", "TGridCellAction", "[] | undefined; category?: string | undefined; columnHeaderType: ", { @@ -2302,7 +2302,7 @@ "EuiDataGridColumn", ", \"id\" | \"display\" | \"displayAsText\" | \"initialWidth\"> & Pick<", "EuiDataGridColumn", - ", \"id\" | \"display\" | \"schema\" | \"actions\" | \"defaultSortDirection\" | \"displayAsText\" | \"initialWidth\" | \"isSortable\"> & { aggregatable?: boolean | undefined; tGridCellActions?: ", + ", \"id\" | \"schema\" | \"actions\" | \"display\" | \"defaultSortDirection\" | \"displayAsText\" | \"initialWidth\" | \"isSortable\"> & { aggregatable?: boolean | undefined; tGridCellActions?: ", "TGridCellAction", "[] | undefined; category?: string | undefined; columnHeaderType: ", { @@ -2849,11 +2849,11 @@ "label": "TGridModelForTimeline", "description": [], "signature": [ - "{ id: string; version: string | null; title: string; columns: (Pick<", + "{ columns: (Pick<", "EuiDataGridColumn", ", \"id\" | \"display\" | \"displayAsText\" | \"initialWidth\"> & Pick<", "EuiDataGridColumn", - ", \"id\" | \"display\" | \"schema\" | \"actions\" | \"defaultSortDirection\" | \"displayAsText\" | \"initialWidth\" | \"isSortable\"> & { aggregatable?: boolean | undefined; tGridCellActions?: ", + ", \"id\" | \"schema\" | \"actions\" | \"display\" | \"defaultSortDirection\" | \"displayAsText\" | \"initialWidth\" | \"isSortable\"> & { aggregatable?: boolean | undefined; tGridCellActions?: ", "TGridCellAction", "[] | undefined; category?: string | undefined; columnHeaderType: ", { @@ -2865,11 +2865,11 @@ }, "; description?: string | null | undefined; esTypes?: string[] | undefined; example?: string | number | null | undefined; format?: string | undefined; linkField?: string | undefined; placeholder?: string | undefined; subType?: ", "IFieldSubType", - " | undefined; type?: string | undefined; })[]; filters?: ", + " | undefined; type?: string | undefined; })[]; title: string; id: string; filters?: ", "Filter", "[] | undefined; dataViewId: string | null; sort: ", "SortColumnTimeline", - "[]; filterManager?: ", + "[]; version: string | null; filterManager?: ", { "pluginId": "data", "scope": "public", @@ -2881,7 +2881,7 @@ "EuiDataGridColumn", ", \"id\" | \"display\" | \"displayAsText\" | \"initialWidth\"> & Pick<", "EuiDataGridColumn", - ", \"id\" | \"display\" | \"schema\" | \"actions\" | \"defaultSortDirection\" | \"displayAsText\" | \"initialWidth\" | \"isSortable\"> & { aggregatable?: boolean | undefined; tGridCellActions?: ", + ", \"id\" | \"schema\" | \"actions\" | \"display\" | \"defaultSortDirection\" | \"displayAsText\" | \"initialWidth\" | \"isSortable\"> & { aggregatable?: boolean | undefined; tGridCellActions?: ", "TGridCellAction", "[] | undefined; category?: string | undefined; columnHeaderType: ", { @@ -3981,7 +3981,7 @@ "signature": [ "Pick<", "EuiDataGridColumn", - ", \"id\" | \"display\" | \"schema\" | \"actions\" | \"defaultSortDirection\" | \"displayAsText\" | \"initialWidth\" | \"isSortable\"> & { aggregatable?: boolean | undefined; tGridCellActions?: ", + ", \"id\" | \"schema\" | \"actions\" | \"display\" | \"defaultSortDirection\" | \"displayAsText\" | \"initialWidth\" | \"isSortable\"> & { aggregatable?: boolean | undefined; tGridCellActions?: ", "TGridCellAction", "[] | undefined; category?: string | undefined; columnHeaderType: ", { @@ -6542,7 +6542,7 @@ "signature": [ "Pick<", "EuiDataGridColumn", - ", \"id\" | \"display\" | \"schema\" | \"actions\" | \"defaultSortDirection\" | \"displayAsText\" | \"initialWidth\" | \"isSortable\"> & { aggregatable?: boolean | undefined; tGridCellActions?: ", + ", \"id\" | \"schema\" | \"actions\" | \"display\" | \"defaultSortDirection\" | \"displayAsText\" | \"initialWidth\" | \"isSortable\"> & { aggregatable?: boolean | undefined; tGridCellActions?: ", "TGridCellAction", "[] | undefined; category?: string | undefined; columnHeaderType: ", { @@ -6650,35 +6650,6 @@ "deprecated": false, "initialIsOpen": false }, - { - "parentPluginId": "timelines", - "id": "def-common.DocValueFields", - "type": "Type", - "tags": [], - "label": "DocValueFields", - "description": [], - "signature": [ - "QueryDslFieldAndFormat" - ], - "path": "x-pack/plugins/timelines/common/search_strategy/common/index.ts", - "deprecated": false, - "initialIsOpen": false - }, - { - "parentPluginId": "timelines", - "id": "def-common.EMPTY_DOCVALUE_FIELD", - "type": "Array", - "tags": [], - "label": "EMPTY_DOCVALUE_FIELD", - "description": [], - "signature": [ - "QueryDslFieldAndFormat", - "[]" - ], - "path": "x-pack/plugins/timelines/common/search_strategy/index_fields/index.ts", - "deprecated": false, - "initialIsOpen": false - }, { "parentPluginId": "timelines", "id": "def-common.EMPTY_INDEX_FIELDS", diff --git a/api_docs/timelines.mdx b/api_docs/timelines.mdx index ed3e4fceafa93a..558aa61bbebcff 100644 --- a/api_docs/timelines.mdx +++ b/api_docs/timelines.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/timelines title: "timelines" image: https://source.unsplash.com/400x175/?github description: API docs for the timelines plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'timelines'] --- import timelinesObj from './timelines.devdocs.json'; @@ -21,7 +21,7 @@ Contact [Security solution](https://github.com/orgs/elastic/teams/security-solut | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 447 | 1 | 342 | 32 | +| 445 | 1 | 340 | 32 | ## Client diff --git a/api_docs/transform.mdx b/api_docs/transform.mdx index e4de9d355501e3..875ef1f9ccfd71 100644 --- a/api_docs/transform.mdx +++ b/api_docs/transform.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/transform title: "transform" image: https://source.unsplash.com/400x175/?github description: API docs for the transform plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'transform'] --- import transformObj from './transform.devdocs.json'; diff --git a/api_docs/triggers_actions_ui.devdocs.json b/api_docs/triggers_actions_ui.devdocs.json index efe1dc16a1b3f5..e8db880ec5e917 100644 --- a/api_docs/triggers_actions_ui.devdocs.json +++ b/api_docs/triggers_actions_ui.devdocs.json @@ -1508,7 +1508,7 @@ "label": "suspendedComponentWithProps", "description": [], "signature": [ - "(ComponentToSuspend: React.ComponentType, size: \"s\" | \"m\" | \"l\" | \"xl\" | \"xxl\" | undefined) => (props: T) => JSX.Element" + "(ComponentToSuspend: React.ComponentType, size: \"m\" | \"s\" | \"l\" | \"xl\" | \"xxl\" | undefined) => (props: T) => JSX.Element" ], "path": "x-pack/plugins/triggers_actions_ui/public/application/lib/suspended_component_with_props.tsx", "deprecated": false, @@ -1535,7 +1535,7 @@ "label": "size", "description": [], "signature": [ - "\"s\" | \"m\" | \"l\" | \"xl\" | \"xxl\" | undefined" + "\"m\" | \"s\" | \"l\" | \"xl\" | \"xxl\" | undefined" ], "path": "x-pack/plugins/triggers_actions_ui/public/application/lib/suspended_component_with_props.tsx", "deprecated": false, @@ -2071,7 +2071,7 @@ "label": "flyoutSize", "description": [], "signature": [ - "\"s\" | \"m\" | \"l\" | undefined" + "\"m\" | \"s\" | \"l\" | undefined" ], "path": "x-pack/plugins/triggers_actions_ui/public/types.ts", "deprecated": false @@ -3596,7 +3596,7 @@ "label": "setRuleProperty", "description": [], "signature": [ - "(key: Prop, value: ", + "(key: Prop, value: ", "SanitizedRule", "[Prop] | null) => void" ], diff --git a/api_docs/triggers_actions_ui.mdx b/api_docs/triggers_actions_ui.mdx index 5da79ec4719de4..c9f8a297d0f055 100644 --- a/api_docs/triggers_actions_ui.mdx +++ b/api_docs/triggers_actions_ui.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/triggersActionsUi title: "triggersActionsUi" image: https://source.unsplash.com/400x175/?github description: API docs for the triggersActionsUi plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'triggersActionsUi'] --- import triggersActionsUiObj from './triggers_actions_ui.devdocs.json'; diff --git a/api_docs/ui_actions.mdx b/api_docs/ui_actions.mdx index 3c618761dad0a1..58b6240a304cdb 100644 --- a/api_docs/ui_actions.mdx +++ b/api_docs/ui_actions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/uiActions title: "uiActions" image: https://source.unsplash.com/400x175/?github description: API docs for the uiActions plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'uiActions'] --- import uiActionsObj from './ui_actions.devdocs.json'; diff --git a/api_docs/ui_actions_enhanced.mdx b/api_docs/ui_actions_enhanced.mdx index 3a0e9c24f0fa26..1cffd81b2e8831 100644 --- a/api_docs/ui_actions_enhanced.mdx +++ b/api_docs/ui_actions_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/uiActionsEnhanced title: "uiActionsEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the uiActionsEnhanced plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'uiActionsEnhanced'] --- import uiActionsEnhancedObj from './ui_actions_enhanced.devdocs.json'; diff --git a/api_docs/unified_field_list.devdocs.json b/api_docs/unified_field_list.devdocs.json new file mode 100644 index 00000000000000..b78402a82f4db1 --- /dev/null +++ b/api_docs/unified_field_list.devdocs.json @@ -0,0 +1,780 @@ +{ + "id": "unifiedFieldList", + "client": { + "classes": [], + "functions": [ + { + "parentPluginId": "unifiedFieldList", + "id": "def-public.FieldStats", + "type": "Function", + "tags": [], + "label": "FieldStats", + "description": [], + "signature": [ + "React.FunctionComponent<", + { + "pluginId": "unifiedFieldList", + "scope": "public", + "docId": "kibUnifiedFieldListPluginApi", + "section": "def-public.FieldStatsProps", + "text": "FieldStatsProps" + }, + ">" + ], + "path": "src/plugins/unified_field_list/public/components/field_stats/index.tsx", + "deprecated": false, + "returnComment": [], + "children": [ + { + "parentPluginId": "unifiedFieldList", + "id": "def-public.FieldStats.$1", + "type": "CompoundType", + "tags": [], + "label": "props", + "description": [], + "signature": [ + "P & { children?: React.ReactNode; }" + ], + "path": "node_modules/@types/react/index.d.ts", + "deprecated": false + }, + { + "parentPluginId": "unifiedFieldList", + "id": "def-public.FieldStats.$2", + "type": "Any", + "tags": [], + "label": "context", + "description": [], + "signature": [ + "any" + ], + "path": "node_modules/@types/react/index.d.ts", + "deprecated": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "unifiedFieldList", + "id": "def-public.loadFieldStats", + "type": "Function", + "tags": [], + "label": "loadFieldStats", + "description": [], + "signature": [ + "(params: FetchFieldStatsParams) => Promise<", + "FieldStatsResponse", + ">" + ], + "path": "src/plugins/unified_field_list/public/services/field_stats/index.tsx", + "deprecated": false, + "children": [ + { + "parentPluginId": "unifiedFieldList", + "id": "def-public.loadFieldStats.$1", + "type": "Object", + "tags": [], + "label": "params", + "description": [], + "signature": [ + "FetchFieldStatsParams" + ], + "path": "src/plugins/unified_field_list/public/services/field_stats/index.tsx", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + } + ], + "interfaces": [ + { + "parentPluginId": "unifiedFieldList", + "id": "def-public.BucketedAggregation", + "type": "Interface", + "tags": [], + "label": "BucketedAggregation", + "description": [], + "signature": [ + "BucketedAggregation", + "" + ], + "path": "src/plugins/unified_field_list/common/types/stats.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "unifiedFieldList", + "id": "def-public.BucketedAggregation.buckets", + "type": "Array", + "tags": [], + "label": "buckets", + "description": [], + "signature": [ + "{ key: KeyType; count: number; }[]" + ], + "path": "src/plugins/unified_field_list/common/types/stats.ts", + "deprecated": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "unifiedFieldList", + "id": "def-public.FieldStatsProps", + "type": "Interface", + "tags": [], + "label": "FieldStatsProps", + "description": [], + "path": "src/plugins/unified_field_list/public/components/field_stats/field_stats.tsx", + "deprecated": false, + "children": [ + { + "parentPluginId": "unifiedFieldList", + "id": "def-public.FieldStatsProps.services", + "type": "Object", + "tags": [], + "label": "services", + "description": [], + "signature": [ + { + "pluginId": "unifiedFieldList", + "scope": "public", + "docId": "kibUnifiedFieldListPluginApi", + "section": "def-public.FieldStatsServices", + "text": "FieldStatsServices" + } + ], + "path": "src/plugins/unified_field_list/public/components/field_stats/field_stats.tsx", + "deprecated": false + }, + { + "parentPluginId": "unifiedFieldList", + "id": "def-public.FieldStatsProps.query", + "type": "CompoundType", + "tags": [], + "label": "query", + "description": [], + "signature": [ + "Query", + " | ", + "AggregateQuery" + ], + "path": "src/plugins/unified_field_list/public/components/field_stats/field_stats.tsx", + "deprecated": false + }, + { + "parentPluginId": "unifiedFieldList", + "id": "def-public.FieldStatsProps.filters", + "type": "Array", + "tags": [], + "label": "filters", + "description": [], + "signature": [ + "Filter", + "[]" + ], + "path": "src/plugins/unified_field_list/public/components/field_stats/field_stats.tsx", + "deprecated": false + }, + { + "parentPluginId": "unifiedFieldList", + "id": "def-public.FieldStatsProps.fromDate", + "type": "string", + "tags": [], + "label": "fromDate", + "description": [], + "path": "src/plugins/unified_field_list/public/components/field_stats/field_stats.tsx", + "deprecated": false + }, + { + "parentPluginId": "unifiedFieldList", + "id": "def-public.FieldStatsProps.toDate", + "type": "string", + "tags": [], + "label": "toDate", + "description": [], + "path": "src/plugins/unified_field_list/public/components/field_stats/field_stats.tsx", + "deprecated": false + }, + { + "parentPluginId": "unifiedFieldList", + "id": "def-public.FieldStatsProps.dataViewOrDataViewId", + "type": "CompoundType", + "tags": [], + "label": "dataViewOrDataViewId", + "description": [], + "signature": [ + "string | ", + { + "pluginId": "dataViews", + "scope": "common", + "docId": "kibDataViewsPluginApi", + "section": "def-common.DataView", + "text": "DataView" + } + ], + "path": "src/plugins/unified_field_list/public/components/field_stats/field_stats.tsx", + "deprecated": false + }, + { + "parentPluginId": "unifiedFieldList", + "id": "def-public.FieldStatsProps.field", + "type": "Object", + "tags": [], + "label": "field", + "description": [], + "signature": [ + { + "pluginId": "dataViews", + "scope": "common", + "docId": "kibDataViewsPluginApi", + "section": "def-common.DataViewField", + "text": "DataViewField" + } + ], + "path": "src/plugins/unified_field_list/public/components/field_stats/field_stats.tsx", + "deprecated": false + }, + { + "parentPluginId": "unifiedFieldList", + "id": "def-public.FieldStatsProps.datatestsubj", + "type": "string", + "tags": [], + "label": "'data-test-subj'", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "src/plugins/unified_field_list/public/components/field_stats/field_stats.tsx", + "deprecated": false + }, + { + "parentPluginId": "unifiedFieldList", + "id": "def-public.FieldStatsProps.overrideMissingContent", + "type": "Function", + "tags": [], + "label": "overrideMissingContent", + "description": [], + "signature": [ + "((params?: { noDataFound?: boolean | undefined; } | undefined) => JSX.Element | null) | undefined" + ], + "path": "src/plugins/unified_field_list/public/components/field_stats/field_stats.tsx", + "deprecated": false, + "children": [ + { + "parentPluginId": "unifiedFieldList", + "id": "def-public.FieldStatsProps.overrideMissingContent.$1", + "type": "Object", + "tags": [], + "label": "params", + "description": [], + "path": "src/plugins/unified_field_list/public/components/field_stats/field_stats.tsx", + "deprecated": false, + "children": [ + { + "parentPluginId": "unifiedFieldList", + "id": "def-public.FieldStatsProps.overrideMissingContent.$1.noDataFound", + "type": "CompoundType", + "tags": [], + "label": "noDataFound", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "src/plugins/unified_field_list/public/components/field_stats/field_stats.tsx", + "deprecated": false + } + ] + } + ], + "returnComment": [] + }, + { + "parentPluginId": "unifiedFieldList", + "id": "def-public.FieldStatsProps.overrideFooter", + "type": "Function", + "tags": [], + "label": "overrideFooter", + "description": [], + "signature": [ + "((params: { element: JSX.Element; totalDocuments?: number | undefined; sampledDocuments?: number | undefined; }) => JSX.Element) | undefined" + ], + "path": "src/plugins/unified_field_list/public/components/field_stats/field_stats.tsx", + "deprecated": false, + "children": [ + { + "parentPluginId": "unifiedFieldList", + "id": "def-public.FieldStatsProps.overrideFooter.$1", + "type": "Object", + "tags": [], + "label": "params", + "description": [], + "path": "src/plugins/unified_field_list/public/components/field_stats/field_stats.tsx", + "deprecated": false, + "children": [ + { + "parentPluginId": "unifiedFieldList", + "id": "def-public.FieldStatsProps.overrideFooter.$1.element", + "type": "Object", + "tags": [], + "label": "element", + "description": [], + "signature": [ + "JSX.Element" + ], + "path": "src/plugins/unified_field_list/public/components/field_stats/field_stats.tsx", + "deprecated": false + }, + { + "parentPluginId": "unifiedFieldList", + "id": "def-public.FieldStatsProps.overrideFooter.$1.totalDocuments", + "type": "number", + "tags": [], + "label": "totalDocuments", + "description": [], + "signature": [ + "number | undefined" + ], + "path": "src/plugins/unified_field_list/public/components/field_stats/field_stats.tsx", + "deprecated": false + }, + { + "parentPluginId": "unifiedFieldList", + "id": "def-public.FieldStatsProps.overrideFooter.$1.sampledDocuments", + "type": "number", + "tags": [], + "label": "sampledDocuments", + "description": [], + "signature": [ + "number | undefined" + ], + "path": "src/plugins/unified_field_list/public/components/field_stats/field_stats.tsx", + "deprecated": false + } + ] + } + ], + "returnComment": [] + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "unifiedFieldList", + "id": "def-public.FieldStatsResponse", + "type": "Interface", + "tags": [], + "label": "FieldStatsResponse", + "description": [], + "signature": [ + "FieldStatsResponse", + "" + ], + "path": "src/plugins/unified_field_list/common/types/stats.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "unifiedFieldList", + "id": "def-public.FieldStatsResponse.totalDocuments", + "type": "number", + "tags": [], + "label": "totalDocuments", + "description": [], + "signature": [ + "number | undefined" + ], + "path": "src/plugins/unified_field_list/common/types/stats.ts", + "deprecated": false + }, + { + "parentPluginId": "unifiedFieldList", + "id": "def-public.FieldStatsResponse.sampledDocuments", + "type": "number", + "tags": [], + "label": "sampledDocuments", + "description": [], + "signature": [ + "number | undefined" + ], + "path": "src/plugins/unified_field_list/common/types/stats.ts", + "deprecated": false + }, + { + "parentPluginId": "unifiedFieldList", + "id": "def-public.FieldStatsResponse.sampledValues", + "type": "number", + "tags": [], + "label": "sampledValues", + "description": [], + "signature": [ + "number | undefined" + ], + "path": "src/plugins/unified_field_list/common/types/stats.ts", + "deprecated": false + }, + { + "parentPluginId": "unifiedFieldList", + "id": "def-public.FieldStatsResponse.histogram", + "type": "Object", + "tags": [], + "label": "histogram", + "description": [], + "signature": [ + "BucketedAggregation", + " | undefined" + ], + "path": "src/plugins/unified_field_list/common/types/stats.ts", + "deprecated": false + }, + { + "parentPluginId": "unifiedFieldList", + "id": "def-public.FieldStatsResponse.topValues", + "type": "Object", + "tags": [], + "label": "topValues", + "description": [], + "signature": [ + "BucketedAggregation", + " | undefined" + ], + "path": "src/plugins/unified_field_list/common/types/stats.ts", + "deprecated": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "unifiedFieldList", + "id": "def-public.FieldStatsServices", + "type": "Interface", + "tags": [], + "label": "FieldStatsServices", + "description": [], + "path": "src/plugins/unified_field_list/public/components/field_stats/field_stats.tsx", + "deprecated": false, + "children": [ + { + "parentPluginId": "unifiedFieldList", + "id": "def-public.FieldStatsServices.uiSettings", + "type": "Object", + "tags": [], + "label": "uiSettings", + "description": [], + "signature": [ + "IUiSettingsClient" + ], + "path": "src/plugins/unified_field_list/public/components/field_stats/field_stats.tsx", + "deprecated": false + }, + { + "parentPluginId": "unifiedFieldList", + "id": "def-public.FieldStatsServices.dataViews", + "type": "Object", + "tags": [], + "label": "dataViews", + "description": [], + "signature": [ + { + "pluginId": "dataViews", + "scope": "public", + "docId": "kibDataViewsPluginApi", + "section": "def-public.DataViewsServicePublic", + "text": "DataViewsServicePublic" + } + ], + "path": "src/plugins/unified_field_list/public/components/field_stats/field_stats.tsx", + "deprecated": false + }, + { + "parentPluginId": "unifiedFieldList", + "id": "def-public.FieldStatsServices.data", + "type": "Object", + "tags": [], + "label": "data", + "description": [], + "signature": [ + { + "pluginId": "data", + "scope": "public", + "docId": "kibDataPluginApi", + "section": "def-public.DataPublicPluginStart", + "text": "DataPublicPluginStart" + } + ], + "path": "src/plugins/unified_field_list/public/components/field_stats/field_stats.tsx", + "deprecated": false + }, + { + "parentPluginId": "unifiedFieldList", + "id": "def-public.FieldStatsServices.fieldFormats", + "type": "CompoundType", + "tags": [], + "label": "fieldFormats", + "description": [], + "signature": [ + "Omit<", + { + "pluginId": "fieldFormats", + "scope": "common", + "docId": "kibFieldFormatsPluginApi", + "section": "def-common.FieldFormatsRegistry", + "text": "FieldFormatsRegistry" + }, + ", \"init\" | \"register\"> & { deserialize: ", + { + "pluginId": "fieldFormats", + "scope": "common", + "docId": "kibFieldFormatsPluginApi", + "section": "def-common.FormatFactory", + "text": "FormatFactory" + }, + "; }" + ], + "path": "src/plugins/unified_field_list/public/components/field_stats/field_stats.tsx", + "deprecated": false + }, + { + "parentPluginId": "unifiedFieldList", + "id": "def-public.FieldStatsServices.charts", + "type": "Object", + "tags": [], + "label": "charts", + "description": [], + "signature": [ + { + "pluginId": "charts", + "scope": "public", + "docId": "kibChartsPluginApi", + "section": "def-public.ChartsPluginSetup", + "text": "ChartsPluginSetup" + } + ], + "path": "src/plugins/unified_field_list/public/components/field_stats/field_stats.tsx", + "deprecated": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "unifiedFieldList", + "id": "def-public.NumberStatsResult", + "type": "Interface", + "tags": [], + "label": "NumberStatsResult", + "description": [], + "path": "src/plugins/unified_field_list/common/types/stats.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "unifiedFieldList", + "id": "def-public.NumberStatsResult.count", + "type": "number", + "tags": [], + "label": "count", + "description": [], + "path": "src/plugins/unified_field_list/common/types/stats.ts", + "deprecated": false + }, + { + "parentPluginId": "unifiedFieldList", + "id": "def-public.NumberStatsResult.histogram", + "type": "Object", + "tags": [], + "label": "histogram", + "description": [], + "signature": [ + "BucketedAggregation", + "" + ], + "path": "src/plugins/unified_field_list/common/types/stats.ts", + "deprecated": false + }, + { + "parentPluginId": "unifiedFieldList", + "id": "def-public.NumberStatsResult.topValues", + "type": "Object", + "tags": [], + "label": "topValues", + "description": [], + "signature": [ + "BucketedAggregation", + "" + ], + "path": "src/plugins/unified_field_list/common/types/stats.ts", + "deprecated": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "unifiedFieldList", + "id": "def-public.TopValuesResult", + "type": "Interface", + "tags": [], + "label": "TopValuesResult", + "description": [], + "path": "src/plugins/unified_field_list/common/types/stats.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "unifiedFieldList", + "id": "def-public.TopValuesResult.count", + "type": "number", + "tags": [], + "label": "count", + "description": [], + "path": "src/plugins/unified_field_list/common/types/stats.ts", + "deprecated": false + }, + { + "parentPluginId": "unifiedFieldList", + "id": "def-public.TopValuesResult.topValues", + "type": "Object", + "tags": [], + "label": "topValues", + "description": [], + "signature": [ + "BucketedAggregation", + "" + ], + "path": "src/plugins/unified_field_list/common/types/stats.ts", + "deprecated": false + } + ], + "initialIsOpen": false + } + ], + "enums": [], + "misc": [], + "objects": [], + "setup": { + "parentPluginId": "unifiedFieldList", + "id": "def-public.UnifiedFieldListPluginSetup", + "type": "Interface", + "tags": [], + "label": "UnifiedFieldListPluginSetup", + "description": [], + "path": "src/plugins/unified_field_list/public/types.ts", + "deprecated": false, + "children": [], + "lifecycle": "setup", + "initialIsOpen": true + }, + "start": { + "parentPluginId": "unifiedFieldList", + "id": "def-public.UnifiedFieldListPluginStart", + "type": "Interface", + "tags": [], + "label": "UnifiedFieldListPluginStart", + "description": [], + "path": "src/plugins/unified_field_list/public/types.ts", + "deprecated": false, + "children": [], + "lifecycle": "start", + "initialIsOpen": true + } + }, + "server": { + "classes": [], + "functions": [], + "interfaces": [ + { + "parentPluginId": "unifiedFieldList", + "id": "def-server.PluginSetup", + "type": "Interface", + "tags": [], + "label": "PluginSetup", + "description": [], + "path": "src/plugins/unified_field_list/server/types.ts", + "deprecated": false, + "children": [], + "initialIsOpen": false + }, + { + "parentPluginId": "unifiedFieldList", + "id": "def-server.PluginStart", + "type": "Interface", + "tags": [], + "label": "PluginStart", + "description": [], + "path": "src/plugins/unified_field_list/server/types.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "unifiedFieldList", + "id": "def-server.PluginStart.dataViews", + "type": "Object", + "tags": [], + "label": "dataViews", + "description": [], + "signature": [ + { + "pluginId": "dataViews", + "scope": "server", + "docId": "kibDataViewsPluginApi", + "section": "def-server.DataViewsServerPluginStart", + "text": "DataViewsServerPluginStart" + } + ], + "path": "src/plugins/unified_field_list/server/types.ts", + "deprecated": false + } + ], + "initialIsOpen": false + } + ], + "enums": [], + "misc": [], + "objects": [], + "setup": { + "parentPluginId": "unifiedFieldList", + "id": "def-server.UnifiedFieldListServerPluginSetup", + "type": "Interface", + "tags": [], + "label": "UnifiedFieldListServerPluginSetup", + "description": [], + "path": "src/plugins/unified_field_list/server/types.ts", + "deprecated": false, + "children": [], + "lifecycle": "setup", + "initialIsOpen": true + }, + "start": { + "parentPluginId": "unifiedFieldList", + "id": "def-server.UnifiedFieldListServerPluginStart", + "type": "Interface", + "tags": [], + "label": "UnifiedFieldListServerPluginStart", + "description": [], + "path": "src/plugins/unified_field_list/server/types.ts", + "deprecated": false, + "children": [], + "lifecycle": "start", + "initialIsOpen": true + } + }, + "common": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [ + { + "parentPluginId": "unifiedFieldList", + "id": "def-common.PLUGIN_ID", + "type": "string", + "tags": [], + "label": "PLUGIN_ID", + "description": [], + "signature": [ + "\"unifiedFieldList\"" + ], + "path": "src/plugins/unified_field_list/common/index.ts", + "deprecated": false, + "initialIsOpen": false + } + ], + "objects": [] + } +} \ No newline at end of file diff --git a/api_docs/unified_field_list.mdx b/api_docs/unified_field_list.mdx new file mode 100644 index 00000000000000..5bd1ebca1d1aa2 --- /dev/null +++ b/api_docs/unified_field_list.mdx @@ -0,0 +1,55 @@ +--- +#### +#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system. +#### Reach out in #docs-engineering for more info. +#### +id: kibUnifiedFieldListPluginApi +slug: /kibana-dev-docs/api/unifiedFieldList +title: "unifiedFieldList" +image: https://source.unsplash.com/400x175/?github +description: API docs for the unifiedFieldList plugin +date: 2022-08-24 +tags: ['contributor', 'dev', 'apidocs', 'kibana', 'unifiedFieldList'] +--- +import unifiedFieldListObj from './unified_field_list.devdocs.json'; + +Contains functionality for the field list which can be integrated into apps + +Contact [Data Discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) for questions regarding this plugin. + +**Code health stats** + +| Public API count | Any count | Items lacking comments | Missing exports | +|-------------------|-----------|------------------------|-----------------| +| 51 | 0 | 49 | 2 | + +## Client + +### Setup + + +### Start + + +### Functions + + +### Interfaces + + +## Server + +### Setup + + +### Start + + +### Interfaces + + +## Common + +### Consts, variables and types + + diff --git a/api_docs/unified_search.devdocs.json b/api_docs/unified_search.devdocs.json index 86e9771981ed85..2e8d4636df6816 100644 --- a/api_docs/unified_search.devdocs.json +++ b/api_docs/unified_search.devdocs.json @@ -407,12 +407,35 @@ { "parentPluginId": "unifiedSearch", "id": "def-public.ApplyGlobalFilterActionContext.embeddable", - "type": "Unknown", + "type": "Object", "tags": [], "label": "embeddable", "description": [], "signature": [ - "unknown" + { + "pluginId": "embeddable", + "scope": "public", + "docId": "kibEmbeddablePluginApi", + "section": "def-public.IEmbeddable", + "text": "IEmbeddable" + }, + "<", + { + "pluginId": "embeddable", + "scope": "common", + "docId": "kibEmbeddablePluginApi", + "section": "def-common.EmbeddableInput", + "text": "EmbeddableInput" + }, + ", ", + { + "pluginId": "embeddable", + "scope": "public", + "docId": "kibEmbeddablePluginApi", + "section": "def-public.EmbeddableOutput", + "text": "EmbeddableOutput" + }, + "> | undefined" ], "path": "src/plugins/unified_search/public/actions/apply_filter_action.ts", "deprecated": false diff --git a/api_docs/unified_search.mdx b/api_docs/unified_search.mdx index f587daed71aed0..b5e41f171145fb 100644 --- a/api_docs/unified_search.mdx +++ b/api_docs/unified_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/unifiedSearch title: "unifiedSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the unifiedSearch plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'unifiedSearch'] --- import unifiedSearchObj from './unified_search.devdocs.json'; diff --git a/api_docs/unified_search_autocomplete.mdx b/api_docs/unified_search_autocomplete.mdx index 60d19fbdd05dfd..a252efc8d8df69 100644 --- a/api_docs/unified_search_autocomplete.mdx +++ b/api_docs/unified_search_autocomplete.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/unifiedSearch-autocomplete title: "unifiedSearch.autocomplete" image: https://source.unsplash.com/400x175/?github description: API docs for the unifiedSearch.autocomplete plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'unifiedSearch.autocomplete'] --- import unifiedSearchAutocompleteObj from './unified_search_autocomplete.devdocs.json'; diff --git a/api_docs/url_forwarding.mdx b/api_docs/url_forwarding.mdx index 0fbf57c9a3b1c7..e1f6c1e362e927 100644 --- a/api_docs/url_forwarding.mdx +++ b/api_docs/url_forwarding.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/urlForwarding title: "urlForwarding" image: https://source.unsplash.com/400x175/?github description: API docs for the urlForwarding plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'urlForwarding'] --- import urlForwardingObj from './url_forwarding.devdocs.json'; diff --git a/api_docs/usage_collection.devdocs.json b/api_docs/usage_collection.devdocs.json index 40cf1b6dde66bf..fc4e370e41c2ff 100644 --- a/api_docs/usage_collection.devdocs.json +++ b/api_docs/usage_collection.devdocs.json @@ -378,7 +378,9 @@ "TransportRequestOptions", " | undefined): Promise<", "WriteResponseBase", - ">; }; name: string | symbol; transform: ", + ">; }; cluster: ", + "default", + "; eql: ", "default", "; search: { >; }; cluster: ", - "default", - "; eql: ", - "default", - "; create: { (this: That, params: ", + ">; }; create: { (this: That, params: ", "CreateRequest", " | ", "CreateRequest", @@ -446,7 +444,7 @@ "default", "; security: ", "default", - "; index: { (this: That, params: ", + "; name: string | symbol; index: { (this: That, params: ", "IndexRequest", " | ", "IndexRequest", @@ -1458,6 +1456,8 @@ "TermvectorsResponse", ">; }; textStructure: ", "default", + "; transform: ", + "default", "; updateByQuery: { (this: That, params: ", "UpdateByQueryRequest", " | ", @@ -1866,7 +1866,7 @@ "\nPossible type values in the schema" ], "signature": [ - "\"boolean\" | \"date\" | \"text\" | \"keyword\" | \"long\" | \"double\" | \"short\" | \"float\" | \"integer\" | \"byte\"" + "\"boolean\" | \"date\" | \"keyword\" | \"text\" | \"long\" | \"double\" | \"short\" | \"float\" | \"integer\" | \"byte\"" ], "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false, diff --git a/api_docs/usage_collection.mdx b/api_docs/usage_collection.mdx index 5fe2987e102cc0..3ce7b1d8423e04 100644 --- a/api_docs/usage_collection.mdx +++ b/api_docs/usage_collection.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/usageCollection title: "usageCollection" image: https://source.unsplash.com/400x175/?github description: API docs for the usageCollection plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'usageCollection'] --- import usageCollectionObj from './usage_collection.devdocs.json'; diff --git a/api_docs/ux.mdx b/api_docs/ux.mdx index 37a7714a4e7b48..54bac6a92c15bb 100644 --- a/api_docs/ux.mdx +++ b/api_docs/ux.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ux title: "ux" image: https://source.unsplash.com/400x175/?github description: API docs for the ux plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ux'] --- import uxObj from './ux.devdocs.json'; diff --git a/api_docs/vis_default_editor.mdx b/api_docs/vis_default_editor.mdx index 6d8ca7f5961cf3..f2f3cbaa04cf2c 100644 --- a/api_docs/vis_default_editor.mdx +++ b/api_docs/vis_default_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visDefaultEditor title: "visDefaultEditor" image: https://source.unsplash.com/400x175/?github description: API docs for the visDefaultEditor plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visDefaultEditor'] --- import visDefaultEditorObj from './vis_default_editor.devdocs.json'; diff --git a/api_docs/vis_type_gauge.mdx b/api_docs/vis_type_gauge.mdx index 7aab904cd13199..010a546d6b23f8 100644 --- a/api_docs/vis_type_gauge.mdx +++ b/api_docs/vis_type_gauge.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeGauge title: "visTypeGauge" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeGauge plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeGauge'] --- import visTypeGaugeObj from './vis_type_gauge.devdocs.json'; diff --git a/api_docs/vis_type_heatmap.mdx b/api_docs/vis_type_heatmap.mdx index 44f1a6baae1965..e403692b60c3f3 100644 --- a/api_docs/vis_type_heatmap.mdx +++ b/api_docs/vis_type_heatmap.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeHeatmap title: "visTypeHeatmap" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeHeatmap plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeHeatmap'] --- import visTypeHeatmapObj from './vis_type_heatmap.devdocs.json'; diff --git a/api_docs/vis_type_pie.mdx b/api_docs/vis_type_pie.mdx index 8a465bc7ee69ac..5f3958c375bbb4 100644 --- a/api_docs/vis_type_pie.mdx +++ b/api_docs/vis_type_pie.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypePie title: "visTypePie" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypePie plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypePie'] --- import visTypePieObj from './vis_type_pie.devdocs.json'; diff --git a/api_docs/vis_type_table.mdx b/api_docs/vis_type_table.mdx index 32f4bdb9497f55..001d4358b53718 100644 --- a/api_docs/vis_type_table.mdx +++ b/api_docs/vis_type_table.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeTable title: "visTypeTable" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeTable plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeTable'] --- import visTypeTableObj from './vis_type_table.devdocs.json'; diff --git a/api_docs/vis_type_timelion.mdx b/api_docs/vis_type_timelion.mdx index cad876e4766ced..8b461616d3953e 100644 --- a/api_docs/vis_type_timelion.mdx +++ b/api_docs/vis_type_timelion.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeTimelion title: "visTypeTimelion" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeTimelion plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeTimelion'] --- import visTypeTimelionObj from './vis_type_timelion.devdocs.json'; diff --git a/api_docs/vis_type_timeseries.mdx b/api_docs/vis_type_timeseries.mdx index 7cd2847cc5643e..094294832f1a5a 100644 --- a/api_docs/vis_type_timeseries.mdx +++ b/api_docs/vis_type_timeseries.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeTimeseries title: "visTypeTimeseries" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeTimeseries plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeTimeseries'] --- import visTypeTimeseriesObj from './vis_type_timeseries.devdocs.json'; diff --git a/api_docs/vis_type_vega.mdx b/api_docs/vis_type_vega.mdx index d63b7b4d5165f3..16965d2c480237 100644 --- a/api_docs/vis_type_vega.mdx +++ b/api_docs/vis_type_vega.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeVega title: "visTypeVega" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeVega plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeVega'] --- import visTypeVegaObj from './vis_type_vega.devdocs.json'; diff --git a/api_docs/vis_type_vislib.mdx b/api_docs/vis_type_vislib.mdx index dd32c514345343..44c7f9c0060907 100644 --- a/api_docs/vis_type_vislib.mdx +++ b/api_docs/vis_type_vislib.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeVislib title: "visTypeVislib" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeVislib plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeVislib'] --- import visTypeVislibObj from './vis_type_vislib.devdocs.json'; diff --git a/api_docs/vis_type_xy.devdocs.json b/api_docs/vis_type_xy.devdocs.json index 26e0033116122d..ec7c7d42c4201c 100644 --- a/api_docs/vis_type_xy.devdocs.json +++ b/api_docs/vis_type_xy.devdocs.json @@ -3,39 +3,6 @@ "client": { "classes": [], "functions": [ - { - "parentPluginId": "visTypeXy", - "id": "def-public.getAggId", - "type": "Function", - "tags": [], - "label": "getAggId", - "description": [ - "\nGet agg id from accessor\n\nFor now this is determined by the esaggs column name. Could be cleaned up in the future." - ], - "signature": [ - "(accessor: string) => string" - ], - "path": "src/plugins/vis_types/xy/public/config/get_agg_id.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "visTypeXy", - "id": "def-public.getAggId.$1", - "type": "string", - "tags": [], - "label": "accessor", - "description": [], - "signature": [ - "string" - ], - "path": "src/plugins/vis_types/xy/public/config/get_agg_id.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [], - "initialIsOpen": false - }, { "parentPluginId": "visTypeXy", "id": "def-public.getPositions", @@ -824,29 +791,6 @@ "path": "src/plugins/vis_types/xy/public/types/param.ts", "deprecated": false, "initialIsOpen": false - }, - { - "parentPluginId": "visTypeXy", - "id": "def-public.XyVisType", - "type": "Type", - "tags": [], - "label": "XyVisType", - "description": [ - "\nType of xy visualizations" - ], - "signature": [ - { - "pluginId": "visTypeXy", - "scope": "common", - "docId": "kibVisTypeXyPluginApi", - "section": "def-common.ChartType", - "text": "ChartType" - }, - " | \"horizontal_bar\"" - ], - "path": "src/plugins/vis_types/xy/common/index.ts", - "deprecated": false, - "initialIsOpen": false } ], "objects": [], @@ -891,31 +835,7 @@ "initialIsOpen": false } ], - "misc": [ - { - "parentPluginId": "visTypeXy", - "id": "def-common.XyVisType", - "type": "Type", - "tags": [], - "label": "XyVisType", - "description": [ - "\nType of xy visualizations" - ], - "signature": [ - { - "pluginId": "visTypeXy", - "scope": "common", - "docId": "kibVisTypeXyPluginApi", - "section": "def-common.ChartType", - "text": "ChartType" - }, - " | \"horizontal_bar\"" - ], - "path": "src/plugins/vis_types/xy/common/index.ts", - "deprecated": false, - "initialIsOpen": false - } - ], + "misc": [], "objects": [] } } \ No newline at end of file diff --git a/api_docs/vis_type_xy.mdx b/api_docs/vis_type_xy.mdx index ff8587505bfbe6..90cc3549dc2a0e 100644 --- a/api_docs/vis_type_xy.mdx +++ b/api_docs/vis_type_xy.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeXy title: "visTypeXy" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeXy plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeXy'] --- import visTypeXyObj from './vis_type_xy.devdocs.json'; @@ -21,7 +21,7 @@ Contact [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 57 | 0 | 51 | 5 | +| 53 | 0 | 50 | 5 | ## Client @@ -45,6 +45,3 @@ Contact [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) ### Enums -### Consts, variables and types - - diff --git a/api_docs/visualizations.devdocs.json b/api_docs/visualizations.devdocs.json index 5931d92077178d..15691cacaad280 100644 --- a/api_docs/visualizations.devdocs.json +++ b/api_docs/visualizations.devdocs.json @@ -99,6 +99,14 @@ "section": "def-common.VisParams", "text": "VisParams" }, + " | undefined, timeRange?: ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataQueryPluginApi", + "section": "def-common.TimeRange", + "text": "TimeRange" + }, " | undefined) => Promise<", { "pluginId": "visualizations", @@ -977,79 +985,683 @@ }, { "parentPluginId": "visualizations", - "id": "def-public.Vis.data", - "type": "Object", + "id": "def-public.Vis.data", + "type": "Object", + "tags": [], + "label": "data", + "description": [], + "path": "src/plugins/visualizations/public/vis.ts", + "deprecated": false, + "children": [] + }, + { + "parentPluginId": "visualizations", + "id": "def-public.Vis.uiState", + "type": "Object", + "tags": [], + "label": "uiState", + "description": [], + "signature": [ + { + "pluginId": "visualizations", + "scope": "public", + "docId": "kibVisualizationsPluginApi", + "section": "def-public.PersistedState", + "text": "PersistedState" + } + ], + "path": "src/plugins/visualizations/public/vis.ts", + "deprecated": false + }, + { + "parentPluginId": "visualizations", + "id": "def-public.Vis.Unnamed", + "type": "Function", + "tags": [], + "label": "Constructor", + "description": [], + "signature": [ + "any" + ], + "path": "src/plugins/visualizations/public/vis.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "visualizations", + "id": "def-public.Vis.Unnamed.$1", + "type": "string", + "tags": [], + "label": "visType", + "description": [], + "signature": [ + "string" + ], + "path": "src/plugins/visualizations/public/vis.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "visualizations", + "id": "def-public.Vis.Unnamed.$2", + "type": "Object", + "tags": [], + "label": "visState", + "description": [], + "signature": [ + { + "pluginId": "visualizations", + "scope": "common", + "docId": "kibVisualizationsPluginApi", + "section": "def-common.SerializedVis", + "text": "SerializedVis" + }, + "" + ], + "path": "src/plugins/visualizations/public/vis.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "visualizations", + "id": "def-public.Vis.setState", + "type": "Function", + "tags": [], + "label": "setState", + "description": [], + "signature": [ + "(inState: PartialVisState) => Promise" + ], + "path": "src/plugins/visualizations/public/vis.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "visualizations", + "id": "def-public.Vis.setState.$1", + "type": "Object", + "tags": [], + "label": "inState", + "description": [], + "signature": [ + "PartialVisState" + ], + "path": "src/plugins/visualizations/public/vis.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "visualizations", + "id": "def-public.Vis.clone", + "type": "Function", + "tags": [], + "label": "clone", + "description": [], + "signature": [ + "() => ", + { + "pluginId": "visualizations", + "scope": "public", + "docId": "kibVisualizationsPluginApi", + "section": "def-public.Vis", + "text": "Vis" + }, + "" + ], + "path": "src/plugins/visualizations/public/vis.ts", + "deprecated": false, + "children": [], + "returnComment": [] + }, + { + "parentPluginId": "visualizations", + "id": "def-public.Vis.serialize", + "type": "Function", + "tags": [], + "label": "serialize", + "description": [], + "signature": [ + "() => ", + { + "pluginId": "visualizations", + "scope": "common", + "docId": "kibVisualizationsPluginApi", + "section": "def-common.SerializedVis", + "text": "SerializedVis" + }, + "<", + { + "pluginId": "visualizations", + "scope": "common", + "docId": "kibVisualizationsPluginApi", + "section": "def-common.VisParams", + "text": "VisParams" + }, + ">" + ], + "path": "src/plugins/visualizations/public/vis.ts", + "deprecated": false, + "children": [], + "returnComment": [] + }, + { + "parentPluginId": "visualizations", + "id": "def-public.Vis.isHierarchical", + "type": "Function", + "tags": [], + "label": "isHierarchical", + "description": [], + "signature": [ + "() => boolean" + ], + "path": "src/plugins/visualizations/public/vis.ts", + "deprecated": false, + "children": [], + "returnComment": [] + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "visualizations", + "id": "def-public.VisualizeEmbeddable", + "type": "Class", + "tags": [], + "label": "VisualizeEmbeddable", + "description": [], + "signature": [ + { + "pluginId": "visualizations", + "scope": "public", + "docId": "kibVisualizationsPluginApi", + "section": "def-public.VisualizeEmbeddable", + "text": "VisualizeEmbeddable" + }, + " extends ", + { + "pluginId": "embeddable", + "scope": "public", + "docId": "kibEmbeddablePluginApi", + "section": "def-public.Embeddable", + "text": "Embeddable" + }, + "<", + { + "pluginId": "visualizations", + "scope": "public", + "docId": "kibVisualizationsPluginApi", + "section": "def-public.VisualizeInput", + "text": "VisualizeInput" + }, + ", ", + "VisualizeOutput", + "> implements ", + { + "pluginId": "embeddable", + "scope": "public", + "docId": "kibEmbeddablePluginApi", + "section": "def-public.ReferenceOrValueEmbeddable", + "text": "ReferenceOrValueEmbeddable" + }, + "<", + "VisualizeByValueInput", + ", ", + "VisualizeByReferenceInput", + ">,", + { + "pluginId": "embeddable", + "scope": "public", + "docId": "kibEmbeddablePluginApi", + "section": "def-public.FilterableEmbeddable", + "text": "FilterableEmbeddable" + } + ], + "path": "src/plugins/visualizations/public/embeddable/visualize_embeddable.tsx", + "deprecated": false, + "children": [ + { + "parentPluginId": "visualizations", + "id": "def-public.VisualizeEmbeddable.type", + "type": "string", + "tags": [], + "label": "type", + "description": [], + "signature": [ + "\"visualization\"" + ], + "path": "src/plugins/visualizations/public/embeddable/visualize_embeddable.tsx", + "deprecated": false + }, + { + "parentPluginId": "visualizations", + "id": "def-public.VisualizeEmbeddable.Unnamed", + "type": "Function", + "tags": [], + "label": "Constructor", + "description": [], + "signature": [ + "any" + ], + "path": "src/plugins/visualizations/public/embeddable/visualize_embeddable.tsx", + "deprecated": false, + "children": [ + { + "parentPluginId": "visualizations", + "id": "def-public.VisualizeEmbeddable.Unnamed.$1", + "type": "Object", + "tags": [], + "label": "timefilter", + "description": [], + "signature": [ + { + "pluginId": "data", + "scope": "public", + "docId": "kibDataQueryPluginApi", + "section": "def-public.TimefilterContract", + "text": "TimefilterContract" + } + ], + "path": "src/plugins/visualizations/public/embeddable/visualize_embeddable.tsx", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "visualizations", + "id": "def-public.VisualizeEmbeddable.Unnamed.$2", + "type": "Object", + "tags": [], + "label": "{ vis, editPath, editUrl, indexPatterns, deps, capabilities }", + "description": [], + "signature": [ + "VisualizeEmbeddableConfiguration" + ], + "path": "src/plugins/visualizations/public/embeddable/visualize_embeddable.tsx", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "visualizations", + "id": "def-public.VisualizeEmbeddable.Unnamed.$3", + "type": "Object", + "tags": [], + "label": "initialInput", + "description": [], + "signature": [ + { + "pluginId": "visualizations", + "scope": "public", + "docId": "kibVisualizationsPluginApi", + "section": "def-public.VisualizeInput", + "text": "VisualizeInput" + } + ], + "path": "src/plugins/visualizations/public/embeddable/visualize_embeddable.tsx", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "visualizations", + "id": "def-public.VisualizeEmbeddable.Unnamed.$4", + "type": "Object", + "tags": [], + "label": "attributeService", + "description": [], + "signature": [ + { + "pluginId": "embeddable", + "scope": "public", + "docId": "kibEmbeddablePluginApi", + "section": "def-public.AttributeService", + "text": "AttributeService" + }, + "<", + "VisualizeSavedObjectAttributes", + ", ", + "VisualizeByValueInput", + ", ", + "VisualizeByReferenceInput", + ", unknown> | undefined" + ], + "path": "src/plugins/visualizations/public/embeddable/visualize_embeddable.tsx", + "deprecated": false, + "isRequired": false + }, + { + "parentPluginId": "visualizations", + "id": "def-public.VisualizeEmbeddable.Unnamed.$5", + "type": "Object", + "tags": [], + "label": "parent", + "description": [], + "signature": [ + { + "pluginId": "embeddable", + "scope": "public", + "docId": "kibEmbeddablePluginApi", + "section": "def-public.IContainer", + "text": "IContainer" + }, + "<{}, ", + { + "pluginId": "embeddable", + "scope": "public", + "docId": "kibEmbeddablePluginApi", + "section": "def-public.ContainerInput", + "text": "ContainerInput" + }, + "<{}>, ", + { + "pluginId": "embeddable", + "scope": "public", + "docId": "kibEmbeddablePluginApi", + "section": "def-public.ContainerOutput", + "text": "ContainerOutput" + }, + "> | undefined" + ], + "path": "src/plugins/visualizations/public/embeddable/visualize_embeddable.tsx", + "deprecated": false, + "isRequired": false + } + ], + "returnComment": [] + }, + { + "parentPluginId": "visualizations", + "id": "def-public.VisualizeEmbeddable.reportsEmbeddableLoad", + "type": "Function", + "tags": [], + "label": "reportsEmbeddableLoad", + "description": [], + "signature": [ + "() => boolean" + ], + "path": "src/plugins/visualizations/public/embeddable/visualize_embeddable.tsx", + "deprecated": false, + "children": [], + "returnComment": [] + }, + { + "parentPluginId": "visualizations", + "id": "def-public.VisualizeEmbeddable.getDescription", + "type": "Function", + "tags": [], + "label": "getDescription", + "description": [], + "signature": [ + "() => string" + ], + "path": "src/plugins/visualizations/public/embeddable/visualize_embeddable.tsx", + "deprecated": false, + "children": [], + "returnComment": [] + }, + { + "parentPluginId": "visualizations", + "id": "def-public.VisualizeEmbeddable.getVis", + "type": "Function", + "tags": [], + "label": "getVis", + "description": [], + "signature": [ + "() => ", + { + "pluginId": "visualizations", + "scope": "public", + "docId": "kibVisualizationsPluginApi", + "section": "def-public.Vis", + "text": "Vis" + }, + "<", + { + "pluginId": "visualizations", + "scope": "common", + "docId": "kibVisualizationsPluginApi", + "section": "def-common.VisParams", + "text": "VisParams" + }, + ">" + ], + "path": "src/plugins/visualizations/public/embeddable/visualize_embeddable.tsx", + "deprecated": false, + "children": [], + "returnComment": [] + }, + { + "parentPluginId": "visualizations", + "id": "def-public.VisualizeEmbeddable.getFilters", + "type": "Function", + "tags": [], + "label": "getFilters", + "description": [ + "\nGets the Visualize embeddable's local filters" + ], + "signature": [ + "() => Promise<", + "Filter", + "[]>" + ], + "path": "src/plugins/visualizations/public/embeddable/visualize_embeddable.tsx", + "deprecated": false, + "children": [], + "returnComment": [ + "Local/panel-level array of filters for Visualize embeddable" + ] + }, + { + "parentPluginId": "visualizations", + "id": "def-public.VisualizeEmbeddable.getQuery", + "type": "Function", + "tags": [], + "label": "getQuery", + "description": [ + "\nGets the Visualize embeddable's local query" + ], + "signature": [ + "() => Promise<", + "Query", + " | ", + "AggregateQuery", + " | undefined>" + ], + "path": "src/plugins/visualizations/public/embeddable/visualize_embeddable.tsx", + "deprecated": false, + "children": [], + "returnComment": [ + "Local/panel-level query for Visualize embeddable" + ] + }, + { + "parentPluginId": "visualizations", + "id": "def-public.VisualizeEmbeddable.getInspectorAdapters", + "type": "Function", + "tags": [], + "label": "getInspectorAdapters", + "description": [], + "signature": [ + "() => ", + { + "pluginId": "inspector", + "scope": "common", + "docId": "kibInspectorPluginApi", + "section": "def-common.Adapters", + "text": "Adapters" + }, + " | undefined" + ], + "path": "src/plugins/visualizations/public/embeddable/visualize_embeddable.tsx", + "deprecated": false, + "children": [], + "returnComment": [] + }, + { + "parentPluginId": "visualizations", + "id": "def-public.VisualizeEmbeddable.openInspector", + "type": "Function", + "tags": [], + "label": "openInspector", + "description": [], + "signature": [ + "() => ", + "OverlayRef", + " | undefined" + ], + "path": "src/plugins/visualizations/public/embeddable/visualize_embeddable.tsx", + "deprecated": false, + "children": [], + "returnComment": [] + }, + { + "parentPluginId": "visualizations", + "id": "def-public.VisualizeEmbeddable.transferCustomizationsToUiState", + "type": "Function", + "tags": [], + "label": "transferCustomizationsToUiState", + "description": [ + "\nTransfers all changes in the containerState.customization into\nthe uiState of this visualization." + ], + "signature": [ + "() => void" + ], + "path": "src/plugins/visualizations/public/embeddable/visualize_embeddable.tsx", + "deprecated": false, + "children": [], + "returnComment": [] + }, + { + "parentPluginId": "visualizations", + "id": "def-public.VisualizeEmbeddable.hasInspector", + "type": "Function", + "tags": [], + "label": "hasInspector", + "description": [], + "signature": [ + "() => boolean" + ], + "path": "src/plugins/visualizations/public/embeddable/visualize_embeddable.tsx", + "deprecated": false, + "children": [], + "returnComment": [] + }, + { + "parentPluginId": "visualizations", + "id": "def-public.VisualizeEmbeddable.onContainerLoading", + "type": "Function", + "tags": [], + "label": "onContainerLoading", + "description": [], + "signature": [ + "() => void" + ], + "path": "src/plugins/visualizations/public/embeddable/visualize_embeddable.tsx", + "deprecated": false, + "children": [], + "returnComment": [] + }, + { + "parentPluginId": "visualizations", + "id": "def-public.VisualizeEmbeddable.onContainerData", + "type": "Function", "tags": [], - "label": "data", + "label": "onContainerData", "description": [], - "path": "src/plugins/visualizations/public/vis.ts", + "signature": [ + "() => void" + ], + "path": "src/plugins/visualizations/public/embeddable/visualize_embeddable.tsx", "deprecated": false, - "children": [] + "children": [], + "returnComment": [] }, { "parentPluginId": "visualizations", - "id": "def-public.Vis.uiState", - "type": "Object", + "id": "def-public.VisualizeEmbeddable.onContainerRender", + "type": "Function", "tags": [], - "label": "uiState", + "label": "onContainerRender", "description": [], "signature": [ - { - "pluginId": "visualizations", - "scope": "public", - "docId": "kibVisualizationsPluginApi", - "section": "def-public.PersistedState", - "text": "PersistedState" - } + "() => void" ], - "path": "src/plugins/visualizations/public/vis.ts", - "deprecated": false + "path": "src/plugins/visualizations/public/embeddable/visualize_embeddable.tsx", + "deprecated": false, + "children": [], + "returnComment": [] }, { "parentPluginId": "visualizations", - "id": "def-public.Vis.Unnamed", + "id": "def-public.VisualizeEmbeddable.onContainerError", "type": "Function", "tags": [], - "label": "Constructor", + "label": "onContainerError", "description": [], "signature": [ - "any" + "(error: ", + { + "pluginId": "expressions", + "scope": "public", + "docId": "kibExpressionsPluginApi", + "section": "def-public.ExpressionRenderError", + "text": "ExpressionRenderError" + }, + ") => void" ], - "path": "src/plugins/visualizations/public/vis.ts", + "path": "src/plugins/visualizations/public/embeddable/visualize_embeddable.tsx", "deprecated": false, "children": [ { "parentPluginId": "visualizations", - "id": "def-public.Vis.Unnamed.$1", - "type": "string", + "id": "def-public.VisualizeEmbeddable.onContainerError.$1", + "type": "Object", "tags": [], - "label": "visType", + "label": "error", "description": [], "signature": [ - "string" + { + "pluginId": "expressions", + "scope": "public", + "docId": "kibExpressionsPluginApi", + "section": "def-public.ExpressionRenderError", + "text": "ExpressionRenderError" + } ], - "path": "src/plugins/visualizations/public/vis.ts", + "path": "src/plugins/visualizations/public/embeddable/visualize_embeddable.tsx", "deprecated": false, "isRequired": true - }, + } + ], + "returnComment": [] + }, + { + "parentPluginId": "visualizations", + "id": "def-public.VisualizeEmbeddable.render", + "type": "Function", + "tags": [], + "label": "render", + "description": [ + "\n" + ], + "signature": [ + "(domNode: HTMLElement) => Promise" + ], + "path": "src/plugins/visualizations/public/embeddable/visualize_embeddable.tsx", + "deprecated": false, + "children": [ { "parentPluginId": "visualizations", - "id": "def-public.Vis.Unnamed.$2", + "id": "def-public.VisualizeEmbeddable.render.$1", "type": "Object", "tags": [], - "label": "visState", + "label": "domNode", "description": [], "signature": [ - { - "pluginId": "visualizations", - "scope": "common", - "docId": "kibVisualizationsPluginApi", - "section": "def-common.SerializedVis", - "text": "SerializedVis" - }, - "" + "HTMLElement" ], - "path": "src/plugins/visualizations/public/vis.ts", + "path": "src/plugins/visualizations/public/embeddable/visualize_embeddable.tsx", "deprecated": false, "isRequired": true } @@ -1058,28 +1670,57 @@ }, { "parentPluginId": "visualizations", - "id": "def-public.Vis.setState", + "id": "def-public.VisualizeEmbeddable.renderError", "type": "Function", "tags": [], - "label": "setState", + "label": "renderError", "description": [], "signature": [ - "(inState: PartialVisState) => Promise" + "(domNode: HTMLElement, error: string | ", + { + "pluginId": "expressions", + "scope": "common", + "docId": "kibExpressionsPluginApi", + "section": "def-common.ErrorLike", + "text": "ErrorLike" + }, + ") => () => boolean" ], - "path": "src/plugins/visualizations/public/vis.ts", + "path": "src/plugins/visualizations/public/embeddable/visualize_embeddable.tsx", "deprecated": false, "children": [ { "parentPluginId": "visualizations", - "id": "def-public.Vis.setState.$1", + "id": "def-public.VisualizeEmbeddable.renderError.$1", "type": "Object", "tags": [], - "label": "inState", + "label": "domNode", "description": [], "signature": [ - "PartialVisState" + "HTMLElement" ], - "path": "src/plugins/visualizations/public/vis.ts", + "path": "src/plugins/visualizations/public/embeddable/visualize_embeddable.tsx", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "visualizations", + "id": "def-public.VisualizeEmbeddable.renderError.$2", + "type": "CompoundType", + "tags": [], + "label": "error", + "description": [], + "signature": [ + "string | ", + { + "pluginId": "expressions", + "scope": "common", + "docId": "kibExpressionsPluginApi", + "section": "def-common.ErrorLike", + "text": "ErrorLike" + } + ], + "path": "src/plugins/visualizations/public/embeddable/visualize_embeddable.tsx", "deprecated": false, "isRequired": true } @@ -1088,69 +1729,124 @@ }, { "parentPluginId": "visualizations", - "id": "def-public.Vis.clone", + "id": "def-public.VisualizeEmbeddable.destroy", "type": "Function", "tags": [], - "label": "clone", + "label": "destroy", "description": [], "signature": [ - "() => ", - { - "pluginId": "visualizations", - "scope": "public", - "docId": "kibVisualizationsPluginApi", - "section": "def-public.Vis", - "text": "Vis" - }, - "" + "() => void" ], - "path": "src/plugins/visualizations/public/vis.ts", + "path": "src/plugins/visualizations/public/embeddable/visualize_embeddable.tsx", "deprecated": false, "children": [], "returnComment": [] }, { "parentPluginId": "visualizations", - "id": "def-public.Vis.serialize", + "id": "def-public.VisualizeEmbeddable.reload", "type": "Function", "tags": [], - "label": "serialize", + "label": "reload", "description": [], "signature": [ - "() => ", + "() => Promise" + ], + "path": "src/plugins/visualizations/public/embeddable/visualize_embeddable.tsx", + "deprecated": false, + "children": [], + "returnComment": [] + }, + { + "parentPluginId": "visualizations", + "id": "def-public.VisualizeEmbeddable.supportedTriggers", + "type": "Function", + "tags": [], + "label": "supportedTriggers", + "description": [], + "signature": [ + "() => string[]" + ], + "path": "src/plugins/visualizations/public/embeddable/visualize_embeddable.tsx", + "deprecated": false, + "children": [], + "returnComment": [] + }, + { + "parentPluginId": "visualizations", + "id": "def-public.VisualizeEmbeddable.inputIsRefType", + "type": "Function", + "tags": [], + "label": "inputIsRefType", + "description": [], + "signature": [ + "(input: ", { "pluginId": "visualizations", - "scope": "common", + "scope": "public", "docId": "kibVisualizationsPluginApi", - "section": "def-common.SerializedVis", - "text": "SerializedVis" + "section": "def-public.VisualizeInput", + "text": "VisualizeInput" }, - "<", + ") => input is ", + "VisualizeByReferenceInput" + ], + "path": "src/plugins/visualizations/public/embeddable/visualize_embeddable.tsx", + "deprecated": false, + "children": [ { - "pluginId": "visualizations", - "scope": "common", - "docId": "kibVisualizationsPluginApi", - "section": "def-common.VisParams", - "text": "VisParams" - }, + "parentPluginId": "visualizations", + "id": "def-public.VisualizeEmbeddable.inputIsRefType.$1", + "type": "Object", + "tags": [], + "label": "input", + "description": [], + "signature": [ + { + "pluginId": "visualizations", + "scope": "public", + "docId": "kibVisualizationsPluginApi", + "section": "def-public.VisualizeInput", + "text": "VisualizeInput" + } + ], + "path": "src/plugins/visualizations/public/embeddable/visualize_embeddable.tsx", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "visualizations", + "id": "def-public.VisualizeEmbeddable.getInputAsValueType", + "type": "Function", + "tags": [], + "label": "getInputAsValueType", + "description": [], + "signature": [ + "() => Promise<", + "VisualizeByValueInput", ">" ], - "path": "src/plugins/visualizations/public/vis.ts", + "path": "src/plugins/visualizations/public/embeddable/visualize_embeddable.tsx", "deprecated": false, "children": [], "returnComment": [] }, { "parentPluginId": "visualizations", - "id": "def-public.Vis.isHierarchical", + "id": "def-public.VisualizeEmbeddable.getInputAsRefType", "type": "Function", "tags": [], - "label": "isHierarchical", + "label": "getInputAsRefType", "description": [], "signature": [ - "() => boolean" + "() => Promise<", + "VisualizeByReferenceInput", + ">" ], - "path": "src/plugins/visualizations/public/vis.ts", + "path": "src/plugins/visualizations/public/embeddable/visualize_embeddable.tsx", "deprecated": false, "children": [], "returnComment": [] @@ -2182,7 +2878,7 @@ "label": "configuration", "description": [], "signature": [ - "{ fill: string | number; legend: { isVisible: boolean; position: string; shouldTruncate: boolean; maxLines: number; showSingleSeries: boolean; }; gridLinesVisibility: { x: boolean; yLeft: boolean; yRight: boolean; }; extents: { yLeftExtent: AxisExtents; yRightExtent: AxisExtents; }; }" + "{ fill: string | number; legend: { isVisible: boolean; position: string; shouldTruncate: boolean; maxLines: number; showSingleSeries: boolean; }; gridLinesVisibility: { x: boolean; yLeft: boolean; yRight: boolean; }; tickLabelsVisibility?: { x: boolean; yLeft: boolean; yRight: boolean; } | undefined; axisTitlesVisibility?: { x: boolean; yLeft: boolean; yRight: boolean; } | undefined; valueLabels?: boolean | undefined; extents?: { yLeftExtent: AxisExtents; yRightExtent: AxisExtents; } | undefined; }" ], "path": "src/plugins/visualizations/public/vis_types/types.ts", "deprecated": false @@ -3084,7 +3780,7 @@ "label": "getDisplayName", "description": [], "signature": [ - "(() => string) | undefined" + "() => string" ], "path": "src/plugins/visualizations/public/types.ts", "deprecated": false, @@ -3620,6 +4316,14 @@ "section": "def-common.VisParams", "text": "VisParams" }, + " | undefined, timeRange?: ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataQueryPluginApi", + "section": "def-common.TimeRange", + "text": "TimeRange" + }, " | undefined) => Promise<", { "pluginId": "visualizations", @@ -3653,6 +4357,27 @@ "path": "src/plugins/visualizations/public/vis_types/types.ts", "deprecated": false, "isRequired": false + }, + { + "parentPluginId": "visualizations", + "id": "def-public.VisTypeDefinition.navigateToLens.$2", + "type": "Object", + "tags": [], + "label": "timeRange", + "description": [], + "signature": [ + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataQueryPluginApi", + "section": "def-common.TimeRange", + "text": "TimeRange" + }, + " | undefined" + ], + "path": "src/plugins/visualizations/public/vis_types/types.ts", + "deprecated": false, + "isRequired": false } ], "returnComment": [] @@ -4451,10 +5176,23 @@ }, { "parentPluginId": "visualizations", - "id": "def-public.VisualizeEditorLayersContext.timeFieldName", + "id": "def-public.VisualizeEditorLayersContext.xFieldName", + "type": "string", + "tags": [], + "label": "xFieldName", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "src/plugins/visualizations/public/vis_types/types.ts", + "deprecated": false + }, + { + "parentPluginId": "visualizations", + "id": "def-public.VisualizeEditorLayersContext.xMode", "type": "string", "tags": [], - "label": "timeFieldName", + "label": "xMode", "description": [], "signature": [ "string | undefined" @@ -5125,7 +5863,7 @@ "label": "VisualizeEmbeddableContract", "description": [], "signature": [ - "{ readonly type: \"visualization\"; readonly id: string; render: (domNode: HTMLElement) => Promise; getExplicitInput: () => ", + "{ readonly type: \"visualization\"; render: (domNode: HTMLElement) => Promise; readonly id: string; getExplicitInput: () => ", { "pluginId": "visualizations", "scope": "public", @@ -5169,7 +5907,23 @@ "section": "def-public.VisualizeInput", "text": "VisualizeInput" }, - ">) => void; reportsEmbeddableLoad: () => boolean; getFilters: () => Promise<", + ">) => void; reportsEmbeddableLoad: () => boolean; getVis: () => ", + { + "pluginId": "visualizations", + "scope": "public", + "docId": "kibVisualizationsPluginApi", + "section": "def-public.Vis", + "text": "Vis" + }, + "<", + { + "pluginId": "visualizations", + "scope": "common", + "docId": "kibVisualizationsPluginApi", + "section": "def-common.VisParams", + "text": "VisParams" + }, + ">; getFilters: () => Promise<", "Filter", "[]>; getInspectorAdapters: () => ", { @@ -5335,7 +6089,9 @@ "section": "def-public.ContainerOutput", "text": "ContainerOutput" }, - ">; }" + ">; updateOutput: (outputChanges: Partial<", + "VisualizeOutput", + ">) => void; }" ], "path": "src/plugins/visualizations/public/index.ts", "deprecated": false, @@ -5442,7 +6198,13 @@ "text": "ErrorEmbeddable" }, " | ", - "VisualizeEmbeddable", + { + "pluginId": "visualizations", + "scope": "public", + "docId": "kibVisualizationsPluginApi", + "section": "def-public.VisualizeEmbeddable", + "text": "VisualizeEmbeddable" + }, " | ", "DisabledLabEmbeddable", " | undefined>; isEditable: () => Promise; getDisplayName: () => string; createFromSavedObject: (savedObjectId: string, input: Partial<", @@ -5486,7 +6248,13 @@ "text": "ErrorEmbeddable" }, " | ", - "VisualizeEmbeddable", + { + "pluginId": "visualizations", + "scope": "public", + "docId": "kibVisualizationsPluginApi", + "section": "def-public.VisualizeEmbeddable", + "text": "VisualizeEmbeddable" + }, " | ", "DisabledLabEmbeddable", ">; readonly savedObjectMetaData: ", @@ -5505,7 +6273,7 @@ "section": "def-public.OnSaveProps", "text": "OnSaveProps" }, - ") => Promise; }" + ") => Promise; }" ], "path": "src/plugins/visualizations/public/index.ts", "deprecated": false, diff --git a/api_docs/visualizations.mdx b/api_docs/visualizations.mdx index 80f26c07ef8acd..307638221da949 100644 --- a/api_docs/visualizations.mdx +++ b/api_docs/visualizations.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visualizations title: "visualizations" image: https://source.unsplash.com/400x175/?github description: API docs for the visualizations plugin -date: 2022-08-17 +date: 2022-08-24 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visualizations'] --- import visualizationsObj from './visualizations.devdocs.json'; @@ -21,7 +21,7 @@ Contact [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 380 | 12 | 356 | 14 | +| 416 | 12 | 388 | 15 | ## Client diff --git a/dev_docs/contributing/best_practices.mdx b/dev_docs/contributing/best_practices.mdx index 16c66417b89c10..7ec289561c8160 100644 --- a/dev_docs/contributing/best_practices.mdx +++ b/dev_docs/contributing/best_practices.mdx @@ -70,7 +70,7 @@ const dataView = savedObjectsClient.get(dataViewId) as DataView; ## Resusable react components -Use [EUI](https://elastic.github.io/eui) for all your basic UI components to create a consistent UI experience. We also have generic UI components offered from the plugin and the plugin. +Use [EUI](https://elastic.github.io/eui) for all your basic UI components to create a consistent UI experience. We also have generic UI components offered from the plugin. ## Don't export code that doesn't need to be public diff --git a/dev_docs/contributing/standards.mdx b/dev_docs/contributing/standards.mdx index 1bb54ada1509c2..aba29e5fab2f28 100644 --- a/dev_docs/contributing/standards.mdx +++ b/dev_docs/contributing/standards.mdx @@ -15,6 +15,49 @@ We expect all developers to read and abide by our overarching . The majority of these items are linted against but some are not. +## Adding dependencies + +Looking for a dependency that isn't already available in Kibana? There are a few things to keep in mind before adding a new dependency. + +First, be sure you have read and are familiar with our . In particular, **Be wary of dependencies** +and **Prefer one way to do things** provide an overview of how we approach this question. + +In general, we have a bias toward **not** adding new dependencies unless there is a compelling reason to do so, as we want to +minimize Kibana's overall complexity. + +Should you find yourself evaluating a new dependency, here are some specific things to ask yourself: + +1. **Is there already another dependency that offers similar functionality?** If so, adding a new dependency may not be necessary. +Prefer one way to do things and use what's already there, unless there is an important reason not to do so. +2. **Does this dependency appear to be well-maintained?** A dependency that hasn't been updated in years is usually more of a +liability than an asset. Make sure the depedency has recent activity, that bugs and security vulnerabilities appear to be addressed +in a timely manner, and that there is active participation from the maintainers and community. +3. **How large is the dependency?** For client-side plugins, heavy dependencies can have a real impact on user experience, +especially if they are included in the initial page bundle and not loaded asynchronously. In some cases it might make more sense +to roll your own rather than include a bloated depedency, especially if you are only using a single piece of functionality. +4. **Does this dependency have a license that's compatible with Kibana's?** Most common open source licenses such as BSD, MIT, +and Apache 2.0/1.1 are okay to use with Kibana. Others may not be, or may require special attribution. +5. **Will this dependency need to be prebuilt?** Due to our build process, native module dependencies should include at least a prebuild +step so at install time it simply downloads instead of building from source. This allows us to optimize bootstrap times. +6. **Am I committed to maintaining this dependency?** Once you add a dependency to the `package.json`, someone else isn't going to +keep it updated for you. That means you will be responsible for updating it regularly, keeping an eye out for security vulnerabilities, +and dealing with any breaking changes that may arise during an upgrade. We recommend relying on the renovate bot to help keep the +dependency updated; be sure to mark your ownership of the package in the +[`renovate.json`](https://github.com/elastic/kibana/blob/main/renovate.json`) file. + +If you have any questions about whether adding a dependency is appropriate, feel free to reach out to one of the following teams +on Github: + +- **@elastic/kibana-tech-leads** +- **@elastic/kibana-core** +- **@elastic/kibana-operations** +- **@elastic/kibana-security** + + + If you are unsure of which licenses are okay to use, refer to the + [Permitted Open Source Licenses list](https://github.com/elastic/open-source/blob/main/elastic-product-policy.md#permitted-licenses-list). + + ## RESTful HTTP APIs ### Terminology diff --git a/dev_docs/key_concepts/embeddables.mdx b/dev_docs/key_concepts/embeddables.mdx index f1a2bea5b9b128..e42233a7f3f26e 100644 --- a/dev_docs/key_concepts/embeddables.mdx +++ b/dev_docs/key_concepts/embeddables.mdx @@ -14,6 +14,7 @@ If you are planning to integrate with the plugin, please get in touch with the A ## Capabilities - Framework-agnostic API. - Out-of-the-box React support. +- Integration with Redux. - Integration with the [UI Actions](https://github.com/elastic/kibana/tree/HEAD/src/plugins/ui_actions) plugin. - Hierarchical structure to enclose multiple widgets. - Error handling. diff --git a/docs/canvas/canvas-tutorial.asciidoc b/docs/canvas/canvas-tutorial.asciidoc index 389cac89cde822..73d808a183920e 100644 --- a/docs/canvas/canvas-tutorial.asciidoc +++ b/docs/canvas/canvas-tutorial.asciidoc @@ -9,9 +9,11 @@ To familiarize yourself with *Canvas*, add the Sample eCommerce orders data, the To create a workpad of the eCommerce store data, add the data set, then create the workpad. -. Go to the {kib} *Home* page, then click *Try our sample data*. +. On the home page, click *Try sample data*. -. On the *Sample eCommerce orders data* card, click *Add data*. +. Click *Other sample data sets*. + +. On the *Sample eCommerce orders* card, click *Add data*. . Open the main menu, then click *Canvas*. diff --git a/docs/developer/getting-started/monorepo-packages.asciidoc b/docs/developer/getting-started/monorepo-packages.asciidoc index b6524c6007b2e7..a9dc912ab58e42 100644 --- a/docs/developer/getting-started/monorepo-packages.asciidoc +++ b/docs/developer/getting-started/monorepo-packages.asciidoc @@ -41,8 +41,6 @@ yarn kbn watch [discrete] === List of Already Migrated Packages to Bazel -- @elastic/eslint-config-kibana -- @elastic/safer-lodash-set - @kbn/ace - @kbn/analytics - @kbn/apm-config-loader @@ -57,6 +55,7 @@ yarn kbn watch - @kbn/docs-utils - @kbn/es - @kbn/es-archiver +- @kbn/eslint-config-kibana - @kbn/eslint-plugin-eslint - @kbn/expect - @kbn/i18n @@ -68,6 +67,7 @@ yarn kbn watch - @kbn/optimizer - @kbn/plugin-helpers - @kbn/rule-data-utils +- @kbn/safer-lodash-set - @kbn/securitysolution-autocomplete - @kbn/securitysolution-es-utils - @kbn/securitysolution-hook-utils diff --git a/docs/developer/plugin-list.asciidoc b/docs/developer/plugin-list.asciidoc index 64077b2ecc106f..e4bda1d283444e 100644 --- a/docs/developer/plugin-list.asciidoc +++ b/docs/developer/plugin-list.asciidoc @@ -259,10 +259,6 @@ oss plugins. generating deep links to other apps using locators, and creating short URLs. -|{kib-repo}blob/{branch}/src/plugins/shared_ux/README.md[sharedUX] -|Our mission is to make consistency in our user experience a product. - - |{kib-repo}blob/{branch}/src/plugins/telemetry/README.md[telemetry] |Telemetry allows Kibana features to have usage tracked in the wild. The general term "telemetry" refers to multiple things: @@ -303,6 +299,10 @@ In general this plugin provides: |Registers commercially licensed generic actions like per panel time range and contains some code that supports drilldown work. +|{kib-repo}blob/{branch}/src/plugins/unified_field_list/README.md[unifiedFieldList] +|This Kibana plugin contains components and services for field list UI (as in fields sidebar on Discover and Lens pages). + + |{kib-repo}blob/{branch}/src/plugins/unified_search/README.md[unifiedSearch] |Contains all the components of Kibana's unified search experience. Specifically: diff --git a/docs/getting-started/images/addData_sampleDataCards_7.15.0.png b/docs/getting-started/images/addData_sampleDataCards_7.15.0.png deleted file mode 100644 index 27e10b98b9670a..00000000000000 Binary files a/docs/getting-started/images/addData_sampleDataCards_7.15.0.png and /dev/null differ diff --git a/docs/getting-started/images/addData_sampleDataCards_8.4.0.png b/docs/getting-started/images/addData_sampleDataCards_8.4.0.png new file mode 100644 index 00000000000000..49a83dbbdc10b8 Binary files /dev/null and b/docs/getting-started/images/addData_sampleDataCards_8.4.0.png differ diff --git a/docs/getting-started/images/addFilterOptions_dashboard_8.4.0.png b/docs/getting-started/images/addFilterOptions_dashboard_8.4.0.png new file mode 100644 index 00000000000000..eb16edb2b07642 Binary files /dev/null and b/docs/getting-started/images/addFilterOptions_dashboard_8.4.0.png differ diff --git a/docs/getting-started/images/addFilter_dashboard_8.4.0.png b/docs/getting-started/images/addFilter_dashboard_8.4.0.png new file mode 100644 index 00000000000000..eeec26daad89d5 Binary files /dev/null and b/docs/getting-started/images/addFilter_dashboard_8.4.0.png differ diff --git a/docs/getting-started/images/availableFields_discover_8.4.0.png b/docs/getting-started/images/availableFields_discover_8.4.0.png new file mode 100644 index 00000000000000..ba3b9ecaeb4ac5 Binary files /dev/null and b/docs/getting-started/images/availableFields_discover_8.4.0.png differ diff --git a/docs/getting-started/images/dashboard_ecommerceRevenueDashboard_7.15.0.png b/docs/getting-started/images/dashboard_ecommerceRevenueDashboard_7.15.0.png index 5b62832b1d093c..7fbc0a9bad4115 100644 Binary files a/docs/getting-started/images/dashboard_ecommerceRevenueDashboard_7.15.0.png and b/docs/getting-started/images/dashboard_ecommerceRevenueDashboard_7.15.0.png differ diff --git a/docs/getting-started/images/dashboard_sampleDataAddFilter_8.4.0.png b/docs/getting-started/images/dashboard_sampleDataAddFilter_8.4.0.png new file mode 100644 index 00000000000000..4c253d3fc3ac57 Binary files /dev/null and b/docs/getting-started/images/dashboard_sampleDataAddFilter_8.4.0.png differ diff --git a/docs/getting-started/images/dashboard_sampleDataFilter_7.15.0.png b/docs/getting-started/images/dashboard_sampleDataFilter_7.15.0.png deleted file mode 100644 index f1f46ab42371af..00000000000000 Binary files a/docs/getting-started/images/dashboard_sampleDataFilter_7.15.0.png and /dev/null differ diff --git a/docs/getting-started/images/ecommerceTreemap_lens_8.4.0.png b/docs/getting-started/images/ecommerceTreemap_lens_8.4.0.png new file mode 100644 index 00000000000000..d933ce93de9d1b Binary files /dev/null and b/docs/getting-started/images/ecommerceTreemap_lens_8.4.0.png differ diff --git a/docs/getting-started/images/kql_discover_8.4.0.png b/docs/getting-started/images/kql_discover_8.4.0.png new file mode 100644 index 00000000000000..cc0398049013a0 Binary files /dev/null and b/docs/getting-started/images/kql_discover_8.4.0.png differ diff --git a/docs/getting-started/images/sampleDataFilter_dashboard_8.4.0.png b/docs/getting-started/images/sampleDataFilter_dashboard_8.4.0.png new file mode 100644 index 00000000000000..7b5af0ad39395c Binary files /dev/null and b/docs/getting-started/images/sampleDataFilter_dashboard_8.4.0.png differ diff --git a/docs/getting-started/images/timeFilter_discover_8.4.0.png b/docs/getting-started/images/timeFilter_discover_8.4.0.png new file mode 100644 index 00000000000000..73f13ef2b1d9c6 Binary files /dev/null and b/docs/getting-started/images/timeFilter_discover_8.4.0.png differ diff --git a/docs/getting-started/images/tutorial-discover-2.png b/docs/getting-started/images/tutorial-discover-2.png deleted file mode 100644 index cf217562c37fd9..00000000000000 Binary files a/docs/getting-started/images/tutorial-discover-2.png and /dev/null differ diff --git a/docs/getting-started/images/tutorial-discover-3.png b/docs/getting-started/images/tutorial-discover-3.png deleted file mode 100644 index 79cf94058bb761..00000000000000 Binary files a/docs/getting-started/images/tutorial-discover-3.png and /dev/null differ diff --git a/docs/getting-started/images/tutorial-discover-4.png b/docs/getting-started/images/tutorial-discover-4.png deleted file mode 100644 index 584221e8cfd04a..00000000000000 Binary files a/docs/getting-started/images/tutorial-discover-4.png and /dev/null differ diff --git a/docs/getting-started/images/tutorial-visualization-dropdown.png b/docs/getting-started/images/tutorial-visualization-dropdown.png deleted file mode 100644 index a069af95ed14a6..00000000000000 Binary files a/docs/getting-started/images/tutorial-visualization-dropdown.png and /dev/null differ diff --git a/docs/getting-started/images/tutorial-visualization-treemap.png b/docs/getting-started/images/tutorial-visualization-treemap.png deleted file mode 100644 index c6e8db133cb444..00000000000000 Binary files a/docs/getting-started/images/tutorial-visualization-treemap.png and /dev/null differ diff --git a/docs/getting-started/images/visualizationTypeDropdown_lens_8.4.0.png b/docs/getting-started/images/visualizationTypeDropdown_lens_8.4.0.png new file mode 100644 index 00000000000000..731327997c59b4 Binary files /dev/null and b/docs/getting-started/images/visualizationTypeDropdown_lens_8.4.0.png differ diff --git a/docs/getting-started/quick-start-guide.asciidoc b/docs/getting-started/quick-start-guide.asciidoc index 2667729f4b8542..bc98fbf5af737f 100644 --- a/docs/getting-started/quick-start-guide.asciidoc +++ b/docs/getting-started/quick-start-guide.asciidoc @@ -1,13 +1,13 @@ [[get-started]] == Quick start -To quickly get up and running with {kib}, set up on Cloud, then add a sample data set that you can explore and analyze. +To quickly get up and running with {kib}, set up on Cloud, then add a sample data set that you can explore and visualize. -When you've finished, you'll know how to: +When you're done, you'll know how to: * <> -* <> +* <> [float] === Required privileges @@ -26,12 +26,14 @@ include::{docs-root}/shared/cloud/ess-getting-started.asciidoc[] Sample data sets come with sample visualizations, dashboards, and more to help you explore {kib} before you ingest or add your own data. -. On the home page, click *Try our sample data*. +. On the home page, click *Try sample data*. + +. Click *Other sample data sets*. . On the *Sample eCommerce orders* card, click *Add data*. + [role="screenshot"] -image::images/addData_sampleDataCards_7.15.0.png[Add data UI for the sample data sets] +image::images/addData_sampleDataCards_8.4.0.png[Add data UI for the sample data sets] [float] [[explore-the-data]] @@ -44,7 +46,7 @@ image::images/addData_sampleDataCards_7.15.0.png[Add data UI for the sample data . Change the <> to *Last 7 days*. + [role="screenshot"] -image::images/tutorial-discover-2.png[Time filter menu with Last 7 days filter configured] +image::images/timeFilter_discover_8.4.0.png[Time filter menu with Last 7 days filter configured] . To view the sales orders for women's clothing that are $60 or more, use the <> search field: + @@ -52,18 +54,18 @@ image::images/tutorial-discover-2.png[Time filter menu with Last 7 days filter c products.taxless_price >= 60 and category : Women's Clothing + [role="screenshot"] -image::images/tutorial-discover-4.png[Discover tables that displays only the orders for women's clothing that are $60 or more] +image::images/kql_discover_8.4.0.png[Discover tables that displays only the orders for women's clothing that are $60 or more] . To view only the product categories that contain sales orders, hover over the *category* field, then click *+*. + [role="screenshot"] -image::images/tutorial-discover-3.png[Discover table that displays only the product categories that contain orders] +image::images/availableFields_discover_8.4.0.png[Discover table that displays only the product categories that contain orders] [float] [[view-and-analyze-the-data]] -== View and analyze the data +== Visualize the data -A dashboard is a collection of panels that you can use to view and analyze the data. Panels contain visualizations, interactive controls, text, and more. +A dashboard is a collection of panels that you can use to visualize the data. Panels contain visualizations, interactive controls, text, and more. . Open the main menu, then click *Dashboard*. @@ -76,7 +78,7 @@ image::images/dashboard_ecommerceRevenueDashboard_7.15.0.png[The [eCommerce] Rev [[create-a-visualization]] === Create a visualization panel -Create a treemap panel that shows the top sales regions and manufacturers, then add the panel to the dashboard. +Create a treemap visualization panel that shows the top sales regions and manufacturers, then add the panel to the dashboard. . In the toolbar, click *Edit*. @@ -85,7 +87,7 @@ Create a treemap panel that shows the top sales regions and manufacturers, then . In the drag-and-drop visualization editor, open the *Visualization type* dropdown, then select *Treemap*. + [role="screenshot"] -image::getting-started/images/tutorial-visualization-dropdown.png[Chart type menu with Treemap selected] +image::getting-started/images/visualizationTypeDropdown_lens_8.4.0.png[Chart type menu with Treemap selected] . From the *Available fields* list, drag the following fields to the workspace: @@ -94,7 +96,7 @@ image::getting-started/images/tutorial-visualization-dropdown.png[Chart type men * *manufacturer.keyword* + [role="screenshot"] -image::getting-started/images/tutorial-visualization-treemap.png[Treemap that displays Top values of geoip.city_name and Top values or manufacturer.keyword fields] +image::getting-started/images/ecommerceTreemap_lens_8.4.0.png[Treemap that displays Top values of geoip.city_name and Top values or manufacturer.keyword fields] . Click *Save and return*. + @@ -113,26 +115,32 @@ You can interact with the dashboard data using controls that allow you to apply . Click *Apply changes*. + [role="screenshot"] -image::images/dashboard_sampleDataFilter_7.15.0.png[The [eCommerce] Revenue Dashboard that shows only the women's clothing data from the Gnomehouse manufacturer] +image::images/sampleDataFilter_dashboard_8.4.0.png[The [eCommerce] Revenue Dashboard that shows only the women's clothing data from the Gnomehouse manufacturer] [float] [[filter-and-query-the-data]] === Filter the data -To view a subset of the data, you can apply filters to the dashboard panels. Apply a filter to view the women's clothing data generated on Wednesday from the Gnomehouse manufacturer. +To view a subset of the data, you can apply filters to the dashboard data. Apply a filter to view the women's clothing data generated on Wednesday from the Gnomehouse manufacturer. . Click *Add filter*. ++ +[role="screenshot"] +image::images/addFilter_dashboard_8.4.0.png[The Add filter action that applies dashboard-level filters] . From the *Field* dropdown, select *day_of_week*. . From the *Operator* dropdown, select *is*. . From the *Value* dropdown, select *Wednesday*. ++ +[role="screenshot"] +image::images/addFilterOptions_dashboard_8.4.0.png[The Add filter options configured to display only the women's clothing data generated on Wednesday from the Gnomehouse manufacturer] -. Click *Save*. +. Click *Add filter*. + [role="screenshot"] -image::images/dashboard_sampleDataAddFilter_7.15.0.png[The [eCommerce] Revenue Dashboard that shows only the women's clothing data generated on Wednesday from the Gnomehouse manufacturer] +image::images/dashboard_sampleDataAddFilter_8.4.0.png[The [eCommerce] Revenue Dashboard that shows only the women's clothing data generated on Wednesday from the Gnomehouse manufacturer] [float] [[quick-start-whats-next]] @@ -142,6 +150,6 @@ image::images/dashboard_sampleDataAddFilter_7.15.0.png[The [eCommerce] Revenue D *Explore your own data in Discover.* Ready to learn more about exploring your data in *Discover*? Go to <>. -*Create a dashboard with your own data.* Ready to learn more about analyzing your data in *Dashboard*? Go to <>. +*Create a dashboard with your own data.* Ready to learn more about visualizing your data on a *Dashboard*? Go to <>. *Try out the {ml-features}.* Ready to analyze the sample data sets and generate models for its patterns of behavior? Go to {ml-docs}/ml-getting-started.html[Getting started with {ml}]. diff --git a/docs/management/advanced-options.asciidoc b/docs/management/advanced-options.asciidoc index 211e2a3dd59231..e98561ce501082 100644 --- a/docs/management/advanced-options.asciidoc +++ b/docs/management/advanced-options.asciidoc @@ -89,7 +89,7 @@ Set this property to `false` to prevent the filter editor and KQL autocomplete from suggesting values for fields. [[autocomplete-valuesuggestionmethod]]`autocomplete:valueSuggestionMethod`:: -When set to `terms_enum`, autocomplete uses the terms enum API for value suggestions. Kibana returns results faster, but suggestions are approximate, sorted alphabetically, and can be outside the selected time range. +When set to `terms_enum`, autocomplete uses the terms enum API for value suggestions. Kibana returns results faster, but suggestions are approximate, sorted alphabetically, and can be outside the selected time range. (Note that this API is incompatible with {ref}/document-level-security.html[Document-Level-Security].) When set to `terms_agg`, Kibana uses a terms aggregation for value suggestions, which is slower, but suggestions include all values that optionally match your time range and are sorted by popularity. @@ -456,9 +456,8 @@ Includes {ref}/frozen-indices.html[frozen indices] in results. Searching through frozen indices might increase the search time. This setting is off by default. Users must opt-in to include frozen indices. -[[search-timeout]]`search:timeout`:: Change the maximum timeout for a search -session or set to 0 to disable the timeout and allow queries to run to -completion. +[[search-timeout]]`search:timeout`:: Change the maximum timeout, in milliseconds (ms), for a search +session. To disable the timeout and allow queries to run to completion, set to 0. The default is 600,000 ms, or 10 minutes. [float] [[kibana-siem-settings]] diff --git a/docs/maps/asset-tracking-tutorial.asciidoc b/docs/maps/asset-tracking-tutorial.asciidoc index 85629e0e611f6c..4e6efff35b3a35 100644 --- a/docs/maps/asset-tracking-tutorial.asciidoc +++ b/docs/maps/asset-tracking-tutorial.asciidoc @@ -318,9 +318,9 @@ cloud.auth: . In {kib}, open the main menu, and click *Stack Management > Data Views*. . Click *Create data view*. . Give the data view a name: *tri_met_tracks**. -. Click *Next step*. -. Set the *Time field* to *trimet.time*. -. Click *Create data view*. +. Set the index pattern as: *tri_met_tracks**. +. Set the *Timestamp field* to *trimet.time*. +. Click *Save data view to Kibana*. {kib} shows the fields in your data view. diff --git a/docs/maps/images/gs-filter-icon.png b/docs/maps/images/gs-filter-icon.png new file mode 100644 index 00000000000000..aebe2d51873fd4 Binary files /dev/null and b/docs/maps/images/gs-filter-icon.png differ diff --git a/docs/maps/images/gs_add_cloropeth_layer.png b/docs/maps/images/gs_add_cloropeth_layer.png index 10774c69adbbae..63dc1e3db2cfed 100644 Binary files a/docs/maps/images/gs_add_cloropeth_layer.png and b/docs/maps/images/gs_add_cloropeth_layer.png differ diff --git a/docs/maps/images/gs_add_es_document_layer.png b/docs/maps/images/gs_add_es_document_layer.png index 4656933552f26b..35a9192634edcc 100644 Binary files a/docs/maps/images/gs_add_es_document_layer.png and b/docs/maps/images/gs_add_es_document_layer.png differ diff --git a/docs/maps/images/gs_dashboard_with_map.png b/docs/maps/images/gs_dashboard_with_map.png index b7d4a7b63ed304..81fc181e698e93 100644 Binary files a/docs/maps/images/gs_dashboard_with_map.png and b/docs/maps/images/gs_dashboard_with_map.png differ diff --git a/docs/maps/images/gs_map_filtered.png b/docs/maps/images/gs_map_filtered.png new file mode 100644 index 00000000000000..f69b2e7397d573 Binary files /dev/null and b/docs/maps/images/gs_map_filtered.png differ diff --git a/docs/maps/images/gs_tooltip_filter.png b/docs/maps/images/gs_tooltip_filter.png new file mode 100644 index 00000000000000..3de04f846c8ae1 Binary files /dev/null and b/docs/maps/images/gs_tooltip_filter.png differ diff --git a/docs/maps/images/reverse-geocoding-tutorial/csa_regions.jpeg b/docs/maps/images/reverse-geocoding-tutorial/csa_regions.jpeg deleted file mode 100644 index 07435954a0b0b1..00000000000000 Binary files a/docs/maps/images/reverse-geocoding-tutorial/csa_regions.jpeg and /dev/null differ diff --git a/docs/maps/images/reverse-geocoding-tutorial/csa_regions.png b/docs/maps/images/reverse-geocoding-tutorial/csa_regions.png new file mode 100644 index 00000000000000..912814d50c292c Binary files /dev/null and b/docs/maps/images/reverse-geocoding-tutorial/csa_regions.png differ diff --git a/docs/maps/images/reverse-geocoding-tutorial/csa_regions_by_web_traffic.png b/docs/maps/images/reverse-geocoding-tutorial/csa_regions_by_web_traffic.png index 491448920ec491..8f107f761f3420 100644 Binary files a/docs/maps/images/reverse-geocoding-tutorial/csa_regions_by_web_traffic.png and b/docs/maps/images/reverse-geocoding-tutorial/csa_regions_by_web_traffic.png differ diff --git a/docs/maps/images/reverse-geocoding-tutorial/discover_enriched_web_log.png b/docs/maps/images/reverse-geocoding-tutorial/discover_enriched_web_log.png index 9c29da2d179473..ef8fde0cd4f225 100644 Binary files a/docs/maps/images/reverse-geocoding-tutorial/discover_enriched_web_log.png and b/docs/maps/images/reverse-geocoding-tutorial/discover_enriched_web_log.png differ diff --git a/docs/maps/images/sample_data_web_logs.png b/docs/maps/images/sample_data_web_logs.png index 76ff9c0d16221d..080824cf476876 100644 Binary files a/docs/maps/images/sample_data_web_logs.png and b/docs/maps/images/sample_data_web_logs.png differ diff --git a/docs/maps/maps-getting-started.asciidoc b/docs/maps/maps-getting-started.asciidoc index d4da7ef8aae2ed..317a9657f19651 100644 --- a/docs/maps/maps-getting-started.asciidoc +++ b/docs/maps/maps-getting-started.asciidoc @@ -34,7 +34,7 @@ refer to <>. . Open the main menu, and then click *Dashboard*. . Click **Create dashboard**. . Set the time range to *Last 7 days*. -. Click the **Create new Maps** icon image:maps/images/app_gis_icon.png[] +. Click the **Create new Maps** icon image:maps/images/app_gis_icon.png[]. [float] [[maps-add-choropleth-layer]] @@ -46,7 +46,7 @@ and lighter shades will symbolize countries with less traffic. . Click **Add layer**, and then click **Choropleth**. -. From the **Layer** dropdown menu, select **World Countries**. +. From the **EMS boundaries** dropdown menu, select **World Countries**. . In **Statistics source**, set: ** **Data view** to **kibana_sample_data_logs** @@ -62,12 +62,12 @@ and lighter shades will symbolize countries with less traffic. . Add a Tooltip field: ** **ISO 3166-1 alpha-2 code** is added by default. -** Click **+ Add** to open field select. +** Click **+ Add** to open the field select. ** Select **name** and click *Add*. . In **Layer style**: -** Set **Fill color: As number** to the grey color ramp. +** Set **Fill color > As number** to the grey color ramp. ** Set **Border color** to white. ** Under **Label**, change **By value** to **Fixed**. @@ -76,7 +76,7 @@ and lighter shades will symbolize countries with less traffic. Your map now looks like this: + [role="screenshot"] -image::maps/images/gs_add_cloropeth_layer.png[] +image::maps/images/gs_add_cloropeth_layer.png[Map showing the Total Requests by Destination layer] [float] [[maps-add-elasticsearch-layer]] @@ -107,7 +107,7 @@ The layer is only visible when users zoom in. . Add a tooltip field and select **agent**, **bytes**, **clientip**, **host**, **machine.os**, **request**, **response**, and **timestamp**. -. In **Scaling**, set *Limits results to 10,000.* +. In **Scaling**, enable *Limit results to 10,000.* . In **Layer style**, set **Fill color** to **#2200FF**. @@ -116,7 +116,7 @@ The layer is only visible when users zoom in. Your map will look like this from zoom level 9 to 24: + [role="screenshot"] -image::maps/images/gs_add_es_document_layer.png[] +image::maps/images/gs_add_es_document_layer.png[Map showing what zoom level looks like a level 9] [float] ==== Add a layer for aggregated data @@ -140,14 +140,14 @@ grids with less bytes transferred. ** Click **Add metric**. ** Set **Aggregation** to **Sum** with **Field** set to **bytes**. . In **Layer style**, change **Symbol size**: -** Set the field select to *sum bytes*. +** Set *By value* to *sum bytes*. ** Set the min size to 7 and the max size to 25 px. . Click **Save & close** button. + Your map will look like this between zoom levels 0 and 9: + [role="screenshot"] -image::maps/images/sample_data_web_logs.png[] +image::maps/images/sample_data_web_logs.png[Map showing what zoom level 3 looks like] [float] [[maps-save]] @@ -164,10 +164,10 @@ View your geospatial data alongside a heat map and pie chart, and then filter th When you apply a filter in one panel, it is applied to all panels on the dashboard. . Click **Add from library** to open a list of panels that you can add to the dashboard. -. Add **[Logs] Unique Visitor Heatmap** and **[Logs] Bytes distribution** to the dashboard. +. Add **[Logs] Unique Destination Heatmap** and **[Logs] Bytes distribution** to the dashboard. + [role="screenshot"] -image::maps/images/gs_dashboard_with_map.png[] +image::maps/images/gs_dashboard_with_map.png[Map in a dashboard with 2 other panels] . To filter for documents with unusually high byte values, click and drag in the *Bytes distribution* chart. @@ -177,10 +177,15 @@ image::maps/images/gs_dashboard_with_map.png[] .. Open a tooltip by clicking anywhere in the United States vector. -.. To show only documents where **geo.src** is **US**, click the filter icon in the row for **ISO 3066-1 alpha-2**. +.. To show only documents where **geo.src** is **US**, click the filter icon image:maps/images/gs-filter-icon.png[filter icon, width=24px]in the row for **ISO 3066-1 alpha-2**. ++ +[role="screenshot"] +image::maps/images/gs_tooltip_filter.png[Tooltip on map, width=75%] ++ +Your filtered map should look similar to this: + [role="screenshot"] -image::maps/images/gs_dashboard_with_terms_filter.png[] +image::maps/images/gs_map_filtered.png[Map showing filtered data] [float] === What's next? diff --git a/docs/maps/reverse-geocoding-tutorial.asciidoc b/docs/maps/reverse-geocoding-tutorial.asciidoc index 5997637b2eb13b..059a7ec4e7b836 100644 --- a/docs/maps/reverse-geocoding-tutorial.asciidoc +++ b/docs/maps/reverse-geocoding-tutorial.asciidoc @@ -2,7 +2,7 @@ [[reverse-geocoding-tutorial]] == Map custom regions with reverse geocoding -*Maps* comes with https://maps.elastic.co/#file[predefined regions] that allow you to quickly visualize regions by metrics. *Maps* also offers the ability to map your own regions. You can use any region data you'd like, as long as your source data contains an identifier for the corresponding region. +*Maps* comes with https://maps.elastic.co/#file[predefined regions] that allow you to quickly visualize regions by metrics. *Maps* also offers the ability to map your own regions. You can use any region data you'd like, as long as your source data contains an identifier for the corresponding region. But how can you map regions when your source data does not contain a region identifier? This is where reverse geocoding comes in. Reverse geocoding is the process of assigning a region identifier to a feature based on its location. @@ -17,7 +17,7 @@ You’ll learn to: When you complete this tutorial, you’ll have a map that looks like this: [role="screenshot"] -image::maps/images/reverse-geocoding-tutorial/csa_regions_by_web_traffic.png[] +image::maps/images/reverse-geocoding-tutorial/csa_regions_by_web_traffic.png[Map showing custom regions] [float] @@ -29,6 +29,7 @@ You’ll use the <> that comes with Kiban To install web logs sample data set: . On the home page, click *Try sample data*. +. Expand *Other sample data sets*. . On the *Sample web logs* card, click *Add data*. @@ -36,13 +37,14 @@ To install web logs sample data set: === Step 2: Index Combined Statistical Area (CSA) regions GeoIP level of detail is very useful for driving decision-making. For example, say you want to spin up a marketing campaign based on the locations of your users or show executive stakeholders which metro areas are experiencing an uptick of traffic. -That kind of scale in the United States is often captured with what the Census Bureau calls the Combined Statistical Area (CSA). Combined Statistical Area is roughly equivalent with how people intuitively think of which urban area they live in. It does not necessarily coincide with state or city boundaries. +That kind of scale in the United States is often captured with what the Census +Bureau calls the Combined Statistical Area (CSA). CSA is roughly equivalent with how people intuitively think of which urban area they live in. It does not necessarily coincide with state or city boundaries. CSAs generally share the same telecom providers and ad networks. New fast food franchises expand to a CSA rather than a particular city or municipality. Basically, people in the same CSA shop in the same IKEA. To get the CSA boundary data: -. Download the "Combined Statistical Areas (CSAs)" zip file from https://www.census.gov/geographies/mapping-files/time-series/geo/carto-boundary-file.html[Census Bureau’s website]. +. Go to the https://www.census.gov/geographies/mapping-files/time-series/geo/carto-boundary-file.html[Census Bureau’s website] and download the `cb_2018_us_csa_500k.zip` file. . Uncompress the zip file. . In Kibana, open the main menu, and click *Maps*. . Click *Create map*. @@ -55,7 +57,7 @@ To get the CSA boundary data: . Set index name to *csa* and click *Import file*. . When importing is complete, click *Add as document layer*. . Add Tooltip fields: -.. Click *+ Add* to open field select. +.. Click *+ Add* to open the field select. .. Select *NAME*, *GEOID*, and *AFFGEOID*. .. Click *Add*. . Click *Save & close*. @@ -63,24 +65,24 @@ To get the CSA boundary data: Looking at the map, you get a sense of what constitutes a metro area in the eyes of the Census Bureau. [role="screenshot"] -image::maps/images/reverse-geocoding-tutorial/csa_regions.jpeg[] +image::maps/images/reverse-geocoding-tutorial/csa_regions.png[Map showing metro area] [float] === Step 3: Reverse geocoding To visualize CSA regions by web log traffic, the web log traffic must contain a CSA region identifier. You'll use {es} {ref}/enrich-processor.html[enrich processor] to add CSA region identifiers to the web logs sample data set. You can skip this step if your source data already contains region identifiers. -. Open the main menu, then click *Dev Tools*. +. Open the main menu, and then click *Dev Tools*. . In *Console*, create a {ref}/geo-match-enrich-policy-type.html[geo_match enrichment policy]: + [source,js] ---------------------------------- -PUT /_enrich/policy/csa_lookup -{ - "geo_match": { - "indices": "csa", - "match_field": "coordinates", - "enrich_fields": [ "GEOID", "NAME"] - } +PUT /_enrich/policy/csa_lookup +{ + "geo_match": { + "indices": "csa", + "match_field": "geometry", + "enrich_fields": [ "GEOID", "NAME"] + } } ---------------------------------- @@ -95,29 +97,29 @@ POST /_enrich/policy/csa_lookup/_execute + [source,js] ---------------------------------- -PUT _ingest/pipeline/lonlat-to-csa -{ - "description": "Reverse geocode longitude-latitude to combined statistical area", - "processors": [ - { - "enrich": { - "field": "geo.coordinates", - "policy_name": "csa_lookup", - "target_field": "csa", - "ignore_missing": true, - "ignore_failure": true, - "description": "Lookup the csa identifier" - } - }, - { - "remove": { - "field": "csa.coordinates", - "ignore_missing": true, - "ignore_failure": true, - "description": "Remove the shape field" - } - } - ] +PUT _ingest/pipeline/lonlat-to-csa +{ + "description": "Reverse geocode longitude-latitude to combined statistical area", + "processors": [ + { + "enrich": { + "field": "geo.coordinates", + "policy_name": "csa_lookup", + "target_field": "csa", + "ignore_missing": true, + "ignore_failure": true, + "description": "Lookup the csa identifier" + } + }, + { + "remove": { + "field": "csa.geometry", + "ignore_missing": true, + "ignore_failure": true, + "description": "Remove the shape field" + } + } + ] } ---------------------------------- @@ -132,16 +134,16 @@ POST kibana_sample_data_logs/_update_by_query?pipeline=lonlat-to-csa + [source,js] ---------------------------------- -PUT kibana_sample_data_logs/_settings -{ - "index": { - "default_pipeline": "lonlat-to-csa" - } +PUT kibana_sample_data_logs/_settings +{ + "index": { + "default_pipeline": "lonlat-to-csa" + } } ---------------------------------- . Open the main menu, and click *Discover*. -. Set the data view to *kibana_sample_data_logs*. +. Set the data view to *Kibana Sample Data Logs*. . Open the <>, and set the time range to the last 30 days. . Scan through the list of *Available fields* until you find the `csa.GEOID` field. You can also search for the field by name. . Click image:images/reverse-geocoding-tutorial/add-icon.png[Add icon] to toggle the field into the document table. @@ -150,7 +152,7 @@ PUT kibana_sample_data_logs/_settings Your web log data now contains `csa.GEOID` and `csa.NAME` fields from the matching *csa* region. Web log traffic not contained in a CSA region does not have values for `csa.GEOID` and `csa.NAME` fields. [role="screenshot"] -image::maps/images/reverse-geocoding-tutorial/discover_enriched_web_log.png[] +image::maps/images/reverse-geocoding-tutorial/discover_enriched_web_log.png[View of data in Discover] [float] === Step 4: Visualize Combined Statistical Area (CSA) regions by web traffic @@ -160,12 +162,12 @@ Now that our web traffic contains CSA region identifiers, you'll visualize CSA r . Click *Create map*. . Click *Add layer*. . Click *Choropleth*. -. For *Boundaries source*: +. For *Boundaries source*: .. Select *Points, lines, and polygons from Elasticsearch*. .. Set *Data view* to *csa*. .. Set *Join field* to *GEOID*. . For *Statistics source*: -.. Set *Data view* to *kibana_sample_data_logs*. +.. Set *Data view* to *Kibana Sample Data Logs*. .. Set *Join field* to *csa.GEOID.keyword*. . Click *Add layer*. . Scroll to *Layer Style* and Set *Label* to *Fixed*. @@ -176,7 +178,6 @@ Now that our web traffic contains CSA region identifiers, you'll visualize CSA r .. Click *Save and add to library*. [role="screenshot"] -image::maps/images/reverse-geocoding-tutorial/csa_regions_by_web_traffic.png[] +image::maps/images/reverse-geocoding-tutorial/csa_regions_by_web_traffic.png[Final map showing custom regions] Congratulations! You have completed the tutorial and have the recipe for visualizing custom regions. You can now try replicating this same analysis with your own data. - diff --git a/docs/osquery/images/enter-query.png b/docs/osquery/images/enter-query.png index efcf8fa58a7a8b..6043eb36329821 100644 Binary files a/docs/osquery/images/enter-query.png and b/docs/osquery/images/enter-query.png differ diff --git a/docs/osquery/osquery.asciidoc b/docs/osquery/osquery.asciidoc index 88f8f768df0dec..66edbc95526eb2 100644 --- a/docs/osquery/osquery.asciidoc +++ b/docs/osquery/osquery.asciidoc @@ -37,26 +37,25 @@ To inspect hosts, run a query against one or more agents or policies, then view the results. . Open the main menu, and then click *Osquery*. - . In the *Live queries* view, click **New live query**. - +. Choose to run a single query or a query pack. . Select one or more agents or groups to query. Start typing in the search field, and you'll get suggestions for agents by name, ID, platform, and policy. - -. Enter a query or select a query from your saved queries. +. Specify the query or pack to run: +** *Query*: Select a saved query or enter a new one in the text box. After you enter the query, you can expand the **Advanced** section to view or set <> included in the results from the live query. Mapping ECS fields is optional. +** *Pack*: Select from query packs that have been loaded and activated. After you select a pack, all of the queries in the pack are displayed. ++ +TIP: Refer to <> to learn about using and managing Elastic prebuilt packs. + [role="screenshot"] image::images/enter-query.png[Select saved query dropdown name showing query name and description] -. (Optional) Expand the **Advanced** section to view or set <> included in the results from the live query. - -. Click **Submit**. +. Click **Submit**. Queries will timeout after 5 minutes if there are no responses. ++ +TIP: To save a single query for future use, click *Save for later* and define the ID, description, and other <>. -. Review the results in a table, or navigate to *Discover* to dive deeper into the response, -or to the drag-and-drop *Lens* editor to create visualizations. +. Review the results. Next, navigate to *Discover* to dive deeper into the response or to *Lens* to create visualizations. . To view more information about the request, such as failures, open the *Status* tab. -. To save the query for future use, click *Save for later* and define the ID, -description, and other <>. [float] [[osquery-view-history]] @@ -72,17 +71,17 @@ Each query has the following options: [role="screenshot"] image::images/live-query-check-results.png[Results of OSquery] - [float] [[osquery-schedule-query]] == Schedule queries with packs -Create packs to organize sets of queries. For example, you might create one pack that checks -for IT compliance-type issues, and another pack that monitors for evidence of malware. -You can schedule packs to run for one or more agent policies. When scheduled, queries in the pack are run at the set intervals for all agents in those policies. Scheduling packs is optional. +A pack is a set of grouped queries that perform similar functions or address common use cases. <> are available to download and can help you get started using the Osquery integration. -. Open the **Packs** tab. +You can also create a custom pack with one or more queries. For example, when creating custom packs, you might create one pack that checks for IT compliance-type issues, and another pack that monitors for evidence of malware. +You can run packs as live queries or schedule packs to run for one or more agent policies. When scheduled, queries in the pack are run at the set intervals for all agents in those policies. + +. Click the **Packs** tab. . Click **Add pack** to create a new pack, or click the name of an existing pack, then **Edit** to add queries to an existing pack. . Provide the following fields: @@ -91,7 +90,7 @@ You can schedule packs to run for one or more agent policies. When scheduled, qu * A short description of the pack. -* The agent policies where this pack should run. If no agent policies are set, then the pack is not scheduled. +* The agent policies where this pack should run. If no agent policies are set, the pack is not scheduled. . Add queries to schedule: @@ -159,28 +158,13 @@ Once you save a query, you can only edit it from the *Saved queries* tab: [float] [[osquery-prebuilt-packs-queries]] == Prebuilt Elastic packs and queries -Osquery Manager includes a set of prebuilt Osquery packs and saved queries -that can help you get started using the integration. - -[float] -[[osquery-prebuilt-queries]] -=== Prebuilt queries -A set of saved queries are included with the integration and available to run as a live query. -Note the following about the prebuilt queries: - -* The queries are not editable. - -* Several of the queries include default ECS mappings to standardize the results. - -* The prebuilt Elastic queries all follow the same naming convention and identify -what type of information is being queried, what operating system it supports if it's limited to one or more, -and that these are Elastic queries. For example, `firewall_rules_windows_elastic`. +The prebuilt Osquery packs are included with the integration. Once you add a pack, you can activate and schedule it. [float] [[osquery-prebuilt-packs]] === Prebuilt packs -The prebuilt Osquery packs are included with the integration and can be optionally loaded. -Once added, you can then activate and schedule the packs. +The prebuilt Osquery packs are included with the integration and can be optionally loaded. +Once added, you can then activate and schedule the packs. You can modify the scheduled agent policies for a prebuilt pack, but you cannot edit queries in the pack. To edit the queries, you must first create a copy of the pack. @@ -194,7 +178,7 @@ For information about the prebuilt packs that are available, refer to < +{{/context.hits}} +-------------------------------------------------- +// NOTCONSOLE +<1> The `fields` parameter here is used to access the `day_of_week` runtime field. +-- ++ +As the {ref}/search-fields.html#search-fields-response[`fields`] response always returns an array of values for each field, +the https://mustache.github.io/[Mustache] template array syntax is used to iterate over these values in your actions as the following example shows: ++ +-- +[source] +-------------------------------------------------- +{{#context.hits}} +Labels: +{{#fields.labels}} +- {{.}} +{{/fields.labels}} +{{/context.hits}} +-------------------------------------------------- +// NOTCONSOLE +-- [float] ==== Test your query diff --git a/docs/user/dashboard/aggregation-based.asciidoc b/docs/user/dashboard/aggregation-based.asciidoc index 842f2e93bc58ef..4ca251b3a19363 100644 --- a/docs/user/dashboard/aggregation-based.asciidoc +++ b/docs/user/dashboard/aggregation-based.asciidoc @@ -140,9 +140,11 @@ a bar chart that displays the top five log traffic sources for every three hours Add the sample web logs data that you'll use to create the bar chart, then create the dashboard. -. From the *Home* page, click *Try our sample data*. +. On the home page, click *Try sample data*. -. From *Sample web logs*, click *Add data*. +. Click *Other sample data sets*. + +. On the *Sample web logs* card, click *Add data*. . Open the main menu, then click *Dashboard*. @@ -153,9 +155,9 @@ Add the sample web logs data that you'll use to create the bar chart, then creat Open the *Aggregation based* editor and change the time range. -. On the dashboard, click *All types > Aggregation based*, select *Vertical bar*, then select *kibana_sample_data_logs*. +. On the dashboard, click *All types > Aggregation based*, select *Vertical bar*, then select *Kibana Sample Data Logs*. -. Make sure the <>> is *Last 7 days*. +. Make sure the <> is *Last 7 days*. [float] [[tutorial-configure-the-bar-chart]] @@ -172,7 +174,7 @@ To create the bar chart, add a <>, then .. Click *Update*. + [role="screenshot"] -image:images/aggBased_barChartTutorial1_8.3.png[Bar chart with sample logs data] +image:images/aggBased_barChartTutorial1_8.4.png[Bar chart with sample logs data] . To show the top five log traffic sources, add a sub-bucket aggregation. @@ -187,7 +189,7 @@ TIP: Aggregation-based panels support a maximum of three *Split series*. .. Click *Update*. + [role="screenshot"] -image:images/aggBased_barChartTutorial2_8.3.png[Bar chart with sample logs data] +image:images/aggBased_barChartTutorial2_8.4.png[Bar chart with sample logs data] [float] [[save-the-aggregation-based-panel]] diff --git a/docs/user/dashboard/images/aggBased_barChartTutorial1_8.3.png b/docs/user/dashboard/images/aggBased_barChartTutorial1_8.3.png deleted file mode 100644 index a30fe3fbd1b78b..00000000000000 Binary files a/docs/user/dashboard/images/aggBased_barChartTutorial1_8.3.png and /dev/null differ diff --git a/docs/user/dashboard/images/aggBased_barChartTutorial1_8.4.png b/docs/user/dashboard/images/aggBased_barChartTutorial1_8.4.png new file mode 100644 index 00000000000000..9e43d6e61a6562 Binary files /dev/null and b/docs/user/dashboard/images/aggBased_barChartTutorial1_8.4.png differ diff --git a/docs/user/dashboard/images/aggBased_barChartTutorial2_8.3.png b/docs/user/dashboard/images/aggBased_barChartTutorial2_8.3.png deleted file mode 100644 index d1d7f0644db31b..00000000000000 Binary files a/docs/user/dashboard/images/aggBased_barChartTutorial2_8.3.png and /dev/null differ diff --git a/docs/user/dashboard/images/aggBased_barChartTutorial2_8.4.png b/docs/user/dashboard/images/aggBased_barChartTutorial2_8.4.png new file mode 100644 index 00000000000000..ea6727c0ca47d8 Binary files /dev/null and b/docs/user/dashboard/images/aggBased_barChartTutorial2_8.4.png differ diff --git a/docs/user/dashboard/images/lens_dataViewDropDown_8.0.png b/docs/user/dashboard/images/lens_dataViewDropDown_8.0.png deleted file mode 100644 index 309e1be49b9db7..00000000000000 Binary files a/docs/user/dashboard/images/lens_dataViewDropDown_8.0.png and /dev/null differ diff --git a/docs/user/dashboard/images/lens_dataViewDropDown_8.3.png b/docs/user/dashboard/images/lens_dataViewDropDown_8.3.png deleted file mode 100644 index 857f28303b8cb4..00000000000000 Binary files a/docs/user/dashboard/images/lens_dataViewDropDown_8.3.png and /dev/null differ diff --git a/docs/user/dashboard/images/lens_dataViewDropDown_8.4.0.png b/docs/user/dashboard/images/lens_dataViewDropDown_8.4.0.png new file mode 100644 index 00000000000000..990cebfc51f6fa Binary files /dev/null and b/docs/user/dashboard/images/lens_dataViewDropDown_8.4.0.png differ diff --git a/docs/user/dashboard/images/lens_lineChartMetricOverTime_8.4.0.png b/docs/user/dashboard/images/lens_lineChartMetricOverTime_8.4.0.png new file mode 100644 index 00000000000000..9ed9b4730fae4a Binary files /dev/null and b/docs/user/dashboard/images/lens_lineChartMetricOverTime_8.4.0.png differ diff --git a/docs/user/dashboard/images/lens_logsDashboard_7.16.png b/docs/user/dashboard/images/lens_logsDashboard_7.16.png deleted file mode 100644 index cdfe0accdbbb5d..00000000000000 Binary files a/docs/user/dashboard/images/lens_logsDashboard_7.16.png and /dev/null differ diff --git a/docs/user/dashboard/images/lens_logsDashboard_8.3.png b/docs/user/dashboard/images/lens_logsDashboard_8.3.png deleted file mode 100644 index 089fd5dcadb0c2..00000000000000 Binary files a/docs/user/dashboard/images/lens_logsDashboard_8.3.png and /dev/null differ diff --git a/docs/user/dashboard/images/lens_logsDashboard_8.4.0.png b/docs/user/dashboard/images/lens_logsDashboard_8.4.0.png new file mode 100644 index 00000000000000..1801fea4e06206 Binary files /dev/null and b/docs/user/dashboard/images/lens_logsDashboard_8.4.0.png differ diff --git a/docs/user/dashboard/images/lens_metricUniqueCountOfClientip_7.16.png b/docs/user/dashboard/images/lens_metricUniqueCountOfClientip_7.16.png deleted file mode 100644 index bed6acf501a3a7..00000000000000 Binary files a/docs/user/dashboard/images/lens_metricUniqueCountOfClientip_7.16.png and /dev/null differ diff --git a/docs/user/dashboard/images/lens_metricUniqueCountOfClientip_8.4.0.png b/docs/user/dashboard/images/lens_metricUniqueCountOfClientip_8.4.0.png new file mode 100644 index 00000000000000..f3b1603b50bef9 Binary files /dev/null and b/docs/user/dashboard/images/lens_metricUniqueCountOfClientip_8.4.0.png differ diff --git a/docs/user/dashboard/images/lens_pieChartCompareSubsetOfDocs_7.16.png b/docs/user/dashboard/images/lens_pieChartCompareSubsetOfDocs_7.16.png index f8e8ba98f691e3..fdeca77da25fb9 100644 Binary files a/docs/user/dashboard/images/lens_pieChartCompareSubsetOfDocs_7.16.png and b/docs/user/dashboard/images/lens_pieChartCompareSubsetOfDocs_7.16.png differ diff --git a/docs/user/dashboard/images/lens_visualizationTypeDropdown_8.0.png b/docs/user/dashboard/images/lens_visualizationTypeDropdown_8.0.png deleted file mode 100644 index 3a7cc44b820ee7..00000000000000 Binary files a/docs/user/dashboard/images/lens_visualizationTypeDropdown_8.0.png and /dev/null differ diff --git a/docs/user/dashboard/images/lens_visualizationTypeDropdown_8.4.0.png b/docs/user/dashboard/images/lens_visualizationTypeDropdown_8.4.0.png new file mode 100644 index 00000000000000..a86dbed105effb Binary files /dev/null and b/docs/user/dashboard/images/lens_visualizationTypeDropdown_8.4.0.png differ diff --git a/docs/user/dashboard/lens-advanced.asciidoc b/docs/user/dashboard/lens-advanced.asciidoc index 68516b49d21588..04822444c530ea 100644 --- a/docs/user/dashboard/lens-advanced.asciidoc +++ b/docs/user/dashboard/lens-advanced.asciidoc @@ -16,7 +16,9 @@ Before you begin, you should be familiar with the <>. Add the sample ecommerce data, and create and set up the dashboard. -. Go to the *Home* page, then click *Try sample data*. +. On the home page, click *Try sample data*. + +. Click *Other sample data sets*. . On the *Sample eCommerce orders* card, click *Add data*. diff --git a/docs/user/dashboard/lens.asciidoc b/docs/user/dashboard/lens.asciidoc index 8e8ffe902a5652..80e1665753c157 100644 --- a/docs/user/dashboard/lens.asciidoc +++ b/docs/user/dashboard/lens.asciidoc @@ -73,7 +73,7 @@ Change the fields list to display a different {data-source}, different time rang * To add fields, open the {data-source} dropdown, then select *Add a field to this {data-source}*. + [role="screenshot"] -image:images/lens_dataViewDropDown_8.3.png[Dropdown menu located next to {data-source} field with items for adding and managing fields] +image:images/lens_dataViewDropDown_8.4.0.png[Dropdown menu located next to {data-source} field with items for adding and managing fields] + For more information about adding fields to {data-sources} and examples, refer to <>. diff --git a/docs/user/dashboard/tutorial-create-a-dashboard-of-lens-panels.asciidoc b/docs/user/dashboard/tutorial-create-a-dashboard-of-lens-panels.asciidoc index 1d4d5d70e879e8..95f937bb654435 100644 --- a/docs/user/dashboard/tutorial-create-a-dashboard-of-lens-panels.asciidoc +++ b/docs/user/dashboard/tutorial-create-a-dashboard-of-lens-panels.asciidoc @@ -8,7 +8,7 @@ at website logs, but this type of dashboard works on any type of data. When you're done, you'll have a complete overview of the sample web logs data. [role="screenshot"] -image::images/lens_logsDashboard_8.3.png[Logs dashboard] +image::images/lens_logsDashboard_8.4.0.png[Logs dashboard] Before you begin, you should be familiar with the <>. @@ -18,7 +18,9 @@ Before you begin, you should be familiar with the <>. Add the sample web logs data, and create and set up the dashboard. -. Go to the *Home* page, then click *Try sample data*. +. On the home page, click *Try sample data*. + +. Click *Other sample data sets*. . On the *Sample web logs* card, click *Add data*. @@ -38,10 +40,10 @@ Open the visualization editor, then make sure the correct fields appear. . On the dashboard, click *Create visualization*. -. Make sure the *kibana_sample_data_logs* data view appears. +. Make sure the *{kib} Sample Data Logs* {data-source} appears. + [role="screenshot"] -image::images/lens_dataViewDropDown_8.3.png[Data view dropdown] +image::images/lens_dataViewDropDown_8.4.0.png[Data view dropdown] To create the visualizations in this tutorial, you'll use the following fields: @@ -68,12 +70,12 @@ The only number function that you can use with *clientip* is *Unique count*, als . Open the *Visualization type* dropdown, then select *Metric*. + [role="screenshot"] -image::images/lens_visualizationTypeDropdown_8.0.png[Visualization type dropdown] +image::images/lens_visualizationTypeDropdown_8.4.0.png[Visualization type dropdown] . From the *Available fields* list, drag *clientip* to the workspace or layer pane. + [role="screenshot"] -image::images/lens_metricUniqueCountOfClientip_7.16.png[Metric visualization of the clientip field] +image::images/lens_metricUniqueCountOfClientip_8.4.0.png[Metric visualization of the clientip field] + In the layer pane, *Unique count of clientip* appears because the editor automatically applies the *Unique count* function to the *clientip* field. *Unique count* is the only numeric function that works with IP addresses. @@ -133,7 +135,7 @@ image::images/lens_lineChartMetricOverTimeLeftAxis_8.3.png[Left axis menu] . Open the *Bottom axis* menu, then select *None* from the *Axis title* dropdown. + [role="screenshot"] -image::images/lens_lineChartMetricOverTimeBottomAxis_8.3.png[Line chart that displays metric data over time] +image::images/lens_lineChartMetricOverTimeBottomAxis_8.3.png[Bottom axis menu] . Click *Save and return* @@ -142,6 +144,9 @@ Since you removed the axis labels, add a panel title: . Open the panel menu, then select *Edit panel title*. . In the *Panel title* field, enter `Median of bytes`, then click *Save*. ++ +[role="screenshot"] +image::images/lens_lineChartMetricOverTime_8.4.0.png[Line chart that displays metric data over time] [discrete] [[view-the-distribution-of-visitors-by-operating-system]] @@ -174,7 +179,7 @@ The chart labels are unable to display because the *request.keyword* field conta [role="screenshot"] image::images/lens_end_to_end_2_1_2.png[Table with top values of request.keyword by most unique visitors] -. In the layer pane, click *Top values of request.keyword*. +. In the layer pane, click *Top 5 values of request.keyword*. .. In the *Number of values* field, enter `10`. @@ -201,7 +206,7 @@ Create a proportional visualization that helps you determine if your users trans . In the layer pane, click *Median of bytes*. -. Click the *Sum* function, then click *Close*. +. Click the *Sum* quick function, then click *Close*. . From the *Available fields* list, drag *bytes* to the *Break down by* field in the layer pane. @@ -256,7 +261,7 @@ The distribution of a number can help you find patterns. For example, you can an . In the layer pane, click *Median of bytes*. -.. Click the *Sum* function. +.. Click the *Sum* quick function. .. In the *Name* field, enter `Transferred bytes`. @@ -293,7 +298,7 @@ Add a panel title: Create a filter for each website traffic source: -. Click the *Filters* function. +. Click *Filters*. . Click *All records*, enter the following in the query bar, then press Return: @@ -319,14 +324,14 @@ Add the user geography grouping: . From the *Available fields* list, drag *geo.srcdest* to the workspace. -. To change the *Group by* order, drag *Top values of geo.srcdest* in the layer pane so that appears first. +. To change the *Group by* order, drag *Top 3 values of geo.srcdest* in the layer pane so that appears first. + [role="screenshot"] image::images/lens_end_to_end_7_2.png[Treemap visualization] Remove the documents that do not match the filter criteria: -. In the layer pane, click *Top values of geo.srcdest*. +. In the layer pane, click *Top 3 values of geo.srcdest*. . Click *Advanced*, deselect *Group other values as "Other"*, then click *Close*. + @@ -358,7 +363,7 @@ Decrease the size of the following panels, then move the panels to the first row * *Website traffic* + [role="screenshot"] -image::images/lens_logsDashboard_8.3.png[Logs dashboard] +image::images/lens_logsDashboard_8.4.0.png[Logs dashboard] [discrete] === Save the dashboard diff --git a/docs/user/dashboard/vega.asciidoc b/docs/user/dashboard/vega.asciidoc index 9c58b9d0ecf495..371b8b949c72a5 100644 --- a/docs/user/dashboard/vega.asciidoc +++ b/docs/user/dashboard/vega.asciidoc @@ -40,9 +40,11 @@ As you edit the specs, work in small steps, and frequently save your work. Small Before starting, add the eCommerce sample data that you'll use in your spec, then create the dashboard. -. From the {kib} *Home* page, click *Try our sample data*. +. On the home page, click *Try sample data*. -. From *eCommerce sample data*, click *Add data*. +. Click *Other sample data sets*. + +. On the *Sample eCommerce orders* card, click *Add data*. . Open the main menu, then click *Dashboard*. diff --git a/legacy_rfcs/text/0015_bazel.md b/legacy_rfcs/text/0015_bazel.md index 82c93c3c7e9c18..390a2d68eb7ab7 100644 --- a/legacy_rfcs/text/0015_bazel.md +++ b/legacy_rfcs/text/0015_bazel.md @@ -191,9 +191,9 @@ A `BUILD.bazel` file will be added to the root of each package defining a `build The `@kbn/pm` package was updated in https://github.com/elastic/kibana/pull/89961 to run the new packages build target, invoked by calling `bazel build //packages:build`, before executing the existing legacy package builds. -The build targets will no longer reside within the package themselves and instead will be within the `bazel/bin` directory. To account for this, any defined dependency will need to be updated to reference the new directory (example: `link:bazel/bin/packages/elastic-datemath`). While also in this transition period, the build will need to copy over the packages from `bazel/bin` into the `node_modules` of the build target. +The build targets will no longer reside within the package themselves and instead will be within the `bazel/bin` directory. To account for this, any defined dependency will need to be updated to reference the new directory (example: `link:bazel/bin/packages/kbn-datemath`). While also in this transition period, the build will need to copy over the packages from `bazel/bin` into the `node_modules` of the build target. -Example package BUILD.bazel for `packages/elastic-datemath`: +Example package BUILD.bazel for `packages/kbn-datemath`: ```python load("@build_bazel_rules_nodejs//:index.bzl", "pkg_npm") diff --git a/nav-kibana-dev.docnav.json b/nav-kibana-dev.docnav.json index 75d0acdc8a9da6..c1ea6f702483c3 100644 --- a/nav-kibana-dev.docnav.json +++ b/nav-kibana-dev.docnav.json @@ -94,6 +94,9 @@ }, { "id": "kibDevKeyConceptsNavigation" + }, + { + "id": "kibDevDocsEmbeddables" } ] }, diff --git a/package.json b/package.json index 13bea69901fbc2..c0effd409918ac 100644 --- a/package.json +++ b/package.json @@ -91,6 +91,9 @@ "**/refractor/prismjs": "~1.27.0", "**/trim": "1.0.1", "**/typescript": "4.6.3", + "**/use-composed-ref": "^1.3.0", + "**/use-latest": "^1.2.1", + "@tanstack/query-core": "^4.2.1", "globby/fast-glob": "3.2.7", "puppeteer/node-fetch": "^2.6.7" }, @@ -102,8 +105,7 @@ "@dnd-kit/utilities": "^2.0.0", "@elastic/apm-rum": "^5.12.0", "@elastic/apm-rum-react": "^1.4.2", - "@elastic/apm-synthtrace": "link:bazel-bin/packages/elastic-apm-synthtrace", - "@elastic/charts": "47.1.1", + "@elastic/charts": "47.2.0", "@elastic/datemath": "5.0.3", "@elastic/elasticsearch": "npm:@elastic/elasticsearch-canary@8.3.0-canary.1", "@elastic/ems-client": "8.3.3", @@ -113,7 +115,6 @@ "@elastic/numeral": "^2.5.1", "@elastic/react-search-ui": "^1.14.0", "@elastic/request-crypto": "2.0.1", - "@elastic/safer-lodash-set": "link:bazel-bin/packages/elastic-safer-lodash-set", "@elastic/search-ui-app-search-connector": "^1.14.0", "@emotion/cache": "^11.9.3", "@emotion/css": "^11.9.0", @@ -139,6 +140,7 @@ "@kbn/analytics-shippers-elastic-v3-server": "link:bazel-bin/packages/analytics/shippers/elastic_v3/server", "@kbn/analytics-shippers-fullstory": "link:bazel-bin/packages/analytics/shippers/fullstory", "@kbn/apm-config-loader": "link:bazel-bin/packages/kbn-apm-config-loader", + "@kbn/apm-synthtrace": "link:bazel-bin/packages/kbn-apm-synthtrace", "@kbn/apm-utils": "link:bazel-bin/packages/kbn-apm-utils", "@kbn/chart-icons": "link:bazel-bin/packages/kbn-chart-icons", "@kbn/coloring": "link:bazel-bin/packages/kbn-coloring", @@ -235,11 +237,14 @@ "@kbn/core-preboot-server-mocks": "link:bazel-bin/packages/core/preboot/core-preboot-server-mocks", "@kbn/core-saved-objects-api-browser": "link:bazel-bin/packages/core/saved-objects/core-saved-objects-api-browser", "@kbn/core-saved-objects-api-server": "link:bazel-bin/packages/core/saved-objects/core-saved-objects-api-server", + "@kbn/core-saved-objects-base-server-internal": "link:bazel-bin/packages/core/saved-objects/core-saved-objects-base-server-internal", + "@kbn/core-saved-objects-base-server-mocks": "link:bazel-bin/packages/core/saved-objects/core-saved-objects-base-server-mocks", "@kbn/core-saved-objects-browser": "link:bazel-bin/packages/core/saved-objects/core-saved-objects-browser", "@kbn/core-saved-objects-browser-internal": "link:bazel-bin/packages/core/saved-objects/core-saved-objects-browser-internal", "@kbn/core-saved-objects-browser-mocks": "link:bazel-bin/packages/core/saved-objects/core-saved-objects-browser-mocks", "@kbn/core-saved-objects-common": "link:bazel-bin/packages/core/saved-objects/core-saved-objects-common", "@kbn/core-saved-objects-server": "link:bazel-bin/packages/core/saved-objects/core-saved-objects-server", + "@kbn/core-saved-objects-utils-server": "link:bazel-bin/packages/core/saved-objects/core-saved-objects-utils-server", "@kbn/core-test-helpers-deprecations-getters": "link:bazel-bin/packages/core/test-helpers/core-test-helpers-deprecations-getters", "@kbn/core-test-helpers-http-setup-browser": "link:bazel-bin/packages/core/test-helpers/core-test-helpers-http-setup-browser", "@kbn/core-theme-browser": "link:bazel-bin/packages/core/theme/core-theme-browser", @@ -282,6 +287,7 @@ "@kbn/plugin-discovery": "link:bazel-bin/packages/kbn-plugin-discovery", "@kbn/react-field": "link:bazel-bin/packages/kbn-react-field", "@kbn/rule-data-utils": "link:bazel-bin/packages/kbn-rule-data-utils", + "@kbn/safer-lodash-set": "link:bazel-bin/packages/kbn-safer-lodash-set", "@kbn/securitysolution-autocomplete": "link:bazel-bin/packages/kbn-securitysolution-autocomplete", "@kbn/securitysolution-es-utils": "link:bazel-bin/packages/kbn-securitysolution-es-utils", "@kbn/securitysolution-hook-utils": "link:bazel-bin/packages/kbn-securitysolution-hook-utils", @@ -307,7 +313,6 @@ "@kbn/shared-ux-card-no-data": "link:bazel-bin/packages/shared-ux/card/no_data/impl", "@kbn/shared-ux-card-no-data-mocks": "link:bazel-bin/packages/shared-ux/card/no_data/mocks", "@kbn/shared-ux-card-no-data-types": "link:bazel-bin/packages/shared-ux/card/no_data/types", - "@kbn/shared-ux-components": "link:bazel-bin/packages/kbn-shared-ux-components", "@kbn/shared-ux-link-redirect-app": "link:bazel-bin/packages/shared-ux/link/redirect_app/impl", "@kbn/shared-ux-link-redirect-app-mocks": "link:bazel-bin/packages/shared-ux/link/redirect_app/mocks", "@kbn/shared-ux-link-redirect-app-types": "link:bazel-bin/packages/shared-ux/link/redirect_app/types", @@ -317,12 +322,20 @@ "@kbn/shared-ux-page-kibana-no-data": "link:bazel-bin/packages/shared-ux/page/kibana_no_data/impl", "@kbn/shared-ux-page-kibana-no-data-mocks": "link:bazel-bin/packages/shared-ux/page/kibana_no_data/mocks", "@kbn/shared-ux-page-kibana-no-data-types": "link:bazel-bin/packages/shared-ux/page/kibana_no_data/types", + "@kbn/shared-ux-page-kibana-template": "link:bazel-bin/packages/shared-ux/page/kibana_template/impl", + "@kbn/shared-ux-page-kibana-template-mocks": "link:bazel-bin/packages/shared-ux/page/kibana_template/mocks", + "@kbn/shared-ux-page-kibana-template-types": "link:bazel-bin/packages/shared-ux/page/kibana_template/types", + "@kbn/shared-ux-page-no-data": "link:bazel-bin/packages/shared-ux/page/no_data/impl", + "@kbn/shared-ux-page-no-data-config": "link:bazel-bin/packages/shared-ux/page/no_data_config/impl", + "@kbn/shared-ux-page-no-data-config-mocks": "link:bazel-bin/packages/shared-ux/page/no_data_config/mocks", + "@kbn/shared-ux-page-no-data-config-types": "link:bazel-bin/packages/shared-ux/page/no_data_config/types", + "@kbn/shared-ux-page-no-data-mocks": "link:bazel-bin/packages/shared-ux/page/no_data/mocks", + "@kbn/shared-ux-page-no-data-types": "link:bazel-bin/packages/shared-ux/page/no_data/types", "@kbn/shared-ux-page-solution-nav": "link:bazel-bin/packages/shared-ux/page/solution_nav", "@kbn/shared-ux-prompt-no-data-views": "link:bazel-bin/packages/shared-ux/prompt/no_data_views/impl", "@kbn/shared-ux-prompt-no-data-views-mocks": "link:bazel-bin/packages/shared-ux/prompt/no_data_views/mocks", "@kbn/shared-ux-prompt-no-data-views-types": "link:bazel-bin/packages/shared-ux/prompt/no_data_views/types", - "@kbn/shared-ux-services": "link:bazel-bin/packages/kbn-shared-ux-services", - "@kbn/shared-ux-storybook": "link:bazel-bin/packages/kbn-shared-ux-storybook", + "@kbn/shared-ux-storybook-config": "link:bazel-bin/packages/shared-ux/storybook/config", "@kbn/shared-ux-storybook-mock": "link:bazel-bin/packages/shared-ux/storybook/mock", "@kbn/shared-ux-utility": "link:bazel-bin/packages/kbn-shared-ux-utility", "@kbn/std": "link:bazel-bin/packages/kbn-std", @@ -353,6 +366,8 @@ "@opentelemetry/semantic-conventions": "^1.4.0", "@reduxjs/toolkit": "^1.6.1", "@slack/webhook": "^5.0.4", + "@tanstack/react-query": "^4.2.1", + "@tanstack/react-query-devtools": "^4.2.1", "@turf/along": "6.0.1", "@turf/area": "6.0.1", "@turf/bbox": "6.0.1", @@ -380,7 +395,7 @@ "color": "^4.2.3", "commander": "^4.1.1", "compare-versions": "3.5.1", - "constate": "^1.3.2", + "constate": "^3.3.2", "content-disposition": "^0.5.4", "copy-to-clipboard": "^3.0.8", "core-js": "^3.23.5", @@ -489,7 +504,7 @@ "pluralize": "3.1.0", "polished": "^3.7.2", "pretty-ms": "6.0.0", - "prop-types": "^15.7.2", + "prop-types": "^15.8.1", "proxy-from-env": "1.0.0", "puid": "1.0.7", "puppeteer": "^10.2.0", @@ -497,39 +512,38 @@ "rbush": "^3.0.1", "re-resizable": "^6.1.1", "re2": "1.17.4", - "react": "^16.14.0", + "react": "^17.0.2", "react-ace": "^7.0.5", "react-beautiful-dnd": "^13.1.0", "react-color": "^2.13.8", - "react-dom": "^16.14.0", + "react-dom": "^17.0.2", "react-dropzone": "^4.2.9", "react-fast-compare": "^2.0.4", - "react-grid-layout": "^0.16.2", - "react-hook-form": "^7.30.0", + "react-focus-on": "^3.6.0", + "react-grid-layout": "^1.3.4", + "react-hook-form": "^7.34.2", "react-intl": "^2.8.0", - "react-is": "^16.13.1", - "react-markdown": "^4.3.1", + "react-is": "^17.0.2", + "react-markdown": "^6.0.3", "react-moment-proptypes": "^1.7.0", "react-monaco-editor": "^0.41.2", - "react-popper-tooltip": "^2.10.1", - "react-query": "^3.39.1", - "react-redux": "^7.2.0", - "react-resizable": "^1.7.5", - "react-resize-detector": "^4.2.0", - "react-reverse-portal": "^1.0.4", + "react-popper-tooltip": "^3.1.1", + "react-redux": "^7.2.8", + "react-resizable": "^3.0.4", + "react-resize-detector": "^7.1.1", + "react-reverse-portal": "^2.1.0", "react-router": "^5.2.0", "react-router-config": "^5.1.1", "react-router-dom": "^5.2.0", - "react-router-redux": "^4.0.8", - "react-shortcuts": "^2.0.0", - "react-sizeme": "^2.6.6", + "react-shortcuts": "^2.1.0", + "react-sizeme": "^3.0.2", "react-syntax-highlighter": "^15.3.1", "react-tiny-virtual-list": "^2.2.0", "react-use": "^15.3.8", - "react-virtualized": "^9.21.2", + "react-virtualized": "^9.22.3", "react-vis": "^1.8.1", "react-visibility-sensor": "^5.1.1", - "recompose": "^0.26.0", + "recompose": "^0.30.0", "reduce-reducers": "^1.0.4", "redux": "^4.1.0", "redux-actions": "^2.6.5", @@ -585,26 +599,26 @@ }, "devDependencies": { "@apidevtools/swagger-parser": "^10.0.3", - "@babel/cli": "^7.18.9", - "@babel/core": "^7.18.9", + "@babel/cli": "^7.18.10", + "@babel/core": "^7.18.10", "@babel/eslint-parser": "^7.18.9", - "@babel/eslint-plugin": "^7.17.7", - "@babel/generator": "^7.18.9", + "@babel/eslint-plugin": "^7.18.10", + "@babel/generator": "^7.18.12", "@babel/helper-plugin-utils": "^7.18.9", - "@babel/parser": "^7.18.9", + "@babel/parser": "^7.18.11", "@babel/plugin-proposal-class-properties": "^7.18.6", "@babel/plugin-proposal-export-namespace-from": "^7.18.9", "@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.6", "@babel/plugin-proposal-object-rest-spread": "^7.18.9", "@babel/plugin-proposal-optional-chaining": "^7.18.9", "@babel/plugin-proposal-private-methods": "^7.18.6", - "@babel/plugin-transform-runtime": "^7.18.9", - "@babel/preset-env": "^7.18.9", + "@babel/plugin-transform-runtime": "^7.18.10", + "@babel/preset-env": "^7.18.10", "@babel/preset-react": "^7.18.6", "@babel/preset-typescript": "^7.18.6", "@babel/register": "^7.18.9", - "@babel/traverse": "^7.18.9", - "@babel/types": "^7.18.9", + "@babel/traverse": "^7.18.11", + "@babel/types": "^7.18.10", "@bazel/ibazel": "^0.16.2", "@bazel/typescript": "4.6.2", "@cypress/code-coverage": "^3.9.12", @@ -685,11 +699,13 @@ "@storybook/addon-storyshots": "^6.4.22", "@storybook/addons": "^6.4.22", "@storybook/api": "^6.4.22", + "@storybook/client-api": "^6.4.22", "@storybook/components": "^6.4.22", "@storybook/core": "^6.4.22", "@storybook/core-common": "^6.4.22", "@storybook/core-events": "^6.4.22", "@storybook/node-logger": "^6.4.22", + "@storybook/preview-web": "^6.4.22", "@storybook/react": "^6.4.22", "@storybook/testing-react": "^1.2.4", "@storybook/theming": "^6.4.22", @@ -725,8 +741,7 @@ "@types/deep-freeze-strict": "^1.1.0", "@types/delete-empty": "^2.0.0", "@types/ejs": "^3.0.6", - "@types/elastic__apm-synthtrace": "link:bazel-bin/packages/elastic-apm-synthtrace/npm_module_types", - "@types/enzyme": "^3.10.8", + "@types/enzyme": "^3.10.12", "@types/eslint": "^7.28.0", "@types/express": "^4.17.13", "@types/extract-zip": "^1.6.2", @@ -753,7 +768,6 @@ "@types/intl-relativeformat": "^2.1.0", "@types/jest": "^26.0.22", "@types/jest-axe": "^3.5.3", - "@types/jest-specific-snapshot": "^0.5.5", "@types/joi": "^17.2.3", "@types/jquery": "^3.3.31", "@types/js-levenshtein": "^1.1.0", @@ -775,6 +789,7 @@ "@types/kbn__analytics-shippers-elastic-v3-server": "link:bazel-bin/packages/analytics/shippers/elastic_v3/server/npm_module_types", "@types/kbn__analytics-shippers-fullstory": "link:bazel-bin/packages/analytics/shippers/fullstory/npm_module_types", "@types/kbn__apm-config-loader": "link:bazel-bin/packages/kbn-apm-config-loader/npm_module_types", + "@types/kbn__apm-synthtrace": "link:bazel-bin/packages/kbn-apm-synthtrace/npm_module_types", "@types/kbn__apm-utils": "link:bazel-bin/packages/kbn-apm-utils/npm_module_types", "@types/kbn__axe-config": "link:bazel-bin/packages/kbn-axe-config/npm_module_types", "@types/kbn__bazel-packages": "link:bazel-bin/packages/kbn-bazel-packages/npm_module_types", @@ -882,11 +897,14 @@ "@types/kbn__core-public-internal-base": "link:bazel-bin/packages/core/public/internal-base/npm_module_types", "@types/kbn__core-saved-objects-api-browser": "link:bazel-bin/packages/core/saved-objects/core-saved-objects-api-browser/npm_module_types", "@types/kbn__core-saved-objects-api-server": "link:bazel-bin/packages/core/saved-objects/core-saved-objects-api-server/npm_module_types", + "@types/kbn__core-saved-objects-base-server-internal": "link:bazel-bin/packages/core/saved-objects/core-saved-objects-base-server-internal/npm_module_types", + "@types/kbn__core-saved-objects-base-server-mocks": "link:bazel-bin/packages/core/saved-objects/core-saved-objects-base-server-mocks/npm_module_types", "@types/kbn__core-saved-objects-browser": "link:bazel-bin/packages/core/saved-objects/core-saved-objects-browser/npm_module_types", "@types/kbn__core-saved-objects-browser-internal": "link:bazel-bin/packages/core/saved-objects/core-saved-objects-browser-internal/npm_module_types", "@types/kbn__core-saved-objects-browser-mocks": "link:bazel-bin/packages/core/saved-objects/core-saved-objects-browser-mocks/npm_module_types", "@types/kbn__core-saved-objects-common": "link:bazel-bin/packages/core/saved-objects/core-saved-objects-common/npm_module_types", "@types/kbn__core-saved-objects-server": "link:bazel-bin/packages/core/saved-objects/core-saved-objects-server/npm_module_types", + "@types/kbn__core-saved-objects-utils-server": "link:bazel-bin/packages/core/saved-objects/core-saved-objects-utils-server/npm_module_types", "@types/kbn__core-server-internal-base": "link:bazel-bin/packages/core/server/internal-base/npm_module_types", "@types/kbn__core-test-helpers-deprecations-getters": "link:bazel-bin/packages/core/test-helpers/core-test-helpers-deprecations-getters/npm_module_types", "@types/kbn__core-test-helpers-http-setup-browser": "link:bazel-bin/packages/core/test-helpers/core-test-helpers-http-setup-browser/npm_module_types", @@ -975,7 +993,6 @@ "@types/kbn__shared-ux-card-no-data": "link:bazel-bin/packages/shared-ux/card/no_data/impl/npm_module_types", "@types/kbn__shared-ux-card-no-data-mocks": "link:bazel-bin/packages/shared-ux/card/no_data/mocks/npm_module_types", "@types/kbn__shared-ux-card-no-data-types": "link:bazel-bin/packages/shared-ux/card/no_data/types/npm_module_types", - "@types/kbn__shared-ux-components": "link:bazel-bin/packages/kbn-shared-ux-components/npm_module_types", "@types/kbn__shared-ux-link-redirect-app": "link:bazel-bin/packages/shared-ux/link/redirect_app/impl/npm_module_types", "@types/kbn__shared-ux-link-redirect-app-mocks": "link:bazel-bin/packages/shared-ux/link/redirect_app/mocks/npm_module_types", "@types/kbn__shared-ux-link-redirect-app-types": "link:bazel-bin/packages/shared-ux/link/redirect_app/types/npm_module_types", @@ -985,12 +1002,20 @@ "@types/kbn__shared-ux-page-kibana-no-data": "link:bazel-bin/packages/shared-ux/page/kibana_no_data/impl/npm_module_types", "@types/kbn__shared-ux-page-kibana-no-data-mocks": "link:bazel-bin/packages/shared-ux/page/kibana_no_data/mocks/npm_module_types", "@types/kbn__shared-ux-page-kibana-no-data-types": "link:bazel-bin/packages/shared-ux/page/kibana_no_data/types/npm_module_types", + "@types/kbn__shared-ux-page-kibana-template": "link:bazel-bin/packages/shared-ux/page/kibana_template/impl/npm_module_types", + "@types/kbn__shared-ux-page-kibana-template-mocks": "link:bazel-bin/packages/shared-ux/page/kibana_template/mocks/npm_module_types", + "@types/kbn__shared-ux-page-kibana-template-types": "link:bazel-bin/packages/shared-ux/page/kibana_template/types/npm_module_types", + "@types/kbn__shared-ux-page-no-data": "link:bazel-bin/packages/shared-ux/page/no_data/impl/npm_module_types", + "@types/kbn__shared-ux-page-no-data-config": "link:bazel-bin/packages/shared-ux/page/no_data_config/impl/npm_module_types", + "@types/kbn__shared-ux-page-no-data-config-mocks": "link:bazel-bin/packages/shared-ux/page/no_data_config/mocks/npm_module_types", + "@types/kbn__shared-ux-page-no-data-config-types": "link:bazel-bin/packages/shared-ux/page/no_data_config/types/npm_module_types", + "@types/kbn__shared-ux-page-no-data-mocks": "link:bazel-bin/packages/shared-ux/page/no_data/mocks/npm_module_types", + "@types/kbn__shared-ux-page-no-data-types": "link:bazel-bin/packages/shared-ux/page/no_data/types/npm_module_types", "@types/kbn__shared-ux-page-solution-nav": "link:bazel-bin/packages/shared-ux/page/solution_nav/npm_module_types", "@types/kbn__shared-ux-prompt-no-data-views": "link:bazel-bin/packages/shared-ux/prompt/no_data_views/impl/npm_module_types", "@types/kbn__shared-ux-prompt-no-data-views-mocks": "link:bazel-bin/packages/shared-ux/prompt/no_data_views/mocks/npm_module_types", "@types/kbn__shared-ux-prompt-no-data-views-types": "link:bazel-bin/packages/shared-ux/prompt/no_data_views/types/npm_module_types", - "@types/kbn__shared-ux-services": "link:bazel-bin/packages/kbn-shared-ux-services/npm_module_types", - "@types/kbn__shared-ux-storybook": "link:bazel-bin/packages/kbn-shared-ux-storybook/npm_module_types", + "@types/kbn__shared-ux-storybook-config": "link:bazel-bin/packages/shared-ux/storybook/config/npm_module_types", "@types/kbn__shared-ux-storybook-mock": "link:bazel-bin/packages/shared-ux/storybook/mock/npm_module_types", "@types/kbn__shared-ux-utility": "link:bazel-bin/packages/kbn-shared-ux-utility/npm_module_types", "@types/kbn__some-dev-log": "link:bazel-bin/packages/kbn-some-dev-log/npm_module_types", @@ -1049,23 +1074,22 @@ "@types/pngjs": "^3.4.0", "@types/prettier": "^2.3.2", "@types/pretty-ms": "^5.0.0", - "@types/prop-types": "^15.7.3", + "@types/prop-types": "^15.7.5", "@types/rbush": "^3.0.0", - "@types/react": "^16.14.25", + "@types/react": "^17.0.45", "@types/react-beautiful-dnd": "^13.0.0", - "@types/react-dom": "^16.9.15", - "@types/react-grid-layout": "^0.16.7", + "@types/react-dom": "^17.0.17", + "@types/react-grid-layout": "^1.3.2", "@types/react-intl": "^2.3.15", - "@types/react-is": "^16.7.2", - "@types/react-redux": "^7.1.9", - "@types/react-resize-detector": "^4.0.1", + "@types/react-is": "^17.0.3", + "@types/react-resize-detector": "^6.1.0", "@types/react-router": "^5.1.7", "@types/react-router-config": "^5.0.2", "@types/react-router-dom": "^5.1.5", - "@types/react-test-renderer": "^16.9.1", - "@types/react-virtualized": "^9.18.7", + "@types/react-test-renderer": "^17.0.2", + "@types/react-virtualized": "^9.21.21", "@types/react-vis": "^1.11.9", - "@types/recompose": "^0.30.6", + "@types/recompose": "^0.30.10", "@types/reduce-reducers": "^1.0.0", "@types/redux-actions": "^2.6.1", "@types/redux-logger": "^3.0.8", @@ -1105,6 +1129,7 @@ "@typescript-eslint/eslint-plugin": "^5.20.0", "@typescript-eslint/parser": "^5.20.0", "@typescript-eslint/typescript-estree": "^5.20.0", + "@wojtekmaj/enzyme-adapter-react-17": "^0.6.7", "@yarnpkg/lockfile": "^1.1.0", "abab": "^2.0.4", "aggregate-error": "^3.1.0", @@ -1150,8 +1175,6 @@ "dpdm": "3.5.0", "ejs": "^3.1.8", "enzyme": "^3.11.0", - "enzyme-adapter-react-16": "^1.15.6", - "enzyme-adapter-utils": "^1.14.0", "enzyme-to-json": "^3.6.1", "eslint": "^7.32.0", "eslint-config-prettier": "^8.5.0", @@ -1199,15 +1222,15 @@ "jest-config": "^26", "jest-diff": "^26.6.2", "jest-environment-jsdom": "^26.6.2", - "jest-environment-jsdom-thirteen": "^1.0.1", + "jest-mock": "^26.6.2", "jest-raw-loader": "^1.0.1", "jest-runtime": "^26", "jest-silent-reporter": "^0.5.0", "jest-snapshot": "^26.6.2", - "jest-specific-snapshot": "2.0.0", + "jest-specific-snapshot": "^4.0.0", "jest-styled-components": "^7.0.3", "jimp": "^0.14.0", - "jsdom": "13.1.0", + "jsdom": "^16.4.0", "json-schema-typed": "^8.0.1", "json5": "^1.0.1", "jsondiffpatch": "0.4.1", @@ -1216,7 +1239,7 @@ "lmdb-store": "^1.6.11", "loader-utils": "^1.2.3", "marge": "^1.0.1", - "micromatch": "3.1.10", + "micromatch": "^4.0.5", "mini-css-extract-plugin": "1.1.0", "minimist": "^1.2.6", "mocha": "^10.0.0", @@ -1247,10 +1270,10 @@ "proxy": "^1.0.2", "q": "^1.5.1", "raw-loader": "^3.1.0", - "react-test-renderer": "^16.14.0", + "react-test-renderer": "^17.0.2", "regenerate": "^1.4.0", "resolve": "^1.22.0", - "rxjs-marbles": "^5.0.6", + "rxjs-marbles": "^7.0.1", "sass-loader": "^10.3.1", "selenium-webdriver": "^4.4.0", "simple-git": "^3.10.0", diff --git a/packages/BUILD.bazel b/packages/BUILD.bazel index 48977f7ef4fc85..812d73e82826f3 100644 --- a/packages/BUILD.bazel +++ b/packages/BUILD.bazel @@ -14,110 +14,111 @@ filegroup( "//packages/analytics/shippers/elastic_v3/common:build", "//packages/analytics/shippers/elastic_v3/server:build", "//packages/analytics/shippers/fullstory:build", + "//packages/core/analytics/core-analytics-browser:build", "//packages/core/analytics/core-analytics-browser-internal:build", "//packages/core/analytics/core-analytics-browser-mocks:build", - "//packages/core/analytics/core-analytics-browser:build", + "//packages/core/analytics/core-analytics-server:build", "//packages/core/analytics/core-analytics-server-internal:build", "//packages/core/analytics/core-analytics-server-mocks:build", - "//packages/core/analytics/core-analytics-server:build", "//packages/core/base/core-base-browser-internal:build", "//packages/core/base/core-base-browser-mocks:build", - "//packages/core/base/core-base-common-internal:build", "//packages/core/base/core-base-common:build", + "//packages/core/base/core-base-common-internal:build", "//packages/core/base/core-base-server-internal:build", "//packages/core/base/core-base-server-mocks:build", "//packages/core/capabilities/core-capabilities-common:build", + "//packages/core/capabilities/core-capabilities-server:build", "//packages/core/capabilities/core-capabilities-server-internal:build", "//packages/core/capabilities/core-capabilities-server-mocks:build", - "//packages/core/capabilities/core-capabilities-server:build", "//packages/core/config/core-config-server-internal:build", + "//packages/core/deprecations/core-deprecations-browser:build", "//packages/core/deprecations/core-deprecations-browser-internal:build", "//packages/core/deprecations/core-deprecations-browser-mocks:build", - "//packages/core/deprecations/core-deprecations-browser:build", "//packages/core/deprecations/core-deprecations-common:build", + "//packages/core/doc-links/core-doc-links-browser:build", "//packages/core/doc-links/core-doc-links-browser-internal:build", "//packages/core/doc-links/core-doc-links-browser-mocks:build", - "//packages/core/doc-links/core-doc-links-browser:build", + "//packages/core/doc-links/core-doc-links-server:build", "//packages/core/doc-links/core-doc-links-server-internal:build", "//packages/core/doc-links/core-doc-links-server-mocks:build", - "//packages/core/doc-links/core-doc-links-server:build", "//packages/core/elasticsearch/core-elasticsearch-client-server-internal:build", "//packages/core/elasticsearch/core-elasticsearch-client-server-mocks:build", + "//packages/core/elasticsearch/core-elasticsearch-server:build", "//packages/core/elasticsearch/core-elasticsearch-server-internal:build", "//packages/core/elasticsearch/core-elasticsearch-server-mocks:build", - "//packages/core/elasticsearch/core-elasticsearch-server:build", "//packages/core/environment/core-environment-server-internal:build", "//packages/core/environment/core-environment-server-mocks:build", + "//packages/core/execution-context/core-execution-context-browser:build", "//packages/core/execution-context/core-execution-context-browser-internal:build", "//packages/core/execution-context/core-execution-context-browser-mocks:build", - "//packages/core/execution-context/core-execution-context-browser:build", "//packages/core/execution-context/core-execution-context-common:build", + "//packages/core/execution-context/core-execution-context-server:build", "//packages/core/execution-context/core-execution-context-server-internal:build", "//packages/core/execution-context/core-execution-context-server-mocks:build", - "//packages/core/execution-context/core-execution-context-server:build", + "//packages/core/fatal-errors/core-fatal-errors-browser:build", "//packages/core/fatal-errors/core-fatal-errors-browser-internal:build", "//packages/core/fatal-errors/core-fatal-errors-browser-mocks:build", - "//packages/core/fatal-errors/core-fatal-errors-browser:build", + "//packages/core/http/core-http-browser:build", "//packages/core/http/core-http-browser-internal:build", "//packages/core/http/core-http-browser-mocks:build", - "//packages/core/http/core-http-browser:build", "//packages/core/http/core-http-common:build", "//packages/core/http/core-http-context-server-internal:build", "//packages/core/http/core-http-context-server-mocks:build", "//packages/core/http/core-http-router-server-internal:build", "//packages/core/http/core-http-router-server-mocks:build", + "//packages/core/http/core-http-server:build", "//packages/core/http/core-http-server-internal:build", "//packages/core/http/core-http-server-mocks:build", - "//packages/core/http/core-http-server:build", + "//packages/core/i18n/core-i18n-browser:build", "//packages/core/i18n/core-i18n-browser-internal:build", "//packages/core/i18n/core-i18n-browser-mocks:build", - "//packages/core/i18n/core-i18n-browser:build", + "//packages/core/injected-metadata/core-injected-metadata-browser:build", "//packages/core/injected-metadata/core-injected-metadata-browser-internal:build", "//packages/core/injected-metadata/core-injected-metadata-browser-mocks:build", - "//packages/core/injected-metadata/core-injected-metadata-browser:build", "//packages/core/injected-metadata/core-injected-metadata-common-internal:build", "//packages/core/integrations/core-integrations-browser-internal:build", "//packages/core/integrations/core-integrations-browser-mocks:build", + "//packages/core/logging/core-logging-server:build", "//packages/core/logging/core-logging-server-internal:build", "//packages/core/logging/core-logging-server-mocks:build", - "//packages/core/logging/core-logging-server:build", "//packages/core/metrics/core-metrics-collectors-server-internal:build", "//packages/core/metrics/core-metrics-collectors-server-mocks:build", + "//packages/core/metrics/core-metrics-server:build", "//packages/core/metrics/core-metrics-server-internal:build", "//packages/core/metrics/core-metrics-server-mocks:build", - "//packages/core/metrics/core-metrics-server:build", - "//packages/core/mount-utils/core-mount-utils-browser-internal:build", "//packages/core/mount-utils/core-mount-utils-browser:build", + "//packages/core/mount-utils/core-mount-utils-browser-internal:build", + "//packages/core/node/core-node-server:build", "//packages/core/node/core-node-server-internal:build", "//packages/core/node/core-node-server-mocks:build", - "//packages/core/node/core-node-server:build", + "//packages/core/notifications/core-notifications-browser:build", "//packages/core/notifications/core-notifications-browser-internal:build", "//packages/core/notifications/core-notifications-browser-mocks:build", - "//packages/core/notifications/core-notifications-browser:build", + "//packages/core/overlays/core-overlays-browser:build", "//packages/core/overlays/core-overlays-browser-internal:build", "//packages/core/overlays/core-overlays-browser-mocks:build", - "//packages/core/overlays/core-overlays-browser:build", + "//packages/core/preboot/core-preboot-server:build", "//packages/core/preboot/core-preboot-server-internal:build", "//packages/core/preboot/core-preboot-server-mocks:build", - "//packages/core/preboot/core-preboot-server:build", "//packages/core/saved-objects/core-saved-objects-api-browser:build", "//packages/core/saved-objects/core-saved-objects-api-server:build", + "//packages/core/saved-objects/core-saved-objects-base-server-internal:build", + "//packages/core/saved-objects/core-saved-objects-base-server-mocks:build", + "//packages/core/saved-objects/core-saved-objects-browser:build", "//packages/core/saved-objects/core-saved-objects-browser-internal:build", "//packages/core/saved-objects/core-saved-objects-browser-mocks:build", - "//packages/core/saved-objects/core-saved-objects-browser:build", "//packages/core/saved-objects/core-saved-objects-common:build", "//packages/core/saved-objects/core-saved-objects-server:build", + "//packages/core/saved-objects/core-saved-objects-utils-server:build", "//packages/core/test-helpers/core-test-helpers-deprecations-getters:build", "//packages/core/test-helpers/core-test-helpers-http-setup-browser:build", + "//packages/core/theme/core-theme-browser:build", "//packages/core/theme/core-theme-browser-internal:build", "//packages/core/theme/core-theme-browser-mocks:build", - "//packages/core/theme/core-theme-browser:build", + "//packages/core/ui-settings/core-ui-settings-browser:build", "//packages/core/ui-settings/core-ui-settings-browser-internal:build", "//packages/core/ui-settings/core-ui-settings-browser-mocks:build", - "//packages/core/ui-settings/core-ui-settings-browser:build", "//packages/core/ui-settings/core-ui-settings-common:build", - "//packages/elastic-apm-synthtrace:build", - "//packages/elastic-safer-lodash-set:build", "//packages/home/sample_data_card:build", "//packages/home/sample_data_tab:build", "//packages/home/sample_data_types:build", @@ -127,6 +128,7 @@ filegroup( "//packages/kbn-ambient-ui-types:build", "//packages/kbn-analytics:build", "//packages/kbn-apm-config-loader:build", + "//packages/kbn-apm-synthtrace:build", "//packages/kbn-apm-utils:build", "//packages/kbn-axe-config:build", "//packages/kbn-babel-plugin-synthetic-packages:build", @@ -139,11 +141,11 @@ filegroup( "//packages/kbn-ci-stats-reporter:build", "//packages/kbn-cli-dev-mode:build", "//packages/kbn-coloring:build", + "//packages/kbn-config:build", "//packages/kbn-config-mocks:build", "//packages/kbn-config-schema:build", - "//packages/kbn-config:build", - "//packages/kbn-crypto-browser:build", "//packages/kbn-crypto:build", + "//packages/kbn-crypto-browser:build", "//packages/kbn-datemath:build", "//packages/kbn-dev-cli-errors:build", "//packages/kbn-dev-cli-runner:build", @@ -152,10 +154,10 @@ filegroup( "//packages/kbn-doc-links:build", "//packages/kbn-docs-utils:build", "//packages/kbn-ebt-tools:build", + "//packages/kbn-es:build", "//packages/kbn-es-archiver:build", "//packages/kbn-es-errors:build", "//packages/kbn-es-query:build", - "//packages/kbn-es:build", "//packages/kbn-eslint-config:build", "//packages/kbn-eslint-plugin-disable:build", "//packages/kbn-eslint-plugin-eslint:build", @@ -168,8 +170,8 @@ filegroup( "//packages/kbn-get-repo-files:build", "//packages/kbn-handlebars:build", "//packages/kbn-hapi-mocks:build", - "//packages/kbn-i18n-react:build", "//packages/kbn-i18n:build", + "//packages/kbn-i18n-react:build", "//packages/kbn-import-resolver:build", "//packages/kbn-interpreter:build", "//packages/kbn-io-ts-utils:build", @@ -177,22 +179,23 @@ filegroup( "//packages/kbn-jsonc:build", "//packages/kbn-kibana-manifest-parser:build", "//packages/kbn-kibana-manifest-schema:build", - "//packages/kbn-logging-mocks:build", "//packages/kbn-logging:build", - "//packages/kbn-managed-vscode-config-cli:build", + "//packages/kbn-logging-mocks:build", "//packages/kbn-managed-vscode-config:build", + "//packages/kbn-managed-vscode-config-cli:build", "//packages/kbn-mapbox-gl:build", "//packages/kbn-monaco:build", - "//packages/kbn-optimizer-webpack-helpers:build", "//packages/kbn-optimizer:build", + "//packages/kbn-optimizer-webpack-helpers:build", "//packages/kbn-performance-testing-dataset-extractor:build", "//packages/kbn-plugin-discovery:build", "//packages/kbn-plugin-generator:build", "//packages/kbn-plugin-helpers:build", "//packages/kbn-react-field:build", - "//packages/kbn-repo-source-classifier-cli:build", "//packages/kbn-repo-source-classifier:build", + "//packages/kbn-repo-source-classifier-cli:build", "//packages/kbn-rule-data-utils:build", + "//packages/kbn-safer-lodash-set:build", "//packages/kbn-securitysolution-autocomplete:build", "//packages/kbn-securitysolution-es-utils:build", "//packages/kbn-securitysolution-hook-utils:build", @@ -210,9 +213,6 @@ filegroup( "//packages/kbn-server-http-tools:build", "//packages/kbn-server-route-repository:build", "//packages/kbn-shared-svg:build", - "//packages/kbn-shared-ux-components:build", - "//packages/kbn-shared-ux-services:build", - "//packages/kbn-shared-ux-storybook:build", "//packages/kbn-shared-ux-utility:build", "//packages/kbn-some-dev-log:build", "//packages/kbn-sort-package-json:build", @@ -222,23 +222,23 @@ filegroup( "//packages/kbn-storybook:build", "//packages/kbn-synthetic-package-map:build", "//packages/kbn-telemetry-tools:build", + "//packages/kbn-test:build", "//packages/kbn-test-jest-helpers:build", "//packages/kbn-test-subj-selector:build", - "//packages/kbn-test:build", "//packages/kbn-timelion-grammar:build", "//packages/kbn-tinymath:build", "//packages/kbn-tooling-log:build", + "//packages/kbn-type-summarizer:build", "//packages/kbn-type-summarizer-cli:build", "//packages/kbn-type-summarizer-core:build", - "//packages/kbn-type-summarizer:build", "//packages/kbn-typed-react-router-config:build", "//packages/kbn-ui-framework:build", "//packages/kbn-ui-shared-deps-npm:build", "//packages/kbn-ui-shared-deps-src:build", "//packages/kbn-ui-theme:build", "//packages/kbn-user-profile-components:build", - "//packages/kbn-utility-types-jest:build", "//packages/kbn-utility-types:build", + "//packages/kbn-utility-types-jest:build", "//packages/kbn-utils:build", "//packages/kbn-yarn-lock-validator:build", "//packages/shared-ux/avatar/solution:build", @@ -258,10 +258,20 @@ filegroup( "//packages/shared-ux/page/kibana_no_data/impl:build", "//packages/shared-ux/page/kibana_no_data/mocks:build", "//packages/shared-ux/page/kibana_no_data/types:build", + "//packages/shared-ux/page/kibana_template/impl:build", + "//packages/shared-ux/page/kibana_template/mocks:build", + "//packages/shared-ux/page/kibana_template/types:build", + "//packages/shared-ux/page/no_data_config/impl:build", + "//packages/shared-ux/page/no_data_config/mocks:build", + "//packages/shared-ux/page/no_data_config/types:build", + "//packages/shared-ux/page/no_data/impl:build", + "//packages/shared-ux/page/no_data/mocks:build", + "//packages/shared-ux/page/no_data/types:build", "//packages/shared-ux/page/solution_nav:build", "//packages/shared-ux/prompt/no_data_views/impl:build", "//packages/shared-ux/prompt/no_data_views/mocks:build", "//packages/shared-ux/prompt/no_data_views/types:build", + "//packages/shared-ux/storybook/config:build", "//packages/shared-ux/storybook/mock:build", "//x-pack/packages/ml/agg_utils:build", "//x-pack/packages/ml/aiops_components:build", @@ -280,116 +290,118 @@ filegroup( "//packages/analytics/shippers/elastic_v3/common:build_types", "//packages/analytics/shippers/elastic_v3/server:build_types", "//packages/analytics/shippers/fullstory:build_types", + "//packages/core/analytics/core-analytics-browser:build_types", "//packages/core/analytics/core-analytics-browser-internal:build_types", "//packages/core/analytics/core-analytics-browser-mocks:build_types", - "//packages/core/analytics/core-analytics-browser:build_types", + "//packages/core/analytics/core-analytics-server:build_types", "//packages/core/analytics/core-analytics-server-internal:build_types", "//packages/core/analytics/core-analytics-server-mocks:build_types", - "//packages/core/analytics/core-analytics-server:build_types", "//packages/core/base/core-base-browser-internal:build_types", "//packages/core/base/core-base-browser-mocks:build_types", - "//packages/core/base/core-base-common-internal:build_types", "//packages/core/base/core-base-common:build_types", + "//packages/core/base/core-base-common-internal:build_types", "//packages/core/base/core-base-server-internal:build_types", "//packages/core/base/core-base-server-mocks:build_types", "//packages/core/capabilities/core-capabilities-common:build_types", + "//packages/core/capabilities/core-capabilities-server:build_types", "//packages/core/capabilities/core-capabilities-server-internal:build_types", "//packages/core/capabilities/core-capabilities-server-mocks:build_types", - "//packages/core/capabilities/core-capabilities-server:build_types", "//packages/core/config/core-config-server-internal:build_types", + "//packages/core/deprecations/core-deprecations-browser:build_types", "//packages/core/deprecations/core-deprecations-browser-internal:build_types", "//packages/core/deprecations/core-deprecations-browser-mocks:build_types", - "//packages/core/deprecations/core-deprecations-browser:build_types", "//packages/core/deprecations/core-deprecations-common:build_types", + "//packages/core/doc-links/core-doc-links-browser:build_types", "//packages/core/doc-links/core-doc-links-browser-internal:build_types", "//packages/core/doc-links/core-doc-links-browser-mocks:build_types", - "//packages/core/doc-links/core-doc-links-browser:build_types", + "//packages/core/doc-links/core-doc-links-server:build_types", "//packages/core/doc-links/core-doc-links-server-internal:build_types", "//packages/core/doc-links/core-doc-links-server-mocks:build_types", - "//packages/core/doc-links/core-doc-links-server:build_types", "//packages/core/elasticsearch/core-elasticsearch-client-server-internal:build_types", "//packages/core/elasticsearch/core-elasticsearch-client-server-mocks:build_types", + "//packages/core/elasticsearch/core-elasticsearch-server:build_types", "//packages/core/elasticsearch/core-elasticsearch-server-internal:build_types", "//packages/core/elasticsearch/core-elasticsearch-server-mocks:build_types", - "//packages/core/elasticsearch/core-elasticsearch-server:build_types", "//packages/core/environment/core-environment-server-internal:build_types", "//packages/core/environment/core-environment-server-mocks:build_types", + "//packages/core/execution-context/core-execution-context-browser:build_types", "//packages/core/execution-context/core-execution-context-browser-internal:build_types", "//packages/core/execution-context/core-execution-context-browser-mocks:build_types", - "//packages/core/execution-context/core-execution-context-browser:build_types", "//packages/core/execution-context/core-execution-context-common:build_types", + "//packages/core/execution-context/core-execution-context-server:build_types", "//packages/core/execution-context/core-execution-context-server-internal:build_types", "//packages/core/execution-context/core-execution-context-server-mocks:build_types", - "//packages/core/execution-context/core-execution-context-server:build_types", + "//packages/core/fatal-errors/core-fatal-errors-browser:build_types", "//packages/core/fatal-errors/core-fatal-errors-browser-internal:build_types", "//packages/core/fatal-errors/core-fatal-errors-browser-mocks:build_types", - "//packages/core/fatal-errors/core-fatal-errors-browser:build_types", + "//packages/core/http/core-http-browser:build_types", "//packages/core/http/core-http-browser-internal:build_types", "//packages/core/http/core-http-browser-mocks:build_types", - "//packages/core/http/core-http-browser:build_types", "//packages/core/http/core-http-common:build_types", "//packages/core/http/core-http-context-server-internal:build_types", "//packages/core/http/core-http-context-server-mocks:build_types", "//packages/core/http/core-http-router-server-internal:build_types", "//packages/core/http/core-http-router-server-mocks:build_types", + "//packages/core/http/core-http-server:build_types", "//packages/core/http/core-http-server-internal:build_types", "//packages/core/http/core-http-server-mocks:build_types", - "//packages/core/http/core-http-server:build_types", + "//packages/core/i18n/core-i18n-browser:build_types", "//packages/core/i18n/core-i18n-browser-internal:build_types", "//packages/core/i18n/core-i18n-browser-mocks:build_types", - "//packages/core/i18n/core-i18n-browser:build_types", + "//packages/core/injected-metadata/core-injected-metadata-browser:build_types", "//packages/core/injected-metadata/core-injected-metadata-browser-internal:build_types", "//packages/core/injected-metadata/core-injected-metadata-browser-mocks:build_types", - "//packages/core/injected-metadata/core-injected-metadata-browser:build_types", "//packages/core/injected-metadata/core-injected-metadata-common-internal:build_types", "//packages/core/integrations/core-integrations-browser-internal:build_types", "//packages/core/integrations/core-integrations-browser-mocks:build_types", + "//packages/core/logging/core-logging-server:build_types", "//packages/core/logging/core-logging-server-internal:build_types", "//packages/core/logging/core-logging-server-mocks:build_types", - "//packages/core/logging/core-logging-server:build_types", "//packages/core/metrics/core-metrics-collectors-server-internal:build_types", "//packages/core/metrics/core-metrics-collectors-server-mocks:build_types", + "//packages/core/metrics/core-metrics-server:build_types", "//packages/core/metrics/core-metrics-server-internal:build_types", "//packages/core/metrics/core-metrics-server-mocks:build_types", - "//packages/core/metrics/core-metrics-server:build_types", - "//packages/core/mount-utils/core-mount-utils-browser-internal:build_types", "//packages/core/mount-utils/core-mount-utils-browser:build_types", + "//packages/core/mount-utils/core-mount-utils-browser-internal:build_types", + "//packages/core/node/core-node-server:build_types", "//packages/core/node/core-node-server-internal:build_types", "//packages/core/node/core-node-server-mocks:build_types", - "//packages/core/node/core-node-server:build_types", + "//packages/core/notifications/core-notifications-browser:build_types", "//packages/core/notifications/core-notifications-browser-internal:build_types", "//packages/core/notifications/core-notifications-browser-mocks:build_types", - "//packages/core/notifications/core-notifications-browser:build_types", + "//packages/core/overlays/core-overlays-browser:build_types", "//packages/core/overlays/core-overlays-browser-internal:build_types", "//packages/core/overlays/core-overlays-browser-mocks:build_types", - "//packages/core/overlays/core-overlays-browser:build_types", + "//packages/core/preboot/core-preboot-server:build_types", "//packages/core/preboot/core-preboot-server-internal:build_types", "//packages/core/preboot/core-preboot-server-mocks:build_types", - "//packages/core/preboot/core-preboot-server:build_types", "//packages/core/saved-objects/core-saved-objects-api-browser:build_types", "//packages/core/saved-objects/core-saved-objects-api-server:build_types", + "//packages/core/saved-objects/core-saved-objects-base-server-internal:build_types", + "//packages/core/saved-objects/core-saved-objects-base-server-mocks:build_types", + "//packages/core/saved-objects/core-saved-objects-browser:build_types", "//packages/core/saved-objects/core-saved-objects-browser-internal:build_types", "//packages/core/saved-objects/core-saved-objects-browser-mocks:build_types", - "//packages/core/saved-objects/core-saved-objects-browser:build_types", "//packages/core/saved-objects/core-saved-objects-common:build_types", "//packages/core/saved-objects/core-saved-objects-server:build_types", + "//packages/core/saved-objects/core-saved-objects-utils-server:build_types", "//packages/core/test-helpers/core-test-helpers-deprecations-getters:build_types", "//packages/core/test-helpers/core-test-helpers-http-setup-browser:build_types", + "//packages/core/theme/core-theme-browser:build_types", "//packages/core/theme/core-theme-browser-internal:build_types", "//packages/core/theme/core-theme-browser-mocks:build_types", - "//packages/core/theme/core-theme-browser:build_types", + "//packages/core/ui-settings/core-ui-settings-browser:build_types", "//packages/core/ui-settings/core-ui-settings-browser-internal:build_types", "//packages/core/ui-settings/core-ui-settings-browser-mocks:build_types", - "//packages/core/ui-settings/core-ui-settings-browser:build_types", "//packages/core/ui-settings/core-ui-settings-common:build_types", - "//packages/elastic-apm-synthtrace:build_types", - "//packages/elastic-safer-lodash-set:build_types", "//packages/home/sample_data_card:build_types", "//packages/home/sample_data_tab:build_types", "//packages/kbn-ace:build_types", "//packages/kbn-alerts:build_types", "//packages/kbn-analytics:build_types", "//packages/kbn-apm-config-loader:build_types", + "//packages/kbn-apm-synthtrace:build_types", "//packages/kbn-apm-utils:build_types", "//packages/kbn-axe-config:build_types", "//packages/kbn-bazel-packages:build_types", @@ -400,11 +412,11 @@ filegroup( "//packages/kbn-ci-stats-reporter:build_types", "//packages/kbn-cli-dev-mode:build_types", "//packages/kbn-coloring:build_types", + "//packages/kbn-config:build_types", "//packages/kbn-config-mocks:build_types", "//packages/kbn-config-schema:build_types", - "//packages/kbn-config:build_types", - "//packages/kbn-crypto-browser:build_types", "//packages/kbn-crypto:build_types", + "//packages/kbn-crypto-browser:build_types", "//packages/kbn-datemath:build_types", "//packages/kbn-dev-cli-errors:build_types", "//packages/kbn-dev-cli-runner:build_types", @@ -424,8 +436,8 @@ filegroup( "//packages/kbn-get-repo-files:build_types", "//packages/kbn-handlebars:build_types", "//packages/kbn-hapi-mocks:build_types", - "//packages/kbn-i18n-react:build_types", "//packages/kbn-i18n:build_types", + "//packages/kbn-i18n-react:build_types", "//packages/kbn-import-resolver:build_types", "//packages/kbn-interpreter:build_types", "//packages/kbn-io-ts-utils:build_types", @@ -433,22 +445,23 @@ filegroup( "//packages/kbn-jsonc:build_types", "//packages/kbn-kibana-manifest-parser:build_types", "//packages/kbn-kibana-manifest-schema:build_types", - "//packages/kbn-logging-mocks:build_types", "//packages/kbn-logging:build_types", - "//packages/kbn-managed-vscode-config-cli:build_types", + "//packages/kbn-logging-mocks:build_types", "//packages/kbn-managed-vscode-config:build_types", + "//packages/kbn-managed-vscode-config-cli:build_types", "//packages/kbn-mapbox-gl:build_types", "//packages/kbn-monaco:build_types", - "//packages/kbn-optimizer-webpack-helpers:build_types", "//packages/kbn-optimizer:build_types", + "//packages/kbn-optimizer-webpack-helpers:build_types", "//packages/kbn-performance-testing-dataset-extractor:build_types", "//packages/kbn-plugin-discovery:build_types", "//packages/kbn-plugin-generator:build_types", "//packages/kbn-plugin-helpers:build_types", "//packages/kbn-react-field:build_types", - "//packages/kbn-repo-source-classifier-cli:build_types", "//packages/kbn-repo-source-classifier:build_types", + "//packages/kbn-repo-source-classifier-cli:build_types", "//packages/kbn-rule-data-utils:build_types", + "//packages/kbn-safer-lodash-set:build_types", "//packages/kbn-securitysolution-autocomplete:build_types", "//packages/kbn-securitysolution-es-utils:build_types", "//packages/kbn-securitysolution-hook-utils:build_types", @@ -466,9 +479,6 @@ filegroup( "//packages/kbn-server-http-tools:build_types", "//packages/kbn-server-route-repository:build_types", "//packages/kbn-shared-svg:build_types", - "//packages/kbn-shared-ux-components:build_types", - "//packages/kbn-shared-ux-services:build_types", - "//packages/kbn-shared-ux-storybook:build_types", "//packages/kbn-shared-ux-utility:build_types", "//packages/kbn-some-dev-log:build_types", "//packages/kbn-sort-package-json:build_types", @@ -476,19 +486,19 @@ filegroup( "//packages/kbn-stdio-dev-helpers:build_types", "//packages/kbn-storybook:build_types", "//packages/kbn-telemetry-tools:build_types", - "//packages/kbn-test-jest-helpers:build_types", "//packages/kbn-test:build_types", + "//packages/kbn-test-jest-helpers:build_types", "//packages/kbn-tooling-log:build_types", + "//packages/kbn-type-summarizer:build_types", "//packages/kbn-type-summarizer-cli:build_types", "//packages/kbn-type-summarizer-core:build_types", - "//packages/kbn-type-summarizer:build_types", "//packages/kbn-typed-react-router-config:build_types", "//packages/kbn-ui-shared-deps-npm:build_types", "//packages/kbn-ui-shared-deps-src:build_types", "//packages/kbn-ui-theme:build_types", "//packages/kbn-user-profile-components:build_types", - "//packages/kbn-utility-types-jest:build_types", "//packages/kbn-utility-types:build_types", + "//packages/kbn-utility-types-jest:build_types", "//packages/kbn-utils:build_types", "//packages/kbn-yarn-lock-validator:build_types", "//packages/shared-ux/avatar/solution:build_types", @@ -503,9 +513,16 @@ filegroup( "//packages/shared-ux/page/analytics_no_data/mocks:build_types", "//packages/shared-ux/page/kibana_no_data/impl:build_types", "//packages/shared-ux/page/kibana_no_data/mocks:build_types", + "//packages/shared-ux/page/kibana_template/impl:build_types", + "//packages/shared-ux/page/kibana_template/mocks:build_types", + "//packages/shared-ux/page/no_data_config/impl:build_types", + "//packages/shared-ux/page/no_data_config/mocks:build_types", + "//packages/shared-ux/page/no_data/impl:build_types", + "//packages/shared-ux/page/no_data/mocks:build_types", "//packages/shared-ux/page/solution_nav:build_types", "//packages/shared-ux/prompt/no_data_views/impl:build_types", "//packages/shared-ux/prompt/no_data_views/mocks:build_types", + "//packages/shared-ux/storybook/config:build_types", "//packages/shared-ux/storybook/mock:build_types", "//x-pack/packages/ml/agg_utils:build_types", "//x-pack/packages/ml/aiops_components:build_types", diff --git a/packages/core/config/core-config-server-internal/BUILD.bazel b/packages/core/config/core-config-server-internal/BUILD.bazel index d2580d6736a760..7bc32e4198ab10 100644 --- a/packages/core/config/core-config-server-internal/BUILD.bazel +++ b/packages/core/config/core-config-server-internal/BUILD.bazel @@ -26,7 +26,7 @@ NPM_MODULE_EXTRA_FILES = [ ] RUNTIME_DEPS = [ - "//packages/elastic-safer-lodash-set", + "//packages/kbn-safer-lodash-set", "//packages/kbn-config", "//packages/core/base/core-base-server-internal", "//packages/kbn-config-mocks", @@ -36,7 +36,7 @@ RUNTIME_DEPS = [ TYPES_DEPS = [ "@npm//@types/node", "@npm//@types/jest", - "//packages/elastic-safer-lodash-set:npm_module_types", + "//packages/kbn-safer-lodash-set:npm_module_types", "//packages/kbn-config:npm_module_types", "//packages/kbn-config-mocks:npm_module_types", "//packages/core/base/core-base-server-internal:npm_module_types", diff --git a/packages/core/logging/core-logging-server-internal/BUILD.bazel b/packages/core/logging/core-logging-server-internal/BUILD.bazel index 199e47161d6a0f..abed6f741fc392 100644 --- a/packages/core/logging/core-logging-server-internal/BUILD.bazel +++ b/packages/core/logging/core-logging-server-internal/BUILD.bazel @@ -29,7 +29,7 @@ RUNTIME_DEPS = [ "@npm//lodash", "@npm//moment-timezone", "@npm//elastic-apm-node", - "//packages/elastic-safer-lodash-set", + "//packages/kbn-safer-lodash-set", "//packages/kbn-config-schema", "//packages/kbn-std", ] @@ -41,7 +41,7 @@ TYPES_DEPS = [ "@npm//rxjs", "@npm//@types/moment-timezone", "@npm//elastic-apm-node", - "//packages/elastic-safer-lodash-set:npm_module_types", + "//packages/kbn-safer-lodash-set:npm_module_types", "//packages/kbn-logging:npm_module_types", "//packages/kbn-config-schema:npm_module_types", "//packages/core/base/core-base-server-internal:npm_module_types", diff --git a/packages/core/logging/core-logging-server-internal/src/appenders/rewrite/policies/meta/meta_policy.ts b/packages/core/logging/core-logging-server-internal/src/appenders/rewrite/policies/meta/meta_policy.ts index 2618f0ed505871..45e62713980c04 100644 --- a/packages/core/logging/core-logging-server-internal/src/appenders/rewrite/policies/meta/meta_policy.ts +++ b/packages/core/logging/core-logging-server-internal/src/appenders/rewrite/policies/meta/meta_policy.ts @@ -8,7 +8,7 @@ import { schema } from '@kbn/config-schema'; import { LogRecord } from '@kbn/logging'; -import { set } from '@elastic/safer-lodash-set'; +import { set } from '@kbn/safer-lodash-set'; import { has, unset } from 'lodash'; import { assertNever } from '@kbn/std'; import type { MetaRewritePolicyConfig } from '@kbn/core-logging-server'; diff --git a/packages/core/logging/core-logging-server-internal/src/global_context/merge_global_context.ts b/packages/core/logging/core-logging-server-internal/src/global_context/merge_global_context.ts index 64186392caa565..7e794f0731cf57 100644 --- a/packages/core/logging/core-logging-server-internal/src/global_context/merge_global_context.ts +++ b/packages/core/logging/core-logging-server-internal/src/global_context/merge_global_context.ts @@ -7,7 +7,7 @@ */ import { has } from 'lodash'; -import { set } from '@elastic/safer-lodash-set'; +import { set } from '@kbn/safer-lodash-set'; import { LogMeta } from '@kbn/logging'; import { GlobalContext } from './types'; diff --git a/packages/core/overlays/core-overlays-browser-internal/src/banners/user_banner_service.tsx b/packages/core/overlays/core-overlays-browser-internal/src/banners/user_banner_service.tsx index 81ee879615b761..5fdc4439136f91 100644 --- a/packages/core/overlays/core-overlays-browser-internal/src/banners/user_banner_service.tsx +++ b/packages/core/overlays/core-overlays-browser-internal/src/banners/user_banner_service.tsx @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import React, { Fragment } from 'react'; +import React from 'react'; import ReactDOM from 'react-dom'; import { filter } from 'rxjs/operators'; import { Subscription } from 'rxjs'; @@ -72,7 +72,7 @@ export class UserBannerService { } > - + {content.trim()} banners.remove(id!)}> diff --git a/packages/core/saved-objects/core-saved-objects-base-server-internal/BUILD.bazel b/packages/core/saved-objects/core-saved-objects-base-server-internal/BUILD.bazel new file mode 100644 index 00000000000000..d64f0bb533a0ff --- /dev/null +++ b/packages/core/saved-objects/core-saved-objects-base-server-internal/BUILD.bazel @@ -0,0 +1,111 @@ +load("@npm//@bazel/typescript:index.bzl", "ts_config") +load("@build_bazel_rules_nodejs//:index.bzl", "js_library") +load("//src/dev/bazel:index.bzl", "jsts_transpiler", "pkg_npm", "pkg_npm_types", "ts_project") + +PKG_DIRNAME = "core-saved-objects-base-server-internal" +PKG_REQUIRE_NAME = "@kbn/core-saved-objects-base-server-internal" + +SOURCE_FILES = glob( + [ + "src/**/*.ts", + ], + exclude = [ + "**/*.test.*", + "**/*.stories.*", + ], +) + +SRCS = SOURCE_FILES + +filegroup( + name = "srcs", + srcs = SRCS, +) + +NPM_MODULE_EXTRA_FILES = [ + "package.json", +] + +RUNTIME_DEPS = [ + "@npm//lodash", + "@npm//semver", + "//packages/kbn-config-schema", + ### test dependencies + "//packages/kbn-logging-mocks", + "@npm//@hapi/boom", +] + +TYPES_DEPS = [ + "@npm//@types/node", + "@npm//@types/jest", + "@npm//@types/lodash", + "@npm//@types/semver", + "//packages/kbn-logging:npm_module_types", + "//packages/kbn-config-schema:npm_module_types", + "//packages/core/base/core-base-server-internal:npm_module_types", + "//packages/core/saved-objects/core-saved-objects-server:npm_module_types", + "//packages/core/saved-objects/core-saved-objects-utils-server:npm_module_types", +] + +jsts_transpiler( + name = "target_node", + srcs = SRCS, + build_pkg_name = package_name(), + root_input_dir = "src", +) + +ts_config( + name = "tsconfig", + src = "tsconfig.json", + deps = [ + "//:tsconfig.base.json", + "//:tsconfig.bazel.json", + ], +) + +ts_project( + name = "tsc_types", + args = ['--pretty'], + srcs = SRCS, + deps = TYPES_DEPS, + declaration = True, + declaration_map = True, + emit_declaration_only = True, + out_dir = "target_types", + root_dir = "src", + tsconfig = ":tsconfig", +) + +js_library( + name = PKG_DIRNAME, + srcs = NPM_MODULE_EXTRA_FILES, + deps = RUNTIME_DEPS + [":target_node"], + package_name = PKG_REQUIRE_NAME, + visibility = ["//visibility:public"], +) + +pkg_npm( + name = "npm_module", + deps = [":" + PKG_DIRNAME], +) + +filegroup( + name = "build", + srcs = [":npm_module"], + visibility = ["//visibility:public"], +) + +pkg_npm_types( + name = "npm_module_types", + srcs = SRCS, + deps = [":tsc_types"], + package_name = PKG_REQUIRE_NAME, + tsconfig = ":tsconfig", + visibility = ["//visibility:public"], +) + +filegroup( + name = "build_types", + srcs = [":npm_module_types"], + visibility = ["//visibility:public"], +) diff --git a/packages/core/saved-objects/core-saved-objects-base-server-internal/README.md b/packages/core/saved-objects/core-saved-objects-base-server-internal/README.md new file mode 100644 index 00000000000000..0315d68aca7b00 --- /dev/null +++ b/packages/core/saved-objects/core-saved-objects-base-server-internal/README.md @@ -0,0 +1,4 @@ +# @kbn/core-saved-objects-base-server-internal + +This package contains the base parts of the server-side savedObjects internal implementation, +used by all the other internal server-side savedObjects packages. \ No newline at end of file diff --git a/packages/core/saved-objects/core-saved-objects-base-server-internal/jest.config.js b/packages/core/saved-objects/core-saved-objects-base-server-internal/jest.config.js new file mode 100644 index 00000000000000..384625b895fcd1 --- /dev/null +++ b/packages/core/saved-objects/core-saved-objects-base-server-internal/jest.config.js @@ -0,0 +1,13 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +module.exports = { + preset: '@kbn/test/jest_node', + rootDir: '../../../..', + roots: ['/packages/core/saved-objects/core-saved-objects-base-server-internal'], +}; diff --git a/packages/core/saved-objects/core-saved-objects-base-server-internal/package.json b/packages/core/saved-objects/core-saved-objects-base-server-internal/package.json new file mode 100644 index 00000000000000..ff4b901f49056e --- /dev/null +++ b/packages/core/saved-objects/core-saved-objects-base-server-internal/package.json @@ -0,0 +1,7 @@ +{ + "name": "@kbn/core-saved-objects-base-server-internal", + "private": true, + "version": "1.0.0", + "main": "./target_node/index.js", + "license": "SSPL-1.0 OR Elastic License 2.0" +} diff --git a/packages/core/saved-objects/core-saved-objects-base-server-internal/src/index.ts b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/index.ts new file mode 100644 index 00000000000000..5b504f43244d64 --- /dev/null +++ b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/index.ts @@ -0,0 +1,29 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +export { LEGACY_URL_ALIAS_TYPE, type LegacyUrlAlias } from './legacy_alias'; +export { + getProperty, + getRootProperties, + getRootPropertiesObjects, + getTypes, + type IndexMapping, + type IndexMappingMeta, + type SavedObjectsTypeMappingDefinitions, +} from './mappings'; +export { SavedObjectsSerializer } from './serialization'; +export { SavedObjectsTypeValidator } from './validation'; +export { decodeRequestVersion, decodeVersion, encodeVersion, encodeHitVersion } from './version'; +export { + savedObjectsConfig, + savedObjectsMigrationConfig, + SavedObjectConfig, + type SavedObjectsConfigType, + type SavedObjectsMigrationConfigType, +} from './saved_objects_config'; +export { SavedObjectTypeRegistry } from './saved_objects_type_registry'; diff --git a/src/core/server/saved_objects/object_types/constants.ts b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/legacy_alias/constants.ts similarity index 100% rename from src/core/server/saved_objects/object_types/constants.ts rename to packages/core/saved-objects/core-saved-objects-base-server-internal/src/legacy_alias/constants.ts diff --git a/packages/kbn-shared-ux-components/src/page_template/util/index.ts b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/legacy_alias/index.ts similarity index 78% rename from packages/kbn-shared-ux-components/src/page_template/util/index.ts rename to packages/core/saved-objects/core-saved-objects-base-server-internal/src/legacy_alias/index.ts index adfefdf8345664..f782267bd20967 100644 --- a/packages/kbn-shared-ux-components/src/page_template/util/index.ts +++ b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/legacy_alias/index.ts @@ -6,5 +6,5 @@ * Side Public License, v 1. */ -export { getClasses } from './presentation'; -export * from './constants'; +export type { LegacyUrlAlias } from './types'; +export { LEGACY_URL_ALIAS_TYPE } from './constants'; diff --git a/src/core/server/saved_objects/object_types/types.ts b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/legacy_alias/types.ts similarity index 100% rename from src/core/server/saved_objects/object_types/types.ts rename to packages/core/saved-objects/core-saved-objects-base-server-internal/src/legacy_alias/types.ts diff --git a/src/core/server/saved_objects/mappings/index.ts b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/mappings/index.ts similarity index 100% rename from src/core/server/saved_objects/mappings/index.ts rename to packages/core/saved-objects/core-saved-objects-base-server-internal/src/mappings/index.ts diff --git a/src/core/server/saved_objects/mappings/lib/get_property.test.ts b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/mappings/lib/get_property.test.ts similarity index 100% rename from src/core/server/saved_objects/mappings/lib/get_property.test.ts rename to packages/core/saved-objects/core-saved-objects-base-server-internal/src/mappings/lib/get_property.test.ts diff --git a/src/core/server/saved_objects/mappings/lib/get_property.ts b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/mappings/lib/get_property.ts similarity index 100% rename from src/core/server/saved_objects/mappings/lib/get_property.ts rename to packages/core/saved-objects/core-saved-objects-base-server-internal/src/mappings/lib/get_property.ts diff --git a/src/core/server/saved_objects/mappings/lib/get_root_properties.ts b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/mappings/lib/get_root_properties.ts similarity index 100% rename from src/core/server/saved_objects/mappings/lib/get_root_properties.ts rename to packages/core/saved-objects/core-saved-objects-base-server-internal/src/mappings/lib/get_root_properties.ts diff --git a/src/core/server/saved_objects/mappings/lib/get_root_properties_objects.test.ts b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/mappings/lib/get_root_properties_objects.test.ts similarity index 100% rename from src/core/server/saved_objects/mappings/lib/get_root_properties_objects.test.ts rename to packages/core/saved-objects/core-saved-objects-base-server-internal/src/mappings/lib/get_root_properties_objects.test.ts diff --git a/src/core/server/saved_objects/mappings/lib/get_root_properties_objects.ts b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/mappings/lib/get_root_properties_objects.ts similarity index 100% rename from src/core/server/saved_objects/mappings/lib/get_root_properties_objects.ts rename to packages/core/saved-objects/core-saved-objects-base-server-internal/src/mappings/lib/get_root_properties_objects.ts diff --git a/src/core/server/saved_objects/mappings/lib/get_types.ts b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/mappings/lib/get_types.ts similarity index 100% rename from src/core/server/saved_objects/mappings/lib/get_types.ts rename to packages/core/saved-objects/core-saved-objects-base-server-internal/src/mappings/lib/get_types.ts diff --git a/src/core/server/saved_objects/mappings/lib/index.ts b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/mappings/lib/index.ts similarity index 100% rename from src/core/server/saved_objects/mappings/lib/index.ts rename to packages/core/saved-objects/core-saved-objects-base-server-internal/src/mappings/lib/index.ts diff --git a/src/core/server/saved_objects/mappings/types.ts b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/mappings/types.ts similarity index 100% rename from src/core/server/saved_objects/mappings/types.ts rename to packages/core/saved-objects/core-saved-objects-base-server-internal/src/mappings/types.ts diff --git a/src/core/server/saved_objects/saved_objects_config.ts b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/saved_objects_config.ts similarity index 100% rename from src/core/server/saved_objects/saved_objects_config.ts rename to packages/core/saved-objects/core-saved-objects-base-server-internal/src/saved_objects_config.ts diff --git a/src/core/server/saved_objects/saved_objects_type_registry.test.ts b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/saved_objects_type_registry.test.ts similarity index 100% rename from src/core/server/saved_objects/saved_objects_type_registry.test.ts rename to packages/core/saved-objects/core-saved-objects-base-server-internal/src/saved_objects_type_registry.test.ts diff --git a/src/core/server/saved_objects/saved_objects_type_registry.ts b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/saved_objects_type_registry.ts similarity index 100% rename from src/core/server/saved_objects/saved_objects_type_registry.ts rename to packages/core/saved-objects/core-saved-objects-base-server-internal/src/saved_objects_type_registry.ts diff --git a/src/core/server/saved_objects/serialization/index.ts b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/serialization/index.ts similarity index 100% rename from src/core/server/saved_objects/serialization/index.ts rename to packages/core/saved-objects/core-saved-objects-base-server-internal/src/serialization/index.ts diff --git a/src/core/server/saved_objects/serialization/serializer.test.ts b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/serialization/serializer.test.ts similarity index 96% rename from src/core/server/saved_objects/serialization/serializer.test.ts rename to packages/core/saved-objects/core-saved-objects-base-server-internal/src/serialization/serializer.test.ts index e0ef357c0d9bea..230993bd06d292 100644 --- a/src/core/server/saved_objects/serialization/serializer.test.ts +++ b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/serialization/serializer.test.ts @@ -7,28 +7,47 @@ */ import _ from 'lodash'; -import type { SavedObjectsRawDoc } from '@kbn/core-saved-objects-server'; +import type { SavedObjectsRawDoc, ISavedObjectTypeRegistry } from '@kbn/core-saved-objects-server'; import { SavedObjectsSerializer } from './serializer'; -import { typeRegistryMock } from '../saved_objects_type_registry.mock'; import { encodeVersion } from '../version'; -import { LEGACY_URL_ALIAS_TYPE } from '../object_types'; +import { LEGACY_URL_ALIAS_TYPE } from '../legacy_alias'; + +const createMockedTypeRegistry = ({ + isNamespaceAgnostic, + isSingleNamespace, + isMultiNamespace, +}: { + isNamespaceAgnostic: boolean; + isSingleNamespace: boolean; + isMultiNamespace: boolean; +}): ISavedObjectTypeRegistry => { + const typeRegistry: Partial = { + isNamespaceAgnostic: jest.fn().mockReturnValue(isNamespaceAgnostic), + isSingleNamespace: jest.fn().mockReturnValue(isSingleNamespace), + isMultiNamespace: jest.fn().mockReturnValue(isMultiNamespace), + }; + return typeRegistry as ISavedObjectTypeRegistry; +}; -let typeRegistry = typeRegistryMock.create(); -typeRegistry.isNamespaceAgnostic.mockReturnValue(true); -typeRegistry.isSingleNamespace.mockReturnValue(false); -typeRegistry.isMultiNamespace.mockReturnValue(false); +let typeRegistry = createMockedTypeRegistry({ + isNamespaceAgnostic: true, + isSingleNamespace: false, + isMultiNamespace: false, +}); const namespaceAgnosticSerializer = new SavedObjectsSerializer(typeRegistry); -typeRegistry = typeRegistryMock.create(); -typeRegistry.isNamespaceAgnostic.mockReturnValue(false); -typeRegistry.isSingleNamespace.mockReturnValue(true); -typeRegistry.isMultiNamespace.mockReturnValue(false); +typeRegistry = typeRegistry = createMockedTypeRegistry({ + isNamespaceAgnostic: false, + isSingleNamespace: true, + isMultiNamespace: false, +}); const singleNamespaceSerializer = new SavedObjectsSerializer(typeRegistry); -typeRegistry = typeRegistryMock.create(); -typeRegistry.isNamespaceAgnostic.mockReturnValue(false); -typeRegistry.isSingleNamespace.mockReturnValue(false); -typeRegistry.isMultiNamespace.mockReturnValue(true); +typeRegistry = typeRegistry = createMockedTypeRegistry({ + isNamespaceAgnostic: false, + isSingleNamespace: false, + isMultiNamespace: true, +}); const multiNamespaceSerializer = new SavedObjectsSerializer(typeRegistry); const sampleTemplate = { diff --git a/src/core/server/saved_objects/serialization/serializer.ts b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/serialization/serializer.ts similarity index 98% rename from src/core/server/saved_objects/serialization/serializer.ts rename to packages/core/saved-objects/core-saved-objects-base-server-internal/src/serialization/serializer.ts index 2e13708ee2f9de..340926abd0bce3 100644 --- a/src/core/server/saved_objects/serialization/serializer.ts +++ b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/serialization/serializer.ts @@ -14,9 +14,9 @@ import type { SavedObjectSanitizedDoc, SavedObjectsRawDocParseOptions, } from '@kbn/core-saved-objects-server'; -import { LEGACY_URL_ALIAS_TYPE } from '../object_types'; +import { SavedObjectsUtils } from '@kbn/core-saved-objects-utils-server'; +import { LEGACY_URL_ALIAS_TYPE } from '../legacy_alias'; import { decodeVersion, encodeVersion } from '../version'; -import { SavedObjectsUtils } from '../service'; /** * Core internal implementation of {@link ISavedObjectsSerializer} diff --git a/src/core/server/saved_objects/validation/index.ts b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/validation/index.ts similarity index 100% rename from src/core/server/saved_objects/validation/index.ts rename to packages/core/saved-objects/core-saved-objects-base-server-internal/src/validation/index.ts diff --git a/src/core/server/saved_objects/validation/schema.test.ts b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/validation/schema.test.ts similarity index 100% rename from src/core/server/saved_objects/validation/schema.test.ts rename to packages/core/saved-objects/core-saved-objects-base-server-internal/src/validation/schema.test.ts diff --git a/src/core/server/saved_objects/validation/schema.ts b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/validation/schema.ts similarity index 97% rename from src/core/server/saved_objects/validation/schema.ts rename to packages/core/saved-objects/core-saved-objects-base-server-internal/src/validation/schema.ts index 8e90c4aef9c70f..221f21b5aa9924 100644 --- a/src/core/server/saved_objects/validation/schema.ts +++ b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/validation/schema.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import { schema, Type } from '@kbn/config-schema'; +import { schema, type Type } from '@kbn/config-schema'; import type { SavedObjectsValidationSpec, SavedObjectSanitizedDoc, diff --git a/src/core/server/saved_objects/validation/validator.test.ts b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/validation/validator.test.ts similarity index 95% rename from src/core/server/saved_objects/validation/validator.test.ts rename to packages/core/saved-objects/core-saved-objects-base-server-internal/src/validation/validator.test.ts index b059070fdf75fa..96bc93be54c1ac 100644 --- a/src/core/server/saved_objects/validation/validator.test.ts +++ b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/validation/validator.test.ts @@ -7,12 +7,12 @@ */ import { schema } from '@kbn/config-schema'; +import { loggerMock, type MockedLogger } from '@kbn/logging-mocks'; import type { SavedObjectSanitizedDoc, SavedObjectsValidationMap, } from '@kbn/core-saved-objects-server'; -import { SavedObjectsTypeValidator } from '.'; -import { loggerMock, MockedLogger } from '@kbn/logging-mocks'; +import { SavedObjectsTypeValidator } from './validator'; describe('Saved Objects type validator', () => { let validator: SavedObjectsTypeValidator; diff --git a/src/core/server/saved_objects/validation/validator.ts b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/validation/validator.ts similarity index 100% rename from src/core/server/saved_objects/validation/validator.ts rename to packages/core/saved-objects/core-saved-objects-base-server-internal/src/validation/validator.ts diff --git a/src/core/server/saved_objects/version/base64.ts b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/version/base64.ts similarity index 100% rename from src/core/server/saved_objects/version/base64.ts rename to packages/core/saved-objects/core-saved-objects-base-server-internal/src/version/base64.ts diff --git a/src/core/server/saved_objects/version/decode_request_version.test.ts b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/version/decode_request_version.test.ts similarity index 100% rename from src/core/server/saved_objects/version/decode_request_version.test.ts rename to packages/core/saved-objects/core-saved-objects-base-server-internal/src/version/decode_request_version.test.ts diff --git a/src/core/server/saved_objects/version/decode_request_version.ts b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/version/decode_request_version.ts similarity index 100% rename from src/core/server/saved_objects/version/decode_request_version.ts rename to packages/core/saved-objects/core-saved-objects-base-server-internal/src/version/decode_request_version.ts diff --git a/src/core/server/saved_objects/version/decode_version.test.ts b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/version/decode_version.test.ts similarity index 100% rename from src/core/server/saved_objects/version/decode_version.test.ts rename to packages/core/saved-objects/core-saved-objects-base-server-internal/src/version/decode_version.test.ts diff --git a/src/core/server/saved_objects/version/decode_version.ts b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/version/decode_version.ts similarity index 93% rename from src/core/server/saved_objects/version/decode_version.ts rename to packages/core/saved-objects/core-saved-objects-base-server-internal/src/version/decode_version.ts index 4166e7eef06c7c..dd4bdcdc8186fa 100644 --- a/src/core/server/saved_objects/version/decode_version.ts +++ b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/version/decode_version.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import { SavedObjectsErrorHelpers } from '../service/lib/errors'; +import { SavedObjectsErrorHelpers } from '@kbn/core-saved-objects-utils-server'; import { decodeBase64 } from './base64'; /** diff --git a/src/core/server/saved_objects/version/encode_hit_version.test.ts b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/version/encode_hit_version.test.ts similarity index 100% rename from src/core/server/saved_objects/version/encode_hit_version.test.ts rename to packages/core/saved-objects/core-saved-objects-base-server-internal/src/version/encode_hit_version.test.ts diff --git a/src/core/server/saved_objects/version/encode_hit_version.ts b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/version/encode_hit_version.ts similarity index 100% rename from src/core/server/saved_objects/version/encode_hit_version.ts rename to packages/core/saved-objects/core-saved-objects-base-server-internal/src/version/encode_hit_version.ts diff --git a/src/core/server/saved_objects/version/encode_version.test.ts b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/version/encode_version.test.ts similarity index 100% rename from src/core/server/saved_objects/version/encode_version.test.ts rename to packages/core/saved-objects/core-saved-objects-base-server-internal/src/version/encode_version.test.ts diff --git a/src/core/server/saved_objects/version/encode_version.ts b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/version/encode_version.ts similarity index 100% rename from src/core/server/saved_objects/version/encode_version.ts rename to packages/core/saved-objects/core-saved-objects-base-server-internal/src/version/encode_version.ts diff --git a/src/plugins/shared_ux/public/index.ts b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/version/index.ts old mode 100755 new mode 100644 similarity index 61% rename from src/plugins/shared_ux/public/index.ts rename to packages/core/saved-objects/core-saved-objects-base-server-internal/src/version/index.ts index 1dcf84eaf4991c..2fb31940d4408b --- a/src/plugins/shared_ux/public/index.ts +++ b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/version/index.ts @@ -6,13 +6,7 @@ * Side Public License, v 1. */ -import { SharedUXPlugin } from './plugin'; - -/** - * Creates the Shared UX plugin. - */ -export function plugin() { - return new SharedUXPlugin(); -} - -export type { SharedUXPluginSetup, SharedUXPluginStart } from './types'; +export { encodeVersion } from './encode_version'; +export { encodeHitVersion } from './encode_hit_version'; +export { decodeVersion } from './decode_version'; +export { decodeRequestVersion } from './decode_request_version'; diff --git a/packages/kbn-shared-ux-services/tsconfig.json b/packages/core/saved-objects/core-saved-objects-base-server-internal/tsconfig.json old mode 100755 new mode 100644 similarity index 85% rename from packages/kbn-shared-ux-services/tsconfig.json rename to packages/core/saved-objects/core-saved-objects-base-server-internal/tsconfig.json index 789c6b3111115d..39d3c7097814ac --- a/packages/kbn-shared-ux-services/tsconfig.json +++ b/packages/core/saved-objects/core-saved-objects-base-server-internal/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "../../tsconfig.bazel.json", + "extends": "../../../../tsconfig.bazel.json", "compilerOptions": { "declaration": true, "declarationMap": true, diff --git a/packages/core/saved-objects/core-saved-objects-base-server-mocks/BUILD.bazel b/packages/core/saved-objects/core-saved-objects-base-server-mocks/BUILD.bazel new file mode 100644 index 00000000000000..9f3538c20a7520 --- /dev/null +++ b/packages/core/saved-objects/core-saved-objects-base-server-mocks/BUILD.bazel @@ -0,0 +1,100 @@ +load("@npm//@bazel/typescript:index.bzl", "ts_config") +load("@build_bazel_rules_nodejs//:index.bzl", "js_library") +load("//src/dev/bazel:index.bzl", "jsts_transpiler", "pkg_npm", "pkg_npm_types", "ts_project") + +PKG_DIRNAME = "core-saved-objects-base-server-mocks" +PKG_REQUIRE_NAME = "@kbn/core-saved-objects-base-server-mocks" + +SOURCE_FILES = glob( + [ + "src/**/*.ts", + ], + exclude = [ + "**/*.test.*", + "**/*.stories.*", + ], +) + +SRCS = SOURCE_FILES + +filegroup( + name = "srcs", + srcs = SRCS, +) + +NPM_MODULE_EXTRA_FILES = [ + "package.json", +] + +RUNTIME_DEPS = [ +] + +TYPES_DEPS = [ + "@npm//@types/node", + "@npm//@types/jest", + "//packages/core/saved-objects/core-saved-objects-server:npm_module_types", + "//packages/core/saved-objects/core-saved-objects-base-server-internal:npm_module_types", +] + +jsts_transpiler( + name = "target_node", + srcs = SRCS, + build_pkg_name = package_name(), + root_input_dir = "src", +) + +ts_config( + name = "tsconfig", + src = "tsconfig.json", + deps = [ + "//:tsconfig.base.json", + "//:tsconfig.bazel.json", + ], +) + +ts_project( + name = "tsc_types", + args = ['--pretty'], + srcs = SRCS, + deps = TYPES_DEPS, + declaration = True, + declaration_map = True, + emit_declaration_only = True, + out_dir = "target_types", + root_dir = "src", + tsconfig = ":tsconfig", +) + +js_library( + name = PKG_DIRNAME, + srcs = NPM_MODULE_EXTRA_FILES, + deps = RUNTIME_DEPS + [":target_node"], + package_name = PKG_REQUIRE_NAME, + visibility = ["//visibility:public"], +) + +pkg_npm( + name = "npm_module", + deps = [":" + PKG_DIRNAME], +) + +filegroup( + name = "build", + srcs = [":npm_module"], + visibility = ["//visibility:public"], +) + +pkg_npm_types( + name = "npm_module_types", + srcs = SRCS, + deps = [":tsc_types"], + package_name = PKG_REQUIRE_NAME, + tsconfig = ":tsconfig", + visibility = ["//visibility:public"], +) + +filegroup( + name = "build_types", + srcs = [":npm_module_types"], + visibility = ["//visibility:public"], +) diff --git a/packages/core/saved-objects/core-saved-objects-base-server-mocks/README.md b/packages/core/saved-objects/core-saved-objects-base-server-mocks/README.md new file mode 100644 index 00000000000000..5da5264ce9eeda --- /dev/null +++ b/packages/core/saved-objects/core-saved-objects-base-server-mocks/README.md @@ -0,0 +1,5 @@ +# @kbn/core-saved-objects-base-server-mocks + +This package contains the mocks for the base server-side savedObjects sub-domain: +- `SavedObjectTypeRegistry` mock +- `SavedObjectsSerializer` mock diff --git a/packages/shared-ux/page/analytics_no_data/mocks/jest.config.js b/packages/core/saved-objects/core-saved-objects-base-server-mocks/jest.config.js similarity index 78% rename from packages/shared-ux/page/analytics_no_data/mocks/jest.config.js rename to packages/core/saved-objects/core-saved-objects-base-server-mocks/jest.config.js index ba5df95ec80fb3..fee774e7876937 100644 --- a/packages/shared-ux/page/analytics_no_data/mocks/jest.config.js +++ b/packages/core/saved-objects/core-saved-objects-base-server-mocks/jest.config.js @@ -8,6 +8,6 @@ module.exports = { preset: '@kbn/test/jest_node', - rootDir: '../../../../..', - roots: ['/packages/shared-ux/page/analytics_no_data/mocks'], + rootDir: '../../../..', + roots: ['/packages/core/saved-objects/core-saved-objects-base-server-mocks'], }; diff --git a/packages/core/saved-objects/core-saved-objects-base-server-mocks/package.json b/packages/core/saved-objects/core-saved-objects-base-server-mocks/package.json new file mode 100644 index 00000000000000..e119e704c7ace8 --- /dev/null +++ b/packages/core/saved-objects/core-saved-objects-base-server-mocks/package.json @@ -0,0 +1,7 @@ +{ + "name": "@kbn/core-saved-objects-base-server-mocks", + "private": true, + "version": "1.0.0", + "main": "./target_node/index.js", + "license": "SSPL-1.0 OR Elastic License 2.0" +} diff --git a/packages/core/saved-objects/core-saved-objects-base-server-mocks/src/index.ts b/packages/core/saved-objects/core-saved-objects-base-server-mocks/src/index.ts new file mode 100644 index 00000000000000..62657cf81ea616 --- /dev/null +++ b/packages/core/saved-objects/core-saved-objects-base-server-mocks/src/index.ts @@ -0,0 +1,10 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +export { typeRegistryMock } from './saved_objects_type_registry.mock'; +export { serializerMock } from './serializer.mock'; diff --git a/src/core/server/saved_objects/saved_objects_type_registry.mock.ts b/packages/core/saved-objects/core-saved-objects-base-server-mocks/src/saved_objects_type_registry.mock.ts similarity index 94% rename from src/core/server/saved_objects/saved_objects_type_registry.mock.ts rename to packages/core/saved-objects/core-saved-objects-base-server-mocks/src/saved_objects_type_registry.mock.ts index 70d05a0f7b0abe..8f792f177b5fc6 100644 --- a/src/core/server/saved_objects/saved_objects_type_registry.mock.ts +++ b/packages/core/saved-objects/core-saved-objects-base-server-mocks/src/saved_objects_type_registry.mock.ts @@ -7,7 +7,7 @@ */ import type { ISavedObjectTypeRegistry } from '@kbn/core-saved-objects-server'; -import type { SavedObjectTypeRegistry } from './saved_objects_type_registry'; +import type { SavedObjectTypeRegistry } from '@kbn/core-saved-objects-base-server-internal'; const createRegistryMock = (): jest.Mocked< ISavedObjectTypeRegistry & Pick diff --git a/packages/core/saved-objects/core-saved-objects-base-server-mocks/src/serializer.mock.ts b/packages/core/saved-objects/core-saved-objects-base-server-mocks/src/serializer.mock.ts new file mode 100644 index 00000000000000..6bdac2e20c1f94 --- /dev/null +++ b/packages/core/saved-objects/core-saved-objects-base-server-mocks/src/serializer.mock.ts @@ -0,0 +1,24 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import type { ISavedObjectsSerializer } from '@kbn/core-saved-objects-server'; + +const createSerializerMock = () => { + const mock: jest.Mocked = { + isRawSavedObject: jest.fn(), + rawToSavedObject: jest.fn(), + savedObjectToRaw: jest.fn(), + generateRawId: jest.fn(), + generateRawLegacyUrlAliasId: jest.fn(), + }; + return mock; +}; + +export const serializerMock = { + create: createSerializerMock, +}; diff --git a/packages/core/saved-objects/core-saved-objects-base-server-mocks/tsconfig.json b/packages/core/saved-objects/core-saved-objects-base-server-mocks/tsconfig.json new file mode 100644 index 00000000000000..39d3c7097814ac --- /dev/null +++ b/packages/core/saved-objects/core-saved-objects-base-server-mocks/tsconfig.json @@ -0,0 +1,18 @@ +{ + "extends": "../../../../tsconfig.bazel.json", + "compilerOptions": { + "declaration": true, + "declarationMap": true, + "emitDeclarationOnly": true, + "outDir": "target_types", + "rootDir": "src", + "stripInternal": false, + "types": [ + "jest", + "node" + ] + }, + "include": [ + "src/**/*" + ] +} diff --git a/packages/core/saved-objects/core-saved-objects-browser-internal/BUILD.bazel b/packages/core/saved-objects/core-saved-objects-browser-internal/BUILD.bazel index b0d0964c54a96a..40aa528d50a984 100644 --- a/packages/core/saved-objects/core-saved-objects-browser-internal/BUILD.bazel +++ b/packages/core/saved-objects/core-saved-objects-browser-internal/BUILD.bazel @@ -29,7 +29,7 @@ NPM_MODULE_EXTRA_FILES = [ RUNTIME_DEPS = [ "@npm//lodash", - "//packages/elastic-safer-lodash-set", + "//packages/kbn-safer-lodash-set", ### test dependencies "//packages/core/http/core-http-browser-mocks", ] @@ -38,7 +38,7 @@ TYPES_DEPS = [ "@npm//@types/node", "@npm//@types/jest", "@npm//lodash", - "//packages/elastic-safer-lodash-set:npm_module_types", + "//packages/kbn-safer-lodash-set:npm_module_types", "//packages/core/base/core-base-browser-internal:npm_module_types", "//packages/core/http/core-http-browser:npm_module_types", "//packages/core/saved-objects/core-saved-objects-common:npm_module_types", diff --git a/packages/core/saved-objects/core-saved-objects-browser-internal/src/simple_saved_object.ts b/packages/core/saved-objects/core-saved-objects-browser-internal/src/simple_saved_object.ts index 89501c69dcfb54..adda64d8b4ff32 100644 --- a/packages/core/saved-objects/core-saved-objects-browser-internal/src/simple_saved_object.ts +++ b/packages/core/saved-objects/core-saved-objects-browser-internal/src/simple_saved_object.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import { set } from '@elastic/safer-lodash-set'; +import { set } from '@kbn/safer-lodash-set'; import { get, has } from 'lodash'; import type { SavedObject as SavedObjectType } from '@kbn/core-saved-objects-common'; import type { diff --git a/packages/core/saved-objects/core-saved-objects-utils-server/BUILD.bazel b/packages/core/saved-objects/core-saved-objects-utils-server/BUILD.bazel new file mode 100644 index 00000000000000..71a61799ee46a8 --- /dev/null +++ b/packages/core/saved-objects/core-saved-objects-utils-server/BUILD.bazel @@ -0,0 +1,106 @@ +load("@npm//@bazel/typescript:index.bzl", "ts_config") +load("@build_bazel_rules_nodejs//:index.bzl", "js_library") +load("//src/dev/bazel:index.bzl", "jsts_transpiler", "pkg_npm", "pkg_npm_types", "ts_project") + +PKG_DIRNAME = "core-saved-objects-utils-server" +PKG_REQUIRE_NAME = "@kbn/core-saved-objects-utils-server" + +SOURCE_FILES = glob( + [ + "src/**/*.ts", + ], + exclude = [ + "**/*.test.*", + "**/*.stories.*", + ], +) + +SRCS = SOURCE_FILES + +filegroup( + name = "srcs", + srcs = SRCS, +) + +NPM_MODULE_EXTRA_FILES = [ + "package.json", +] + +RUNTIME_DEPS = [ + "@npm//lodash", + "@npm//uuid", + "@npm//@hapi/boom", +] + + +TYPES_DEPS = [ + "@npm//@types/node", + "@npm//@types/jest", + "@npm//@types/lodash", + "@npm//@types/uuid", + "@npm//@hapi/boom", + "//packages/core/saved-objects/core-saved-objects-server:npm_module_types", +] + +jsts_transpiler( + name = "target_node", + srcs = SRCS, + build_pkg_name = package_name(), + root_input_dir = "src", +) + +ts_config( + name = "tsconfig", + src = "tsconfig.json", + deps = [ + "//:tsconfig.base.json", + "//:tsconfig.bazel.json", + ], +) + +ts_project( + name = "tsc_types", + args = ['--pretty'], + srcs = SRCS, + deps = TYPES_DEPS, + declaration = True, + declaration_map = True, + emit_declaration_only = True, + out_dir = "target_types", + root_dir = "src", + tsconfig = ":tsconfig", +) + +js_library( + name = PKG_DIRNAME, + srcs = NPM_MODULE_EXTRA_FILES, + deps = RUNTIME_DEPS + [":target_node"], + package_name = PKG_REQUIRE_NAME, + visibility = ["//visibility:public"], +) + +pkg_npm( + name = "npm_module", + deps = [":" + PKG_DIRNAME], +) + +filegroup( + name = "build", + srcs = [":npm_module"], + visibility = ["//visibility:public"], +) + +pkg_npm_types( + name = "npm_module_types", + srcs = SRCS, + deps = [":tsc_types"], + package_name = PKG_REQUIRE_NAME, + tsconfig = ":tsconfig", + visibility = ["//visibility:public"], +) + +filegroup( + name = "build_types", + srcs = [":npm_module_types"], + visibility = ["//visibility:public"], +) diff --git a/packages/core/saved-objects/core-saved-objects-utils-server/README.md b/packages/core/saved-objects/core-saved-objects-utils-server/README.md new file mode 100644 index 00000000000000..ecbfa469575aec --- /dev/null +++ b/packages/core/saved-objects/core-saved-objects-utils-server/README.md @@ -0,0 +1,5 @@ +# @kbn/core-saved-objects-utils-server + +This package contains public utilities for Core's server-side `savedObjects` domain. + + diff --git a/packages/shared-ux/storybook/mock/jest.config.js b/packages/core/saved-objects/core-saved-objects-utils-server/jest.config.js similarity index 83% rename from packages/shared-ux/storybook/mock/jest.config.js rename to packages/core/saved-objects/core-saved-objects-utils-server/jest.config.js index f29327c23ca150..5458bf05b67678 100644 --- a/packages/shared-ux/storybook/mock/jest.config.js +++ b/packages/core/saved-objects/core-saved-objects-utils-server/jest.config.js @@ -9,5 +9,5 @@ module.exports = { preset: '@kbn/test/jest_node', rootDir: '../../../..', - roots: ['/packages/shared-ux/storybook/mock'], + roots: ['/packages/core/saved-objects/core-saved-objects-utils-server'], }; diff --git a/packages/core/saved-objects/core-saved-objects-utils-server/package.json b/packages/core/saved-objects/core-saved-objects-utils-server/package.json new file mode 100644 index 00000000000000..13220da373261d --- /dev/null +++ b/packages/core/saved-objects/core-saved-objects-utils-server/package.json @@ -0,0 +1,7 @@ +{ + "name": "@kbn/core-saved-objects-utils-server", + "private": true, + "version": "1.0.0", + "main": "./target_node/index.js", + "license": "SSPL-1.0 OR Elastic License 2.0" +} diff --git a/packages/kbn-shared-ux-storybook/src/index.ts b/packages/core/saved-objects/core-saved-objects-utils-server/src/index.ts old mode 100755 new mode 100644 similarity index 52% rename from packages/kbn-shared-ux-storybook/src/index.ts rename to packages/core/saved-objects/core-saved-objects-utils-server/src/index.ts index 6b310673eb00db..3704cebf083984 --- a/packages/kbn-shared-ux-storybook/src/index.ts +++ b/packages/core/saved-objects/core-saved-objects-utils-server/src/index.ts @@ -6,17 +6,12 @@ * Side Public License, v 1. */ -export { servicesDecorator } from './decorators'; - +export { mergeSavedObjectMigrationMaps } from './merge_migration_maps'; +export { SavedObjectsErrorHelpers, type DecoratedError } from './saved_objects_error_helpers'; export { - applicationServiceFactory, - docLinksServiceFactory, - editorsServiceFactory, - httpServiceFactory, - platformServiceFactory, - servicesFactory, - userPermissionsServiceFactory, - dataServiceFactory, -} from './services'; - -export type { DataServiceFactoryConfig } from './services'; + SavedObjectsUtils, + ALL_NAMESPACES_STRING, + DEFAULT_NAMESPACE_STRING, + FIND_DEFAULT_PAGE, + FIND_DEFAULT_PER_PAGE, +} from './saved_objects_utils'; diff --git a/src/core/server/saved_objects/migrations/utils.test.ts b/packages/core/saved-objects/core-saved-objects-utils-server/src/merge_migration_maps.test.ts similarity index 96% rename from src/core/server/saved_objects/migrations/utils.test.ts rename to packages/core/saved-objects/core-saved-objects-utils-server/src/merge_migration_maps.test.ts index e3378c3fb9e783..28b3ebd3735b4f 100644 --- a/src/core/server/saved_objects/migrations/utils.test.ts +++ b/packages/core/saved-objects/core-saved-objects-utils-server/src/merge_migration_maps.test.ts @@ -11,7 +11,7 @@ import type { SavedObjectMigrationMap, SavedObjectUnsanitizedDoc, } from '@kbn/core-saved-objects-server'; -import { mergeSavedObjectMigrationMaps } from './utils'; +import { mergeSavedObjectMigrationMaps } from './merge_migration_maps'; describe('mergeSavedObjectMigrationMaps', () => { const obj1: SavedObjectMigrationMap = { diff --git a/src/core/server/saved_objects/migrations/utils.ts b/packages/core/saved-objects/core-saved-objects-utils-server/src/merge_migration_maps.ts similarity index 96% rename from src/core/server/saved_objects/migrations/utils.ts rename to packages/core/saved-objects/core-saved-objects-utils-server/src/merge_migration_maps.ts index 108317fc6698bb..e5f2f1d74a7cf1 100644 --- a/src/core/server/saved_objects/migrations/utils.ts +++ b/packages/core/saved-objects/core-saved-objects-utils-server/src/merge_migration_maps.ts @@ -7,12 +7,12 @@ */ import { mergeWith } from 'lodash'; -import { +import type { SavedObjectMigrationContext, SavedObjectMigrationFn, SavedObjectMigrationMap, SavedObjectUnsanitizedDoc, -} from '../..'; +} from '@kbn/core-saved-objects-server'; /** * Merges two saved object migration maps. diff --git a/src/core/server/saved_objects/service/lib/errors.test.ts b/packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.test.ts similarity index 99% rename from src/core/server/saved_objects/service/lib/errors.test.ts rename to packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.test.ts index 3bea693429254e..6f312a09a56e9d 100644 --- a/src/core/server/saved_objects/service/lib/errors.test.ts +++ b/packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.test.ts @@ -7,8 +7,7 @@ */ import Boom from '@hapi/boom'; - -import { SavedObjectsErrorHelpers } from './errors'; +import { SavedObjectsErrorHelpers } from './saved_objects_error_helpers'; describe('savedObjectsClient/errorTypes', () => { describe('BadRequest error', () => { diff --git a/src/core/server/saved_objects/service/lib/errors.ts b/packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.ts similarity index 100% rename from src/core/server/saved_objects/service/lib/errors.ts rename to packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.ts diff --git a/src/core/server/saved_objects/service/lib/utils.test.mock.ts b/packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_utils.test.mock.ts similarity index 100% rename from src/core/server/saved_objects/service/lib/utils.test.mock.ts rename to packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_utils.test.mock.ts diff --git a/src/core/server/saved_objects/service/lib/utils.test.ts b/packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_utils.test.ts similarity index 94% rename from src/core/server/saved_objects/service/lib/utils.test.ts rename to packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_utils.test.ts index 8c836afd087d36..717b52ef248ca8 100644 --- a/src/core/server/saved_objects/service/lib/utils.test.ts +++ b/packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_utils.test.ts @@ -6,10 +6,10 @@ * Side Public License, v 1. */ -import { mockUuidv1, mockUuidv5 } from './utils.test.mock'; +import { mockUuidv1, mockUuidv5 } from './saved_objects_utils.test.mock'; -import { SavedObjectsFindOptions } from '@kbn/core-saved-objects-api-server'; -import { SavedObjectsUtils } from './utils'; +import type { SavedObjectsFindOptions } from '@kbn/core-saved-objects-api-server'; +import { SavedObjectsUtils } from './saved_objects_utils'; describe('SavedObjectsUtils', () => { const { diff --git a/src/core/server/saved_objects/service/lib/utils.ts b/packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_utils.ts similarity index 100% rename from src/core/server/saved_objects/service/lib/utils.ts rename to packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_utils.ts diff --git a/packages/core/saved-objects/core-saved-objects-utils-server/tsconfig.json b/packages/core/saved-objects/core-saved-objects-utils-server/tsconfig.json new file mode 100644 index 00000000000000..39d3c7097814ac --- /dev/null +++ b/packages/core/saved-objects/core-saved-objects-utils-server/tsconfig.json @@ -0,0 +1,18 @@ +{ + "extends": "../../../../tsconfig.bazel.json", + "compilerOptions": { + "declaration": true, + "declarationMap": true, + "emitDeclarationOnly": true, + "outDir": "target_types", + "rootDir": "src", + "stripInternal": false, + "types": [ + "jest", + "node" + ] + }, + "include": [ + "src/**/*" + ] +} diff --git a/packages/core/test-helpers/core-test-helpers-deprecations-getters/BUILD.bazel b/packages/core/test-helpers/core-test-helpers-deprecations-getters/BUILD.bazel index 19d2290d18f848..3eb0b8d9184fa0 100644 --- a/packages/core/test-helpers/core-test-helpers-deprecations-getters/BUILD.bazel +++ b/packages/core/test-helpers/core-test-helpers-deprecations-getters/BUILD.bazel @@ -27,7 +27,7 @@ NPM_MODULE_EXTRA_FILES = [ ] RUNTIME_DEPS = [ - "//packages/elastic-safer-lodash-set", + "//packages/kbn-safer-lodash-set", "//packages/kbn-config", "//packages/kbn-config-mocks", ] @@ -35,7 +35,7 @@ RUNTIME_DEPS = [ TYPES_DEPS = [ "@npm//@types/node", "@npm//@types/jest", - "//packages/elastic-safer-lodash-set:npm_module_types", + "//packages/kbn-safer-lodash-set:npm_module_types", "//packages/kbn-config:npm_module_types", "//packages/kbn-config-mocks:npm_module_types", ] diff --git a/packages/core/test-helpers/core-test-helpers-deprecations-getters/src/deprecations_getters.ts b/packages/core/test-helpers/core-test-helpers-deprecations-getters/src/deprecations_getters.ts index 825649a77ac519..9bdbd9c9b3efa2 100644 --- a/packages/core/test-helpers/core-test-helpers-deprecations-getters/src/deprecations_getters.ts +++ b/packages/core/test-helpers/core-test-helpers-deprecations-getters/src/deprecations_getters.ts @@ -5,7 +5,7 @@ * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ -import { set } from '@elastic/safer-lodash-set'; +import { set } from '@kbn/safer-lodash-set'; import type { ConfigDeprecationProvider, ConfigDeprecationContext } from '@kbn/config'; import { configDeprecationFactory, applyDeprecations } from '@kbn/config'; import { configDeprecationsMock } from '@kbn/config-mocks'; diff --git a/packages/kbn-apm-config-loader/BUILD.bazel b/packages/kbn-apm-config-loader/BUILD.bazel index 74b7fdfe52a1ad..b7d9249c9f5872 100644 --- a/packages/kbn-apm-config-loader/BUILD.bazel +++ b/packages/kbn-apm-config-loader/BUILD.bazel @@ -27,14 +27,14 @@ NPM_MODULE_EXTRA_FILES = [ ] RUNTIME_DEPS = [ - "//packages/elastic-safer-lodash-set", + "//packages/kbn-safer-lodash-set", "//packages/kbn-utils", "@npm//js-yaml", "@npm//lodash", ] TYPES_DEPS = [ - "//packages/elastic-safer-lodash-set:npm_module_types", + "//packages/kbn-safer-lodash-set:npm_module_types", "//packages/kbn-utils:npm_module_types", "@npm//@elastic/apm-rum", "@npm//@types/jest", diff --git a/packages/kbn-apm-config-loader/src/utils/apply_config_overrides.ts b/packages/kbn-apm-config-loader/src/utils/apply_config_overrides.ts index e2ae5a2dce3ba1..54993ce0843f93 100644 --- a/packages/kbn-apm-config-loader/src/utils/apply_config_overrides.ts +++ b/packages/kbn-apm-config-loader/src/utils/apply_config_overrides.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import { set } from '@elastic/safer-lodash-set'; +import { set } from '@kbn/safer-lodash-set'; import { getArgValue } from './read_argv'; /** diff --git a/packages/kbn-apm-config-loader/src/utils/read_config.ts b/packages/kbn-apm-config-loader/src/utils/read_config.ts index 0d6fce88b0532e..f41f8e66c7d5b5 100644 --- a/packages/kbn-apm-config-loader/src/utils/read_config.ts +++ b/packages/kbn-apm-config-loader/src/utils/read_config.ts @@ -9,7 +9,7 @@ import { readFileSync } from 'fs'; import { safeLoad } from 'js-yaml'; -import { set } from '@elastic/safer-lodash-set'; +import { set } from '@kbn/safer-lodash-set'; import { isPlainObject } from 'lodash'; import { ensureDeepObject } from './ensure_deep_object'; diff --git a/packages/elastic-apm-synthtrace/BUILD.bazel b/packages/kbn-apm-synthtrace/BUILD.bazel similarity index 96% rename from packages/elastic-apm-synthtrace/BUILD.bazel rename to packages/kbn-apm-synthtrace/BUILD.bazel index d0963f43e171b2..0e759e33c0ab5b 100644 --- a/packages/elastic-apm-synthtrace/BUILD.bazel +++ b/packages/kbn-apm-synthtrace/BUILD.bazel @@ -2,8 +2,8 @@ load("@npm//@bazel/typescript:index.bzl", "ts_config") load("@build_bazel_rules_nodejs//:index.bzl", "js_library") load("//src/dev/bazel:index.bzl", "jsts_transpiler", "pkg_npm", "pkg_npm_types", "ts_project") -PKG_BASE_NAME = "elastic-apm-synthtrace" -PKG_REQUIRE_NAME = "@elastic/apm-synthtrace" +PKG_BASE_NAME = "kbn-apm-synthtrace" +PKG_REQUIRE_NAME = "@kbn/apm-synthtrace" SOURCE_FILES = glob( [ diff --git a/packages/elastic-apm-synthtrace/README.md b/packages/kbn-apm-synthtrace/README.md similarity index 92% rename from packages/elastic-apm-synthtrace/README.md rename to packages/kbn-apm-synthtrace/README.md index 24ce3b055abd0d..3afc25fb7e9a81 100644 --- a/packages/elastic-apm-synthtrace/README.md +++ b/packages/kbn-apm-synthtrace/README.md @@ -1,6 +1,6 @@ -# @elastic/apm-synthtrace +# @kbn/apm-synthtrace -`@elastic/apm-synthtrace` is a tool in technical preview to generate synthetic APM data. It is intended to be used for development and testing of the Elastic APM app in Kibana. +`@kbn/apm-synthtrace` is a tool in technical preview to generate synthetic APM data. It is intended to be used for development and testing of the Elastic APM app in Kibana. At a high-level, the module works by modeling APM events/metricsets with [a fluent API](https://en.wikipedia.org/wiki/Fluent_interface). The models can then be serialized and converted to Elasticsearch documents. In the future we might support APM Server as an output as well. @@ -25,7 +25,7 @@ This library can currently be used in two ways: #### Example ```ts -import { service, timerange, toElasticsearchOutput } from '@elastic/apm-synthtrace'; +import { service, timerange, toElasticsearchOutput } from '@kbn/apm-synthtrace'; const instance = service('synth-go', 'production', 'go').instance('instance-a'); @@ -72,14 +72,14 @@ const esEvents = toElasticsearchOutput(traceEvents.concat(metricsets)); #### Generating metricsets -`@elastic/apm-synthtrace` can also automatically generate transaction metrics, span destination metrics and transaction breakdown metrics based on the generated trace events. If we expand on the previous example: +`@kbn/apm-synthtrace` can also automatically generate transaction metrics, span destination metrics and transaction breakdown metrics based on the generated trace events. If we expand on the previous example: ```ts import { getTransactionMetrics, getSpanDestinationMetrics, getBreakdownMetrics, -} from '@elastic/apm-synthtrace'; +} from '@kbn/apm-synthtrace'; const esEvents = toElasticsearchOutput([ ...traceEvents, @@ -91,7 +91,7 @@ const esEvents = toElasticsearchOutput([ ### CLI -Via the CLI, you can run scenarios, either using a fixed time range or continuously generating data. Scenarios are available in [`packages/elastic-apm-synthtrace/src/scenarios/`](https://github.com/elastic/kibana/blob/main/packages/elastic-apm-synthtrace/src/scenarios/). +Via the CLI, you can run scenarios, either using a fixed time range or continuously generating data. Scenarios are available in [`packages/kbn-apm-synthtrace/src/scenarios/`](https://github.com/elastic/kibana/blob/main/packages/kbn-apm-synthtrace/src/scenarios/). For live data ingestion: diff --git a/packages/elastic-apm-synthtrace/bin/synthtrace b/packages/kbn-apm-synthtrace/bin/synthtrace similarity index 100% rename from packages/elastic-apm-synthtrace/bin/synthtrace rename to packages/kbn-apm-synthtrace/bin/synthtrace diff --git a/packages/elastic-apm-synthtrace/jest.config.js b/packages/kbn-apm-synthtrace/jest.config.js similarity index 89% rename from packages/elastic-apm-synthtrace/jest.config.js rename to packages/kbn-apm-synthtrace/jest.config.js index 13d8643c5213cd..e89880dc7e8dfd 100644 --- a/packages/elastic-apm-synthtrace/jest.config.js +++ b/packages/kbn-apm-synthtrace/jest.config.js @@ -9,7 +9,7 @@ module.exports = { preset: '@kbn/test', rootDir: '../..', - roots: ['/packages/elastic-apm-synthtrace'], + roots: ['/packages/kbn-apm-synthtrace'], setupFiles: [], setupFilesAfterEnv: [], }; diff --git a/packages/elastic-apm-synthtrace/package.json b/packages/kbn-apm-synthtrace/package.json similarity index 86% rename from packages/elastic-apm-synthtrace/package.json rename to packages/kbn-apm-synthtrace/package.json index bbfcd496c922b8..17d4c9b10b75be 100644 --- a/packages/elastic-apm-synthtrace/package.json +++ b/packages/kbn-apm-synthtrace/package.json @@ -1,5 +1,5 @@ { - "name": "@elastic/apm-synthtrace", + "name": "@kbn/apm-synthtrace", "version": "0.1.0", "description": "Elastic APM trace data generator", "license": "SSPL-1.0 OR Elastic License 2.0", diff --git a/packages/elastic-apm-synthtrace/src/.eslintrc.js b/packages/kbn-apm-synthtrace/src/.eslintrc.js similarity index 100% rename from packages/elastic-apm-synthtrace/src/.eslintrc.js rename to packages/kbn-apm-synthtrace/src/.eslintrc.js diff --git a/packages/elastic-apm-synthtrace/src/cli.ts b/packages/kbn-apm-synthtrace/src/cli.ts similarity index 100% rename from packages/elastic-apm-synthtrace/src/cli.ts rename to packages/kbn-apm-synthtrace/src/cli.ts diff --git a/packages/elastic-apm-synthtrace/src/cli/run_synthtrace.ts b/packages/kbn-apm-synthtrace/src/cli/run_synthtrace.ts similarity index 100% rename from packages/elastic-apm-synthtrace/src/cli/run_synthtrace.ts rename to packages/kbn-apm-synthtrace/src/cli/run_synthtrace.ts diff --git a/packages/elastic-apm-synthtrace/src/cli/scenario.ts b/packages/kbn-apm-synthtrace/src/cli/scenario.ts similarity index 100% rename from packages/elastic-apm-synthtrace/src/cli/scenario.ts rename to packages/kbn-apm-synthtrace/src/cli/scenario.ts diff --git a/packages/elastic-apm-synthtrace/src/cli/utils/get_common_services.ts b/packages/kbn-apm-synthtrace/src/cli/utils/get_common_services.ts similarity index 100% rename from packages/elastic-apm-synthtrace/src/cli/utils/get_common_services.ts rename to packages/kbn-apm-synthtrace/src/cli/utils/get_common_services.ts diff --git a/packages/elastic-apm-synthtrace/src/cli/utils/get_scenario.ts b/packages/kbn-apm-synthtrace/src/cli/utils/get_scenario.ts similarity index 100% rename from packages/elastic-apm-synthtrace/src/cli/utils/get_scenario.ts rename to packages/kbn-apm-synthtrace/src/cli/utils/get_scenario.ts diff --git a/packages/elastic-apm-synthtrace/src/cli/utils/interval_to_ms.ts b/packages/kbn-apm-synthtrace/src/cli/utils/interval_to_ms.ts similarity index 100% rename from packages/elastic-apm-synthtrace/src/cli/utils/interval_to_ms.ts rename to packages/kbn-apm-synthtrace/src/cli/utils/interval_to_ms.ts diff --git a/packages/elastic-apm-synthtrace/src/cli/utils/parse_run_cli_flags.ts b/packages/kbn-apm-synthtrace/src/cli/utils/parse_run_cli_flags.ts similarity index 100% rename from packages/elastic-apm-synthtrace/src/cli/utils/parse_run_cli_flags.ts rename to packages/kbn-apm-synthtrace/src/cli/utils/parse_run_cli_flags.ts diff --git a/packages/elastic-apm-synthtrace/src/cli/utils/start_historical_data_upload.ts b/packages/kbn-apm-synthtrace/src/cli/utils/start_historical_data_upload.ts similarity index 100% rename from packages/elastic-apm-synthtrace/src/cli/utils/start_historical_data_upload.ts rename to packages/kbn-apm-synthtrace/src/cli/utils/start_historical_data_upload.ts diff --git a/packages/elastic-apm-synthtrace/src/cli/utils/start_live_data_upload.ts b/packages/kbn-apm-synthtrace/src/cli/utils/start_live_data_upload.ts similarity index 100% rename from packages/elastic-apm-synthtrace/src/cli/utils/start_live_data_upload.ts rename to packages/kbn-apm-synthtrace/src/cli/utils/start_live_data_upload.ts diff --git a/packages/elastic-apm-synthtrace/src/cli/utils/synthtrace_worker.ts b/packages/kbn-apm-synthtrace/src/cli/utils/synthtrace_worker.ts similarity index 100% rename from packages/elastic-apm-synthtrace/src/cli/utils/synthtrace_worker.ts rename to packages/kbn-apm-synthtrace/src/cli/utils/synthtrace_worker.ts diff --git a/packages/elastic-apm-synthtrace/src/cli/utils/worker.js b/packages/kbn-apm-synthtrace/src/cli/utils/worker.js similarity index 100% rename from packages/elastic-apm-synthtrace/src/cli/utils/worker.js rename to packages/kbn-apm-synthtrace/src/cli/utils/worker.js diff --git a/packages/elastic-apm-synthtrace/src/index.ts b/packages/kbn-apm-synthtrace/src/index.ts similarity index 100% rename from packages/elastic-apm-synthtrace/src/index.ts rename to packages/kbn-apm-synthtrace/src/index.ts diff --git a/packages/elastic-apm-synthtrace/src/lib/agent_config/agent_config.ts b/packages/kbn-apm-synthtrace/src/lib/agent_config/agent_config.ts similarity index 100% rename from packages/elastic-apm-synthtrace/src/lib/agent_config/agent_config.ts rename to packages/kbn-apm-synthtrace/src/lib/agent_config/agent_config.ts diff --git a/packages/elastic-apm-synthtrace/src/lib/agent_config/agent_config_fields.ts b/packages/kbn-apm-synthtrace/src/lib/agent_config/agent_config_fields.ts similarity index 100% rename from packages/elastic-apm-synthtrace/src/lib/agent_config/agent_config_fields.ts rename to packages/kbn-apm-synthtrace/src/lib/agent_config/agent_config_fields.ts diff --git a/packages/elastic-apm-synthtrace/src/lib/agent_config/index.ts b/packages/kbn-apm-synthtrace/src/lib/agent_config/index.ts similarity index 100% rename from packages/elastic-apm-synthtrace/src/lib/agent_config/index.ts rename to packages/kbn-apm-synthtrace/src/lib/agent_config/index.ts diff --git a/packages/elastic-apm-synthtrace/src/lib/agent_config/observer.ts b/packages/kbn-apm-synthtrace/src/lib/agent_config/observer.ts similarity index 100% rename from packages/elastic-apm-synthtrace/src/lib/agent_config/observer.ts rename to packages/kbn-apm-synthtrace/src/lib/agent_config/observer.ts diff --git a/packages/elastic-apm-synthtrace/src/lib/apm/aggregators/service_latency_aggregator.ts b/packages/kbn-apm-synthtrace/src/lib/apm/aggregators/service_latency_aggregator.ts similarity index 100% rename from packages/elastic-apm-synthtrace/src/lib/apm/aggregators/service_latency_aggregator.ts rename to packages/kbn-apm-synthtrace/src/lib/apm/aggregators/service_latency_aggregator.ts diff --git a/packages/elastic-apm-synthtrace/src/lib/apm/apm_error.ts b/packages/kbn-apm-synthtrace/src/lib/apm/apm_error.ts similarity index 100% rename from packages/elastic-apm-synthtrace/src/lib/apm/apm_error.ts rename to packages/kbn-apm-synthtrace/src/lib/apm/apm_error.ts diff --git a/packages/elastic-apm-synthtrace/src/lib/apm/apm_fields.ts b/packages/kbn-apm-synthtrace/src/lib/apm/apm_fields.ts similarity index 100% rename from packages/elastic-apm-synthtrace/src/lib/apm/apm_fields.ts rename to packages/kbn-apm-synthtrace/src/lib/apm/apm_fields.ts diff --git a/packages/elastic-apm-synthtrace/src/lib/apm/base_span.ts b/packages/kbn-apm-synthtrace/src/lib/apm/base_span.ts similarity index 100% rename from packages/elastic-apm-synthtrace/src/lib/apm/base_span.ts rename to packages/kbn-apm-synthtrace/src/lib/apm/base_span.ts diff --git a/packages/elastic-apm-synthtrace/src/lib/apm/browser.ts b/packages/kbn-apm-synthtrace/src/lib/apm/browser.ts similarity index 100% rename from packages/elastic-apm-synthtrace/src/lib/apm/browser.ts rename to packages/kbn-apm-synthtrace/src/lib/apm/browser.ts diff --git a/packages/elastic-apm-synthtrace/src/lib/apm/client/apm_synthtrace_es_client.ts b/packages/kbn-apm-synthtrace/src/lib/apm/client/apm_synthtrace_es_client.ts similarity index 100% rename from packages/elastic-apm-synthtrace/src/lib/apm/client/apm_synthtrace_es_client.ts rename to packages/kbn-apm-synthtrace/src/lib/apm/client/apm_synthtrace_es_client.ts diff --git a/packages/elastic-apm-synthtrace/src/lib/apm/client/apm_synthtrace_kibana_client.ts b/packages/kbn-apm-synthtrace/src/lib/apm/client/apm_synthtrace_kibana_client.ts similarity index 92% rename from packages/elastic-apm-synthtrace/src/lib/apm/client/apm_synthtrace_kibana_client.ts rename to packages/kbn-apm-synthtrace/src/lib/apm/client/apm_synthtrace_kibana_client.ts index bf068d7f331857..7bd2443031c800 100644 --- a/packages/elastic-apm-synthtrace/src/lib/apm/client/apm_synthtrace_kibana_client.ts +++ b/packages/kbn-apm-synthtrace/src/lib/apm/client/apm_synthtrace_kibana_client.ts @@ -54,9 +54,8 @@ export class ApmSynthtraceKibanaClient { }); } async fetchLatestApmPackageVersion(currentKibanaVersion: string) { - const url = - 'https://epr-snapshot.elastic.co/search?package=apm&prerelease=true&all=true&kibana.version='; - const response = await fetch(url + currentKibanaVersion, { method: 'GET' }); + const url = `https://epr-snapshot.elastic.co/search?package=apm&prerelease=true&all=true&kibana.version=${currentKibanaVersion}`; + const response = await fetch(url, { method: 'GET' }); const json = (await response.json()) as Array<{ version: string }>; const packageVersions = (json ?? []).map((item) => item.version).sort(Semver.rcompare); const validPackageVersions = packageVersions.filter((v) => Semver.valid(v)); @@ -71,7 +70,7 @@ export class ApmSynthtraceKibanaClient { async installApmPackage(kibanaUrl: string, version: string, username: string, password: string) { const packageVersion = await this.fetchLatestApmPackageVersion(version); - const response = await fetch(kibanaUrl + '/api/fleet/epm/packages/apm/' + packageVersion, { + const response = await fetch(`${kibanaUrl}/api/fleet/epm/packages/apm/${packageVersion}`, { method: 'POST', headers: { Authorization: 'Basic ' + Buffer.from(username + ':' + password).toString('base64'), diff --git a/packages/elastic-apm-synthtrace/src/lib/apm/defaults/get_chrome_user_agent_defaults.ts b/packages/kbn-apm-synthtrace/src/lib/apm/defaults/get_chrome_user_agent_defaults.ts similarity index 100% rename from packages/elastic-apm-synthtrace/src/lib/apm/defaults/get_chrome_user_agent_defaults.ts rename to packages/kbn-apm-synthtrace/src/lib/apm/defaults/get_chrome_user_agent_defaults.ts diff --git a/packages/elastic-apm-synthtrace/src/lib/apm/index.ts b/packages/kbn-apm-synthtrace/src/lib/apm/index.ts similarity index 91% rename from packages/elastic-apm-synthtrace/src/lib/apm/index.ts rename to packages/kbn-apm-synthtrace/src/lib/apm/index.ts index fcb8e078bf02ab..a136daabee8f2f 100644 --- a/packages/elastic-apm-synthtrace/src/lib/apm/index.ts +++ b/packages/kbn-apm-synthtrace/src/lib/apm/index.ts @@ -13,6 +13,7 @@ import { getChromeUserAgentDefaults } from './defaults/get_chrome_user_agent_def import { getBreakdownMetrics } from './processors/get_breakdown_metrics'; import { getApmWriteTargets } from './utils/get_apm_write_targets'; import { ApmSynthtraceEsClient } from './client/apm_synthtrace_es_client'; +import { ApmSynthtraceKibanaClient } from './client/apm_synthtrace_kibana_client'; import type { ApmException } from './apm_fields'; @@ -25,6 +26,7 @@ export const apm = { getBreakdownMetrics, getApmWriteTargets, ApmSynthtraceEsClient, + ApmSynthtraceKibanaClient, }; export type { ApmSynthtraceEsClient, ApmException }; diff --git a/packages/elastic-apm-synthtrace/src/lib/apm/instance.ts b/packages/kbn-apm-synthtrace/src/lib/apm/instance.ts similarity index 100% rename from packages/elastic-apm-synthtrace/src/lib/apm/instance.ts rename to packages/kbn-apm-synthtrace/src/lib/apm/instance.ts diff --git a/packages/elastic-apm-synthtrace/src/lib/apm/metricset.ts b/packages/kbn-apm-synthtrace/src/lib/apm/metricset.ts similarity index 100% rename from packages/elastic-apm-synthtrace/src/lib/apm/metricset.ts rename to packages/kbn-apm-synthtrace/src/lib/apm/metricset.ts diff --git a/packages/elastic-apm-synthtrace/src/lib/apm/processors/get_breakdown_metrics.ts b/packages/kbn-apm-synthtrace/src/lib/apm/processors/get_breakdown_metrics.ts similarity index 100% rename from packages/elastic-apm-synthtrace/src/lib/apm/processors/get_breakdown_metrics.ts rename to packages/kbn-apm-synthtrace/src/lib/apm/processors/get_breakdown_metrics.ts diff --git a/packages/elastic-apm-synthtrace/src/lib/apm/processors/get_span_destination_metrics.ts b/packages/kbn-apm-synthtrace/src/lib/apm/processors/get_span_destination_metrics.ts similarity index 100% rename from packages/elastic-apm-synthtrace/src/lib/apm/processors/get_span_destination_metrics.ts rename to packages/kbn-apm-synthtrace/src/lib/apm/processors/get_span_destination_metrics.ts diff --git a/packages/elastic-apm-synthtrace/src/lib/apm/processors/get_transaction_metrics.ts b/packages/kbn-apm-synthtrace/src/lib/apm/processors/get_transaction_metrics.ts similarity index 100% rename from packages/elastic-apm-synthtrace/src/lib/apm/processors/get_transaction_metrics.ts rename to packages/kbn-apm-synthtrace/src/lib/apm/processors/get_transaction_metrics.ts diff --git a/packages/elastic-apm-synthtrace/src/lib/apm/rum_span.ts b/packages/kbn-apm-synthtrace/src/lib/apm/rum_span.ts similarity index 100% rename from packages/elastic-apm-synthtrace/src/lib/apm/rum_span.ts rename to packages/kbn-apm-synthtrace/src/lib/apm/rum_span.ts diff --git a/packages/elastic-apm-synthtrace/src/lib/apm/rum_transaction.ts b/packages/kbn-apm-synthtrace/src/lib/apm/rum_transaction.ts similarity index 100% rename from packages/elastic-apm-synthtrace/src/lib/apm/rum_transaction.ts rename to packages/kbn-apm-synthtrace/src/lib/apm/rum_transaction.ts diff --git a/packages/elastic-apm-synthtrace/src/lib/apm/service.ts b/packages/kbn-apm-synthtrace/src/lib/apm/service.ts similarity index 100% rename from packages/elastic-apm-synthtrace/src/lib/apm/service.ts rename to packages/kbn-apm-synthtrace/src/lib/apm/service.ts diff --git a/packages/elastic-apm-synthtrace/src/lib/apm/span.ts b/packages/kbn-apm-synthtrace/src/lib/apm/span.ts similarity index 100% rename from packages/elastic-apm-synthtrace/src/lib/apm/span.ts rename to packages/kbn-apm-synthtrace/src/lib/apm/span.ts diff --git a/packages/elastic-apm-synthtrace/src/lib/apm/transaction.ts b/packages/kbn-apm-synthtrace/src/lib/apm/transaction.ts similarity index 100% rename from packages/elastic-apm-synthtrace/src/lib/apm/transaction.ts rename to packages/kbn-apm-synthtrace/src/lib/apm/transaction.ts diff --git a/packages/elastic-apm-synthtrace/src/lib/apm/utils/aggregate.ts b/packages/kbn-apm-synthtrace/src/lib/apm/utils/aggregate.ts similarity index 100% rename from packages/elastic-apm-synthtrace/src/lib/apm/utils/aggregate.ts rename to packages/kbn-apm-synthtrace/src/lib/apm/utils/aggregate.ts diff --git a/packages/elastic-apm-synthtrace/src/lib/apm/utils/create_picker.ts b/packages/kbn-apm-synthtrace/src/lib/apm/utils/create_picker.ts similarity index 100% rename from packages/elastic-apm-synthtrace/src/lib/apm/utils/create_picker.ts rename to packages/kbn-apm-synthtrace/src/lib/apm/utils/create_picker.ts diff --git a/packages/elastic-apm-synthtrace/src/lib/apm/utils/get_apm_write_targets.ts b/packages/kbn-apm-synthtrace/src/lib/apm/utils/get_apm_write_targets.ts similarity index 100% rename from packages/elastic-apm-synthtrace/src/lib/apm/utils/get_apm_write_targets.ts rename to packages/kbn-apm-synthtrace/src/lib/apm/utils/get_apm_write_targets.ts diff --git a/packages/elastic-apm-synthtrace/src/lib/entity.ts b/packages/kbn-apm-synthtrace/src/lib/entity.ts similarity index 100% rename from packages/elastic-apm-synthtrace/src/lib/entity.ts rename to packages/kbn-apm-synthtrace/src/lib/entity.ts diff --git a/packages/elastic-apm-synthtrace/src/lib/entity_generator.ts b/packages/kbn-apm-synthtrace/src/lib/entity_generator.ts similarity index 100% rename from packages/elastic-apm-synthtrace/src/lib/entity_generator.ts rename to packages/kbn-apm-synthtrace/src/lib/entity_generator.ts diff --git a/packages/elastic-apm-synthtrace/src/lib/entity_iterable.ts b/packages/kbn-apm-synthtrace/src/lib/entity_iterable.ts similarity index 100% rename from packages/elastic-apm-synthtrace/src/lib/entity_iterable.ts rename to packages/kbn-apm-synthtrace/src/lib/entity_iterable.ts diff --git a/packages/elastic-apm-synthtrace/src/lib/entity_streams.ts b/packages/kbn-apm-synthtrace/src/lib/entity_streams.ts similarity index 100% rename from packages/elastic-apm-synthtrace/src/lib/entity_streams.ts rename to packages/kbn-apm-synthtrace/src/lib/entity_streams.ts diff --git a/packages/elastic-apm-synthtrace/src/lib/interval.ts b/packages/kbn-apm-synthtrace/src/lib/interval.ts similarity index 100% rename from packages/elastic-apm-synthtrace/src/lib/interval.ts rename to packages/kbn-apm-synthtrace/src/lib/interval.ts diff --git a/packages/elastic-apm-synthtrace/src/lib/serializable.ts b/packages/kbn-apm-synthtrace/src/lib/serializable.ts similarity index 100% rename from packages/elastic-apm-synthtrace/src/lib/serializable.ts rename to packages/kbn-apm-synthtrace/src/lib/serializable.ts diff --git a/packages/elastic-apm-synthtrace/src/lib/stack_monitoring/cluster.ts b/packages/kbn-apm-synthtrace/src/lib/stack_monitoring/cluster.ts similarity index 100% rename from packages/elastic-apm-synthtrace/src/lib/stack_monitoring/cluster.ts rename to packages/kbn-apm-synthtrace/src/lib/stack_monitoring/cluster.ts diff --git a/packages/elastic-apm-synthtrace/src/lib/stack_monitoring/cluster_stats.ts b/packages/kbn-apm-synthtrace/src/lib/stack_monitoring/cluster_stats.ts similarity index 100% rename from packages/elastic-apm-synthtrace/src/lib/stack_monitoring/cluster_stats.ts rename to packages/kbn-apm-synthtrace/src/lib/stack_monitoring/cluster_stats.ts diff --git a/packages/elastic-apm-synthtrace/src/lib/stack_monitoring/index.ts b/packages/kbn-apm-synthtrace/src/lib/stack_monitoring/index.ts similarity index 100% rename from packages/elastic-apm-synthtrace/src/lib/stack_monitoring/index.ts rename to packages/kbn-apm-synthtrace/src/lib/stack_monitoring/index.ts diff --git a/packages/elastic-apm-synthtrace/src/lib/stack_monitoring/kibana.ts b/packages/kbn-apm-synthtrace/src/lib/stack_monitoring/kibana.ts similarity index 100% rename from packages/elastic-apm-synthtrace/src/lib/stack_monitoring/kibana.ts rename to packages/kbn-apm-synthtrace/src/lib/stack_monitoring/kibana.ts diff --git a/packages/elastic-apm-synthtrace/src/lib/stack_monitoring/kibana_stats.ts b/packages/kbn-apm-synthtrace/src/lib/stack_monitoring/kibana_stats.ts similarity index 100% rename from packages/elastic-apm-synthtrace/src/lib/stack_monitoring/kibana_stats.ts rename to packages/kbn-apm-synthtrace/src/lib/stack_monitoring/kibana_stats.ts diff --git a/packages/elastic-apm-synthtrace/src/lib/stack_monitoring/stack_monitoring_fields.ts b/packages/kbn-apm-synthtrace/src/lib/stack_monitoring/stack_monitoring_fields.ts similarity index 100% rename from packages/elastic-apm-synthtrace/src/lib/stack_monitoring/stack_monitoring_fields.ts rename to packages/kbn-apm-synthtrace/src/lib/stack_monitoring/stack_monitoring_fields.ts diff --git a/packages/elastic-apm-synthtrace/src/lib/stream_aggregator.ts b/packages/kbn-apm-synthtrace/src/lib/stream_aggregator.ts similarity index 100% rename from packages/elastic-apm-synthtrace/src/lib/stream_aggregator.ts rename to packages/kbn-apm-synthtrace/src/lib/stream_aggregator.ts diff --git a/packages/elastic-apm-synthtrace/src/lib/stream_processor.ts b/packages/kbn-apm-synthtrace/src/lib/stream_processor.ts similarity index 100% rename from packages/elastic-apm-synthtrace/src/lib/stream_processor.ts rename to packages/kbn-apm-synthtrace/src/lib/stream_processor.ts diff --git a/packages/elastic-apm-synthtrace/src/lib/timerange.ts b/packages/kbn-apm-synthtrace/src/lib/timerange.ts similarity index 100% rename from packages/elastic-apm-synthtrace/src/lib/timerange.ts rename to packages/kbn-apm-synthtrace/src/lib/timerange.ts diff --git a/packages/elastic-apm-synthtrace/src/lib/utils/clean_write_targets.ts b/packages/kbn-apm-synthtrace/src/lib/utils/clean_write_targets.ts similarity index 100% rename from packages/elastic-apm-synthtrace/src/lib/utils/clean_write_targets.ts rename to packages/kbn-apm-synthtrace/src/lib/utils/clean_write_targets.ts diff --git a/packages/elastic-apm-synthtrace/src/lib/utils/create_logger.ts b/packages/kbn-apm-synthtrace/src/lib/utils/create_logger.ts similarity index 100% rename from packages/elastic-apm-synthtrace/src/lib/utils/create_logger.ts rename to packages/kbn-apm-synthtrace/src/lib/utils/create_logger.ts diff --git a/packages/elastic-apm-synthtrace/src/lib/utils/dedot.ts b/packages/kbn-apm-synthtrace/src/lib/utils/dedot.ts similarity index 100% rename from packages/elastic-apm-synthtrace/src/lib/utils/dedot.ts rename to packages/kbn-apm-synthtrace/src/lib/utils/dedot.ts diff --git a/packages/elastic-apm-synthtrace/src/lib/utils/generate_id.ts b/packages/kbn-apm-synthtrace/src/lib/utils/generate_id.ts similarity index 100% rename from packages/elastic-apm-synthtrace/src/lib/utils/generate_id.ts rename to packages/kbn-apm-synthtrace/src/lib/utils/generate_id.ts diff --git a/packages/elastic-apm-synthtrace/src/lib/utils/get_synthtrace_environment.ts b/packages/kbn-apm-synthtrace/src/lib/utils/get_synthtrace_environment.ts similarity index 100% rename from packages/elastic-apm-synthtrace/src/lib/utils/get_synthtrace_environment.ts rename to packages/kbn-apm-synthtrace/src/lib/utils/get_synthtrace_environment.ts diff --git a/packages/elastic-apm-synthtrace/src/lib/utils/merge_iterable.ts b/packages/kbn-apm-synthtrace/src/lib/utils/merge_iterable.ts similarity index 100% rename from packages/elastic-apm-synthtrace/src/lib/utils/merge_iterable.ts rename to packages/kbn-apm-synthtrace/src/lib/utils/merge_iterable.ts diff --git a/packages/elastic-apm-synthtrace/src/scenarios/agent_config.ts b/packages/kbn-apm-synthtrace/src/scenarios/agent_config.ts similarity index 100% rename from packages/elastic-apm-synthtrace/src/scenarios/agent_config.ts rename to packages/kbn-apm-synthtrace/src/scenarios/agent_config.ts diff --git a/packages/elastic-apm-synthtrace/src/scenarios/aws_lambda.ts b/packages/kbn-apm-synthtrace/src/scenarios/aws_lambda.ts similarity index 100% rename from packages/elastic-apm-synthtrace/src/scenarios/aws_lambda.ts rename to packages/kbn-apm-synthtrace/src/scenarios/aws_lambda.ts diff --git a/packages/elastic-apm-synthtrace/src/scenarios/kibana_stats.ts b/packages/kbn-apm-synthtrace/src/scenarios/kibana_stats.ts similarity index 100% rename from packages/elastic-apm-synthtrace/src/scenarios/kibana_stats.ts rename to packages/kbn-apm-synthtrace/src/scenarios/kibana_stats.ts diff --git a/packages/elastic-apm-synthtrace/src/scenarios/low_throughput.ts b/packages/kbn-apm-synthtrace/src/scenarios/low_throughput.ts similarity index 100% rename from packages/elastic-apm-synthtrace/src/scenarios/low_throughput.ts rename to packages/kbn-apm-synthtrace/src/scenarios/low_throughput.ts diff --git a/packages/elastic-apm-synthtrace/src/scenarios/many_services.ts b/packages/kbn-apm-synthtrace/src/scenarios/many_services.ts similarity index 100% rename from packages/elastic-apm-synthtrace/src/scenarios/many_services.ts rename to packages/kbn-apm-synthtrace/src/scenarios/many_services.ts diff --git a/packages/elastic-apm-synthtrace/src/scenarios/monitoring.ts b/packages/kbn-apm-synthtrace/src/scenarios/monitoring.ts similarity index 100% rename from packages/elastic-apm-synthtrace/src/scenarios/monitoring.ts rename to packages/kbn-apm-synthtrace/src/scenarios/monitoring.ts diff --git a/packages/elastic-apm-synthtrace/src/scenarios/simple_trace.ts b/packages/kbn-apm-synthtrace/src/scenarios/simple_trace.ts similarity index 100% rename from packages/elastic-apm-synthtrace/src/scenarios/simple_trace.ts rename to packages/kbn-apm-synthtrace/src/scenarios/simple_trace.ts diff --git a/packages/elastic-apm-synthtrace/src/scenarios/span_links.ts b/packages/kbn-apm-synthtrace/src/scenarios/span_links.ts similarity index 100% rename from packages/elastic-apm-synthtrace/src/scenarios/span_links.ts rename to packages/kbn-apm-synthtrace/src/scenarios/span_links.ts diff --git a/packages/elastic-apm-synthtrace/src/test/apm_events_to_elasticsearch_output.test.ts b/packages/kbn-apm-synthtrace/src/test/apm_events_to_elasticsearch_output.test.ts similarity index 100% rename from packages/elastic-apm-synthtrace/src/test/apm_events_to_elasticsearch_output.test.ts rename to packages/kbn-apm-synthtrace/src/test/apm_events_to_elasticsearch_output.test.ts diff --git a/packages/elastic-apm-synthtrace/src/test/event_dsl_behavior.test.ts b/packages/kbn-apm-synthtrace/src/test/event_dsl_behavior.test.ts similarity index 100% rename from packages/elastic-apm-synthtrace/src/test/event_dsl_behavior.test.ts rename to packages/kbn-apm-synthtrace/src/test/event_dsl_behavior.test.ts diff --git a/packages/elastic-apm-synthtrace/src/test/rate_per_minute.test.ts b/packages/kbn-apm-synthtrace/src/test/rate_per_minute.test.ts similarity index 100% rename from packages/elastic-apm-synthtrace/src/test/rate_per_minute.test.ts rename to packages/kbn-apm-synthtrace/src/test/rate_per_minute.test.ts diff --git a/packages/elastic-apm-synthtrace/src/test/scenarios/01_simple_trace.test.ts b/packages/kbn-apm-synthtrace/src/test/scenarios/01_simple_trace.test.ts similarity index 100% rename from packages/elastic-apm-synthtrace/src/test/scenarios/01_simple_trace.test.ts rename to packages/kbn-apm-synthtrace/src/test/scenarios/01_simple_trace.test.ts diff --git a/packages/elastic-apm-synthtrace/src/test/scenarios/02_transaction_metrics.test.ts b/packages/kbn-apm-synthtrace/src/test/scenarios/02_transaction_metrics.test.ts similarity index 100% rename from packages/elastic-apm-synthtrace/src/test/scenarios/02_transaction_metrics.test.ts rename to packages/kbn-apm-synthtrace/src/test/scenarios/02_transaction_metrics.test.ts diff --git a/packages/elastic-apm-synthtrace/src/test/scenarios/03_span_destination_metrics.test.ts b/packages/kbn-apm-synthtrace/src/test/scenarios/03_span_destination_metrics.test.ts similarity index 100% rename from packages/elastic-apm-synthtrace/src/test/scenarios/03_span_destination_metrics.test.ts rename to packages/kbn-apm-synthtrace/src/test/scenarios/03_span_destination_metrics.test.ts diff --git a/packages/elastic-apm-synthtrace/src/test/scenarios/04_breakdown_metrics.test.ts b/packages/kbn-apm-synthtrace/src/test/scenarios/04_breakdown_metrics.test.ts similarity index 100% rename from packages/elastic-apm-synthtrace/src/test/scenarios/04_breakdown_metrics.test.ts rename to packages/kbn-apm-synthtrace/src/test/scenarios/04_breakdown_metrics.test.ts diff --git a/packages/elastic-apm-synthtrace/src/test/scenarios/05_transactions_with_errors.test.ts b/packages/kbn-apm-synthtrace/src/test/scenarios/05_transactions_with_errors.test.ts similarity index 100% rename from packages/elastic-apm-synthtrace/src/test/scenarios/05_transactions_with_errors.test.ts rename to packages/kbn-apm-synthtrace/src/test/scenarios/05_transactions_with_errors.test.ts diff --git a/packages/elastic-apm-synthtrace/src/test/scenarios/06_application_metrics.test.ts b/packages/kbn-apm-synthtrace/src/test/scenarios/06_application_metrics.test.ts similarity index 100% rename from packages/elastic-apm-synthtrace/src/test/scenarios/06_application_metrics.test.ts rename to packages/kbn-apm-synthtrace/src/test/scenarios/06_application_metrics.test.ts diff --git a/packages/elastic-apm-synthtrace/src/test/scenarios/__snapshots__/01_simple_trace.test.ts.snap b/packages/kbn-apm-synthtrace/src/test/scenarios/__snapshots__/01_simple_trace.test.ts.snap similarity index 100% rename from packages/elastic-apm-synthtrace/src/test/scenarios/__snapshots__/01_simple_trace.test.ts.snap rename to packages/kbn-apm-synthtrace/src/test/scenarios/__snapshots__/01_simple_trace.test.ts.snap diff --git a/packages/elastic-apm-synthtrace/src/test/streams_merge.test.ts b/packages/kbn-apm-synthtrace/src/test/streams_merge.test.ts similarity index 100% rename from packages/elastic-apm-synthtrace/src/test/streams_merge.test.ts rename to packages/kbn-apm-synthtrace/src/test/streams_merge.test.ts diff --git a/packages/elastic-apm-synthtrace/tsconfig.json b/packages/kbn-apm-synthtrace/tsconfig.json similarity index 100% rename from packages/elastic-apm-synthtrace/tsconfig.json rename to packages/kbn-apm-synthtrace/tsconfig.json diff --git a/packages/kbn-bazel-packages/BUILD.bazel b/packages/kbn-bazel-packages/BUILD.bazel index e3a3545be167d6..9c7a793459623e 100644 --- a/packages/kbn-bazel-packages/BUILD.bazel +++ b/packages/kbn-bazel-packages/BUILD.bazel @@ -7,6 +7,7 @@ PKG_REQUIRE_NAME = "@kbn/bazel-packages" SOURCE_FILES = glob( [ + "src/**/*.js", "src/**/*.ts", ], exclude = [ @@ -37,11 +38,6 @@ NPM_MODULE_EXTRA_FILES = [ # "@npm//name-of-package" # eg. "@npm//lodash" RUNTIME_DEPS = [ - "//packages/kbn-utils", - "//packages/kbn-std", - "//packages/kbn-synthetic-package-map", - "@npm//globby", - "@npm//normalize-path", ] # In this array place dependencies necessary to build the types, which will include the @@ -55,13 +51,8 @@ RUNTIME_DEPS = [ # References to NPM packages work the same as RUNTIME_DEPS: # eg. "@npm//@types/babel__core" TYPES_DEPS = [ - "//packages/kbn-utils:npm_module_types", - "//packages/kbn-std:npm_module_types", - "//packages/kbn-synthetic-package-map:npm_module_types", "@npm//@types/node", - "@npm//@types/normalize-path", - "@npm//globby", - "@npm//normalize-path", + "@npm//@types/jest", ] jsts_transpiler( @@ -87,6 +78,7 @@ ts_project( deps = TYPES_DEPS, declaration = True, declaration_map = True, + allow_js = True, emit_declaration_only = True, out_dir = "target_types", root_dir = "src", diff --git a/packages/kbn-bazel-packages/src/async.js b/packages/kbn-bazel-packages/src/async.js new file mode 100644 index 00000000000000..38b535447953f3 --- /dev/null +++ b/packages/kbn-bazel-packages/src/async.js @@ -0,0 +1,107 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +/** + * + * @template T + * @template T2 + * @param {(v: T) => Promise} fn + * @param {T} item + * @returns {Promise>} + */ +const settle = async (fn, item) => { + const [result] = await Promise.allSettled([(async () => fn(item))()]); + return result; +}; + +/** + * @template T + * @template T2 + * @param {Array} source + * @param {number} limit + * @param {(v: T) => Promise} mapFn + * @returns {Promise} + */ +function asyncMapWithLimit(source, limit, mapFn) { + return new Promise((resolve, reject) => { + if (limit < 1) { + reject(new Error('invalid limit, must be greater than 0')); + return; + } + + let failed = false; + let inProgress = 0; + const queue = [...source.entries()]; + + /** @type {T2[]} */ + const results = new Array(source.length); + + /** + * this is run for each item, manages the inProgress state, + * calls the mapFn with that item, writes the map result to + * the result array, and calls runMore() after each item + * completes to either start another item or resolve the + * returned promise. + * + * @param {number} index + * @param {T} item + */ + function run(index, item) { + inProgress += 1; + settle(mapFn, item).then((result) => { + inProgress -= 1; + + if (failed) { + return; + } + + if (result.status === 'fulfilled') { + results[index] = result.value; + runMore(); + return; + } + + // when an error occurs we update the state to prevent + // holding onto old results and ignore future results + // from in-progress promises + failed = true; + results.length = 0; + reject(result.reason); + }); + } + + /** + * If there is work in the queue, schedule it, if there isn't + * any work to be scheduled and there isn't anything in progress + * then we're done. This function is called every time a mapFn + * promise resolves and once after initialization + */ + function runMore() { + if (!queue.length) { + if (inProgress === 0) { + resolve(results); + } + + return; + } + + while (inProgress < limit) { + const entry = queue.shift(); + if (!entry) { + break; + } + + run(...entry); + } + } + + runMore(); + }); +} + +module.exports = { asyncMapWithLimit }; diff --git a/packages/kbn-bazel-packages/src/async.test.ts b/packages/kbn-bazel-packages/src/async.test.ts new file mode 100644 index 00000000000000..b238783f74fb85 --- /dev/null +++ b/packages/kbn-bazel-packages/src/async.test.ts @@ -0,0 +1,61 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { setTimeout } from 'timers/promises'; +import { asyncMapWithLimit } from './async'; + +const NUMS = [1, 2, 3, 4]; +const ident = jest.fn(async function ident(x: T) { + return await x; +}); +const double = jest.fn(async function double(x: number) { + return x * 2; +}); + +beforeEach(() => { + jest.clearAllMocks(); +}); + +it('resolves with an empty array', async () => { + const result = await asyncMapWithLimit([], 10, ident); + expect(ident).not.toHaveBeenCalled(); + expect(result).toEqual([]); +}); + +it('resolves with a mapped array', async () => { + const result = await asyncMapWithLimit(NUMS, 10, double); + expect(double).toHaveBeenCalledTimes(NUMS.length); + expect(result.join(',')).toMatchInlineSnapshot(`"2,4,6,8"`); +}); + +it('rejects when limit it not >= 1', async () => { + await expect(() => asyncMapWithLimit([], -1, ident)).rejects.toMatchInlineSnapshot( + `[Error: invalid limit, must be greater than 0]` + ); + await expect(() => asyncMapWithLimit([], 0, ident)).rejects.toMatchInlineSnapshot( + `[Error: invalid limit, must be greater than 0]` + ); + await expect(() => asyncMapWithLimit([], -Infinity, ident)).rejects.toMatchInlineSnapshot( + `[Error: invalid limit, must be greater than 0]` + ); +}); + +it('rejects with the first error produced and stops calling mapFn', async () => { + const map = jest.fn(async (num) => { + if (num % 2 === 0) { + throw new Error('even numbers are not supported'); + } + return num * 2; + }); + + await expect(() => asyncMapWithLimit(NUMS, 1, map)).rejects.toMatchInlineSnapshot( + `[Error: even numbers are not supported]` + ); + await setTimeout(10); + expect(map).toHaveBeenCalledTimes(2); +}); diff --git a/packages/kbn-bazel-packages/src/bazel_package.ts b/packages/kbn-bazel-packages/src/bazel_package.js similarity index 67% rename from packages/kbn-bazel-packages/src/bazel_package.ts rename to packages/kbn-bazel-packages/src/bazel_package.js index 91e411770175bd..c6a31ccc0dbc1f 100644 --- a/packages/kbn-bazel-packages/src/bazel_package.ts +++ b/packages/kbn-bazel-packages/src/bazel_package.js @@ -6,27 +6,31 @@ * Side Public License, v 1. */ -import { inspect } from 'util'; -import Path from 'path'; -import Fsp from 'fs/promises'; +const { inspect } = require('util'); +const Path = require('path'); +const Fsp = require('fs/promises'); -import normalizePath from 'normalize-path'; -import { REPO_ROOT } from '@kbn/utils'; - -import { readPackageJson, ParsedPackageJson } from './parse_package_json'; +/** @typedef {import('./types').ParsedPackageJson} ParsedPackageJson */ +const { readPackageJson } = require('./parse_package_json'); const BUILD_RULE_NAME = /(^|\s)name\s*=\s*"build"/; const BUILD_TYPES_RULE_NAME = /(^|\s)name\s*=\s*"build_types"/; /** * Representation of a Bazel Package in the Kibana repository + * @class + * @property {string} normalizedRepoRelativeDir + * @property {import('./types').ParsedPackageJson} pkg + * @property {string | undefined} buildBazelContent */ -export class BazelPackage { +class BazelPackage { /** * Create a BazelPackage object from a package directory. Reads some files from the package and returns * a Promise for a BazelPackage instance. + * @param {string} repoRoot + * @param {string} dir */ - static async fromDir(dir: string) { + static async fromDir(repoRoot, dir) { const pkg = readPackageJson(Path.resolve(dir, 'package.json')); let buildBazelContent; @@ -36,23 +40,30 @@ export class BazelPackage { throw new Error(`unable to read BUILD.bazel file in [${dir}]: ${error.message}`); } - return new BazelPackage(normalizePath(Path.relative(REPO_ROOT, dir)), pkg, buildBazelContent); + return new BazelPackage(Path.relative(repoRoot, dir), pkg, buildBazelContent); } constructor( /** * Relative path from the root of the repository to the package directory + * @type {string} */ - public readonly normalizedRepoRelativeDir: string, + normalizedRepoRelativeDir, /** * Parsed package.json file from the package + * @type {import('./types').ParsedPackageJson} */ - public readonly pkg: ParsedPackageJson, + pkg, /** * Content of the BUILD.bazel file + * @type {string | undefined} */ - private readonly buildBazelContent?: string - ) {} + buildBazelContent = undefined + ) { + this.normalizedRepoRelativeDir = normalizedRepoRelativeDir; + this.pkg = pkg; + this.buildBazelContent = buildBazelContent; + } /** * Returns true if the package includes a `:build` bazel rule @@ -83,3 +94,7 @@ export class BazelPackage { return `BazelPackage<${this.normalizedRepoRelativeDir}>`; } } + +module.exports = { + BazelPackage, +}; diff --git a/packages/kbn-bazel-packages/src/bazel_package_dirs.ts b/packages/kbn-bazel-packages/src/bazel_package_dirs.js similarity index 68% rename from packages/kbn-bazel-packages/src/bazel_package_dirs.ts rename to packages/kbn-bazel-packages/src/bazel_package_dirs.js index 755ef614c04561..7e3f728a21ca72 100644 --- a/packages/kbn-bazel-packages/src/bazel_package_dirs.ts +++ b/packages/kbn-bazel-packages/src/bazel_package_dirs.js @@ -6,10 +6,7 @@ * Side Public License, v 1. */ -import globby from 'globby'; -import Path from 'path'; - -import { REPO_ROOT } from '@kbn/utils'; +const { expandWildcards } = require('./find_files'); /** * This is a list of repo-relative paths to directories containing packages. Do not @@ -19,7 +16,7 @@ import { REPO_ROOT } from '@kbn/utils'; * eg. src/vis_editors => would find a package at src/vis_editors/foo/package.json * src/vis_editors/* => would find a package at src/vis_editors/foo/bar/package.json */ -export const BAZEL_PACKAGE_DIRS = [ +const BAZEL_PACKAGE_DIRS = [ 'packages', 'packages/shared-ux', 'packages/shared-ux/*', @@ -34,18 +31,13 @@ export const BAZEL_PACKAGE_DIRS = [ /** * Resolve all the BAZEL_PACKAGE_DIRS to absolute paths + * @param {string} repoRoot */ -export function getAllBazelPackageDirs() { - return globby.sync(BAZEL_PACKAGE_DIRS, { - cwd: REPO_ROOT, - onlyDirectories: true, - expandDirectories: false, - }); +function getAllBazelPackageDirs(repoRoot) { + return expandWildcards(repoRoot, BAZEL_PACKAGE_DIRS); } -/** - * Resolve all the BAZEL_PACKAGE_DIRS to repo-relative paths - */ -export function getAllRepoRelativeBazelPackageDirs() { - return getAllBazelPackageDirs().map((path) => Path.relative(REPO_ROOT, path)); -} +module.exports = { + BAZEL_PACKAGE_DIRS, + getAllBazelPackageDirs, +}; diff --git a/packages/kbn-bazel-packages/src/discover_packages.js b/packages/kbn-bazel-packages/src/discover_packages.js new file mode 100644 index 00000000000000..17678115c74526 --- /dev/null +++ b/packages/kbn-bazel-packages/src/discover_packages.js @@ -0,0 +1,44 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +const Path = require('path'); + +const { BazelPackage } = require('./bazel_package'); +const { getAllBazelPackageDirs } = require('./bazel_package_dirs'); +const { findPackages } = require('./find_files'); +const { asyncMapWithLimit } = require('./async'); + +/** + * @param {string} repoRoot + */ +function discoverBazelPackageLocations(repoRoot) { + const packagesWithBuildBazel = getAllBazelPackageDirs(repoRoot) + .flatMap((packageDir) => findPackages(packageDir, 'BUILD.bazel')) + .map((path) => Path.dirname(path)); + + // NOTE: only return as discovered packages with a package.json + BUILD.bazel file. + // In the future we should change this to only discover the ones with kibana.jsonc. + return getAllBazelPackageDirs(repoRoot) + .flatMap((packageDir) => findPackages(packageDir, 'package.json')) + .map((path) => Path.dirname(path)) + .filter((pkg) => packagesWithBuildBazel.includes(pkg)) + .sort((a, b) => a.localeCompare(b)); +} + +/** + * @param {string} repoRoot + */ +async function discoverBazelPackages(repoRoot) { + return await asyncMapWithLimit( + discoverBazelPackageLocations(repoRoot), + 100, + async (dir) => await BazelPackage.fromDir(repoRoot, dir) + ); +} + +module.exports = { discoverBazelPackageLocations, discoverBazelPackages }; diff --git a/packages/kbn-bazel-packages/src/discover_packages.ts b/packages/kbn-bazel-packages/src/discover_packages.ts deleted file mode 100644 index 8b78e4e2931188..00000000000000 --- a/packages/kbn-bazel-packages/src/discover_packages.ts +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import Path from 'path'; - -import globby from 'globby'; -import normalizePath from 'normalize-path'; -import { REPO_ROOT } from '@kbn/utils'; -import { asyncMapWithLimit } from '@kbn/std'; - -import { BazelPackage } from './bazel_package'; -import { BAZEL_PACKAGE_DIRS } from './bazel_package_dirs'; - -export function discoverBazelPackageLocations(repoRoot: string) { - const packagesWithPackageJson = globby - .sync( - BAZEL_PACKAGE_DIRS.map((dir) => `${dir}/*/package.json`), - { - cwd: repoRoot, - absolute: true, - } - ) - // NOTE: removing x-pack by default for now to prevent a situation where a BUILD.bazel file - // needs to be added at the root of the folder which will make x-pack to be wrongly recognized - // as a Bazel package in that case - .filter((path) => !normalizePath(path).includes('x-pack/package.json')) - .sort((a, b) => a.localeCompare(b)) - .map((path) => Path.dirname(path)); - - const packagesWithBuildBazel = globby - .sync( - BAZEL_PACKAGE_DIRS.map((dir) => `${dir}/*/BUILD.bazel`), - { - cwd: repoRoot, - absolute: true, - } - ) - .map((path) => Path.dirname(path)); - - // NOTE: only return as discovered packages the ones with a package.json + BUILD.bazel file. - // In the future we should change this to only discover the ones declaring kibana.json. - return packagesWithPackageJson.filter((pkg) => packagesWithBuildBazel.includes(pkg)); -} - -export async function discoverBazelPackages(repoRoot: string = REPO_ROOT) { - return await asyncMapWithLimit( - discoverBazelPackageLocations(repoRoot), - 100, - async (dir) => await BazelPackage.fromDir(dir) - ); -} diff --git a/packages/kbn-bazel-packages/src/find_files.js b/packages/kbn-bazel-packages/src/find_files.js new file mode 100644 index 00000000000000..9be6c2e2560790 --- /dev/null +++ b/packages/kbn-bazel-packages/src/find_files.js @@ -0,0 +1,114 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +const Path = require('path'); +const Fs = require('fs'); + +/** + * @param {string} path + */ +function safeIsFile(path) { + try { + return Fs.statSync(path).isFile(); + } catch (error) { + if (error.code === 'ENOENT') { + return false; + } + + throw error; + } +} + +/** + * @param {string} path + */ +function safeReadDir(path) { + try { + return Fs.readdirSync(path, { + withFileTypes: true, + }); + } catch (error) { + if (error.code === 'ENOENT' || error.code === 'ENOTDIR') { + return []; + } + + throw error; + } +} + +/** + * Search for `name` files in directories within `packageDir` + * + * @param {string} packageDir + * @param {string} name + * @returns {string[]} + */ +function findPackages(packageDir, name) { + return ( + // get the directories within the "package dir" + safeReadDir(packageDir) + // if this directory has a file with the name, it's a match + .flatMap((e) => { + if (!e.isDirectory()) { + return []; + } + + const path = Path.resolve(packageDir, e.name, name); + return safeIsFile(path) ? path : []; + }) + ); +} + +/** + * Expand simple `*` wildcards in patterns, which are otherwise expected to be + * paths relative to `cwd`. + * + * @param {string} cwd + * @param {string[]} patterns + */ +function expandWildcards(cwd, patterns) { + /** @type {Set} */ + const results = new Set(); + + /** @type {Set} */ + const queue = new Set(patterns.map((p) => Path.resolve(cwd, p))); + + for (const pattern of queue) { + let length = 3; + let index = pattern.indexOf('/*/'); + if (index === -1 && pattern.endsWith('/*')) { + length = 2; + index = pattern.length - length; + } + + if (index === -1) { + results.add(pattern); + continue; + } + + const left = pattern.slice(0, index + 1); + const right = pattern.slice(index + length); + for (const ent of safeReadDir(left)) { + if (!ent.isDirectory()) { + continue; + } + + const path = Path.resolve(left, ent.name); + + if (right) { + queue.add(Path.resolve(path, right)); + } else { + results.add(path); + } + } + } + + return [...results]; +} + +module.exports = { findPackages, expandWildcards }; diff --git a/packages/kbn-bazel-packages/src/index.js b/packages/kbn-bazel-packages/src/index.js new file mode 100644 index 00000000000000..254b8bb9da44c6 --- /dev/null +++ b/packages/kbn-bazel-packages/src/index.js @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +/** @typedef {import('./bazel_package').BazelPackage} BazelPackage */ + +const { BAZEL_PACKAGE_DIRS, getAllBazelPackageDirs } = require('./bazel_package_dirs'); +const { discoverBazelPackageLocations, discoverBazelPackages } = require('./discover_packages'); + +module.exports = { + BAZEL_PACKAGE_DIRS, + getAllBazelPackageDirs, + discoverBazelPackageLocations, + discoverBazelPackages, +}; diff --git a/packages/kbn-bazel-packages/src/parse_package_json.ts b/packages/kbn-bazel-packages/src/parse_package_json.js similarity index 57% rename from packages/kbn-bazel-packages/src/parse_package_json.ts rename to packages/kbn-bazel-packages/src/parse_package_json.js index b060656c0c5125..27a78f91a44661 100644 --- a/packages/kbn-bazel-packages/src/parse_package_json.ts +++ b/packages/kbn-bazel-packages/src/parse_package_json.js @@ -6,40 +6,22 @@ * Side Public License, v 1. */ -import Fs from 'fs'; +const Fs = require('fs'); /** - * Simple parsed representation of a package.json file, validated - * by `assertParsedPackageJson()` and extensible as needed in the future + * @param {unknown} v + * @returns {v is Record} */ -export interface ParsedPackageJson { - /** The name of the package, usually `@kbn/`+something */ - name: string; - /** "dependenices" property from package.json */ - dependencies?: Record; - /** "devDependenices" property from package.json */ - devDependencies?: Record; - /** Some kibana specific properties about this package */ - kibana?: { - /** Is this package only intended for dev? */ - devOnly?: boolean; - }; - /** Scripts defined in the package.json file */ - scripts?: { - [key: string]: string | undefined; - }; - /** All other fields in the package.json are typed as unknown as we don't care what they are */ - [key: string]: unknown; -} - -function isObj(v: unknown): v is Record { +function isObj(v) { return !!(typeof v === 'object' && v); } /** * Asserts that given value looks like a parsed package.json file + * @param {unknown} v + * @returns {asserts v is import('./types').ParsedPackageJson} */ -export function assertParsedPackageJson(v: unknown): asserts v is ParsedPackageJson { +function validateParsedPackageJson(v) { if (!isObj(v) || typeof v.name !== 'string') { throw new Error('Expected at least a "name" property'); } @@ -66,14 +48,18 @@ export function assertParsedPackageJson(v: unknown): asserts v is ParsedPackageJ /** * Reads a given package.json file from disk and parses it + * @param {string} path + * @returns {import('./types').ParsedPackageJson} */ -export function readPackageJson(path: string): ParsedPackageJson { +function readPackageJson(path) { let pkg; try { pkg = JSON.parse(Fs.readFileSync(path, 'utf8')); - assertParsedPackageJson(pkg); + validateParsedPackageJson(pkg); } catch (error) { throw new Error(`unable to parse package.json at [${path}]: ${error.message}`); } return pkg; } + +module.exports = { readPackageJson, validateParsedPackageJson }; diff --git a/packages/kbn-bazel-packages/src/types.ts b/packages/kbn-bazel-packages/src/types.ts new file mode 100644 index 00000000000000..dc77d35bc206af --- /dev/null +++ b/packages/kbn-bazel-packages/src/types.ts @@ -0,0 +1,31 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +/** + * Simple parsed representation of a package.json file, validated + * by `assertParsedPackageJson()` and extensible as needed in the future + */ +export interface ParsedPackageJson { + /** The name of the package, usually `@kbn/`+something */ + name: string; + /** "dependenices" property from package.json */ + dependencies?: Record; + /** "devDependenices" property from package.json */ + devDependencies?: Record; + /** Some kibana specific properties about this package */ + kibana?: { + /** Is this package only intended for dev? */ + devOnly?: boolean; + }; + /** Scripts defined in the package.json file */ + scripts?: { + [key: string]: string | undefined; + }; + /** All other fields in the package.json are typed as unknown as we don't care what they are */ + [key: string]: unknown; +} diff --git a/packages/kbn-bazel-packages/tsconfig.json b/packages/kbn-bazel-packages/tsconfig.json index 789c6b3111115d..9f78bc243ac66c 100644 --- a/packages/kbn-bazel-packages/tsconfig.json +++ b/packages/kbn-bazel-packages/tsconfig.json @@ -4,6 +4,8 @@ "declaration": true, "declarationMap": true, "emitDeclarationOnly": true, + "allowJs": true, + "checkJs": true, "outDir": "target_types", "rootDir": "src", "stripInternal": false, diff --git a/packages/kbn-coloring/BUILD.bazel b/packages/kbn-coloring/BUILD.bazel index 4b20561e70c963..f266fe42a904db 100644 --- a/packages/kbn-coloring/BUILD.bazel +++ b/packages/kbn-coloring/BUILD.bazel @@ -41,7 +41,6 @@ NPM_MODULE_EXTRA_FILES = [ RUNTIME_DEPS = [ "//packages/kbn-i18n", "//packages/kbn-i18n-react", - "//packages/kbn-shared-ux-storybook", "//packages/kbn-interpreter", "//packages/kbn-utility-types", "//packages/kbn-shared-ux-utility", @@ -65,7 +64,6 @@ RUNTIME_DEPS = [ TYPES_DEPS = [ "//packages/kbn-i18n:npm_module_types", "//packages/kbn-i18n-react:npm_module_types", - "//packages/kbn-shared-ux-storybook:npm_module_types", "//packages/kbn-interpreter:npm_module_types", "//packages/kbn-utility-types:npm_module_types", "//packages/kbn-shared-ux-utility:npm_module_types", diff --git a/packages/kbn-coloring/src/shared_components/coloring/assets/infinity.tsx b/packages/kbn-coloring/src/shared_components/coloring/assets/infinity.tsx new file mode 100644 index 00000000000000..8e28d98f579bd8 --- /dev/null +++ b/packages/kbn-coloring/src/shared_components/coloring/assets/infinity.tsx @@ -0,0 +1,17 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import React from 'react'; +import { EuiIconProps } from '@elastic/eui'; + +export const InfinityIcon = (props: Omit) => ( + + + + +); diff --git a/packages/kbn-coloring/src/shared_components/coloring/color_ranges/color_ranges.test.tsx b/packages/kbn-coloring/src/shared_components/coloring/color_ranges/color_ranges.test.tsx index 20a694a59283e9..ce2f4f3e6a9fe4 100644 --- a/packages/kbn-coloring/src/shared_components/coloring/color_ranges/color_ranges.test.tsx +++ b/packages/kbn-coloring/src/shared_components/coloring/color_ranges/color_ranges.test.tsx @@ -59,6 +59,7 @@ describe('Color Ranges', () => { continuity: 'none', }, showExtraActions: true, + displayInfinity: false, dispatch, }; }); diff --git a/packages/kbn-coloring/src/shared_components/coloring/color_ranges/color_ranges.tsx b/packages/kbn-coloring/src/shared_components/coloring/color_ranges/color_ranges.tsx index b8d8b3aa604d19..99055f904d2ea4 100644 --- a/packages/kbn-coloring/src/shared_components/coloring/color_ranges/color_ranges.tsx +++ b/packages/kbn-coloring/src/shared_components/coloring/color_ranges/color_ranges.tsx @@ -26,6 +26,7 @@ export interface ColorRangesProps { colorRanges: ColorRange[]; paletteConfiguration: CustomPaletteParams | undefined; showExtraActions: boolean; + displayInfinity: boolean; dispatch: Dispatch; } @@ -33,6 +34,7 @@ export function ColorRanges({ colorRanges, paletteConfiguration, showExtraActions, + displayInfinity, dispatch, }: ColorRangesProps) { const [colorRangesValidity, setColorRangesValidity] = useState< @@ -65,6 +67,7 @@ export function ColorRanges({ index={index} validation={colorRangesValidity[index]} accessor="start" + displayInfinity={displayInfinity} /> ))} @@ -79,6 +82,7 @@ export function ColorRanges({ index={colorRanges.length - 1} validation={colorRangesValidity.last} accessor="end" + displayInfinity={displayInfinity} /> ) : null} diff --git a/packages/kbn-coloring/src/shared_components/coloring/color_ranges/color_ranges_item.tsx b/packages/kbn-coloring/src/shared_components/coloring/color_ranges/color_ranges_item.tsx index 99bb66b1166471..33caaece5cfcf9 100644 --- a/packages/kbn-coloring/src/shared_components/coloring/color_ranges/color_ranges_item.tsx +++ b/packages/kbn-coloring/src/shared_components/coloring/color_ranges/color_ranges_item.tsx @@ -52,6 +52,7 @@ export interface ColorRangesItemProps { continuity: PaletteContinuity; accessor: ColorRangeAccessor; validation?: ColorRangeValidation; + displayInfinity: boolean; } type ColorRangeItemMode = 'value' | 'auto' | 'edit'; @@ -67,10 +68,18 @@ const getMode = ( return (isLast ? checkIsMaxContinuity : checkIsMinContinuity)(continuity) ? 'auto' : 'edit'; }; -const getPlaceholderForAutoMode = (isLast: boolean) => +const getPlaceholderForAutoMode = (isLast: boolean, displayInfinity: boolean) => isLast - ? i18n.translate('coloring.dynamicColoring.customPalette.maxValuePlaceholder', { - defaultMessage: 'Max. value', + ? displayInfinity + ? i18n.translate('coloring.dynamicColoring.customPalette.extentPlaceholderInfinity', { + defaultMessage: 'Infinity', + }) + : i18n.translate('coloring.dynamicColoring.customPalette.maxValuePlaceholder', { + defaultMessage: 'Max. value', + }) + : displayInfinity + ? i18n.translate('coloring.dynamicColoring.customPalette.extentPlaceholderNegativeInfinity', { + defaultMessage: '-Infinity', }) : i18n.translate('coloring.dynamicColoring.customPalette.minValuePlaceholder', { defaultMessage: 'Min. value', @@ -102,6 +111,7 @@ export function ColorRangeItem({ validation, continuity, dispatch, + displayInfinity, }: ColorRangesItemProps) { const { dataBounds, palettes } = useContext(ColorRangesContext); const [popoverInFocus, setPopoverInFocus] = useState(false); @@ -220,7 +230,7 @@ export function ColorRangeItem({ } disabled={isDisabled} onChange={onValueChange} - placeholder={mode === 'auto' ? getPlaceholderForAutoMode(isLast) : ''} + placeholder={mode === 'auto' ? getPlaceholderForAutoMode(isLast, displayInfinity) : ''} append={getAppend(rangeType, mode)} onBlur={onLeaveFocus} data-test-subj={`lnsPalettePanel_dynamicColoring_range_value_${index}`} @@ -241,6 +251,7 @@ export function ColorRangeItem({ continuity={continuity} rangeType={rangeType} colorRanges={colorRanges} + displayInfinity={displayInfinity} dispatch={dispatch} accessor={accessor} /> diff --git a/packages/kbn-coloring/src/shared_components/coloring/color_ranges/color_ranges_item_buttons.tsx b/packages/kbn-coloring/src/shared_components/coloring/color_ranges/color_ranges_item_buttons.tsx index 41e1d56712b8ce..e8f0d8269d0bda 100644 --- a/packages/kbn-coloring/src/shared_components/coloring/color_ranges/color_ranges_item_buttons.tsx +++ b/packages/kbn-coloring/src/shared_components/coloring/color_ranges/color_ranges_item_buttons.tsx @@ -20,6 +20,7 @@ import { TooltipWrapper } from '../tooltip_wrapper'; import type { ColorRangesActions, ColorRange, ColorRangeAccessor } from './types'; import { ColorRangesContext } from './color_ranges_context'; +import { InfinityIcon } from '../assets/infinity'; export interface ColorRangesItemButtonProps { index: number; @@ -28,6 +29,7 @@ export interface ColorRangesItemButtonProps { continuity: PaletteContinuity; dispatch: Dispatch; accessor: ColorRangeAccessor; + displayInfinity: boolean; } const switchContinuity = (isLast: boolean, continuity: PaletteContinuity) => { @@ -117,6 +119,7 @@ export function ColorRangeAutoDetectButton({ continuity, dispatch, accessor, + displayInfinity, }: ColorRangesItemButtonProps) { const { dataBounds, palettes } = useContext(ColorRangesContext); const isLast = isLastItem(accessor); @@ -131,8 +134,16 @@ export function ColorRangeAutoDetectButton({ }, [continuity, dataBounds, dispatch, isLast, palettes]); const tooltipContent = isLast - ? i18n.translate('coloring.dynamicColoring.customPalette.useAutoMaxValue', { - defaultMessage: `Use maximum data value`, + ? displayInfinity + ? i18n.translate('coloring.dynamicColoring.customPalette.useAutoMaxValueInfinity', { + defaultMessage: `Use positive infinity`, + }) + : i18n.translate('coloring.dynamicColoring.customPalette.useAutoMaxValue', { + defaultMessage: `Use maximum data value`, + }) + : displayInfinity + ? i18n.translate('coloring.dynamicColoring.customPalette.useAutoMinValueInfinity', { + defaultMessage: `Use negative infinity`, }) : i18n.translate('coloring.dynamicColoring.customPalette.useAutoMinValue', { defaultMessage: `Use minimum data value`, @@ -141,7 +152,7 @@ export function ColorRangeAutoDetectButton({ return ( { const idPrefix = useMemo(() => htmlIdGenerator()(), []); const colorRangesToShow = toColorRanges( @@ -190,6 +192,9 @@ export const CustomizablePalette = ({ showExtraActions={showExtraActions} paletteConfiguration={localState.activePalette?.params} colorRanges={localState.colorRanges} + displayInfinity={ + displayInfinity && localState.activePalette.params?.rangeType !== 'percent' + } dispatch={dispatch} /> diff --git a/packages/kbn-config/BUILD.bazel b/packages/kbn-config/BUILD.bazel index 13cff50a1a2d70..4eeda0470542c9 100644 --- a/packages/kbn-config/BUILD.bazel +++ b/packages/kbn-config/BUILD.bazel @@ -30,7 +30,7 @@ NPM_MODULE_EXTRA_FILES = [ ] RUNTIME_DEPS = [ - "//packages/elastic-safer-lodash-set", + "//packages/kbn-safer-lodash-set", "//packages/kbn-config-schema", "//packages/kbn-logging", "//packages/kbn-logging-mocks", @@ -47,7 +47,7 @@ RUNTIME_DEPS = [ ] TYPES_DEPS = [ - "//packages/elastic-safer-lodash-set:npm_module_types", + "//packages/kbn-safer-lodash-set:npm_module_types", "//packages/kbn-config-schema:npm_module_types", "//packages/kbn-logging:npm_module_types", "//packages/kbn-logging-mocks:npm_module_types", diff --git a/packages/kbn-config/src/deprecation/apply_deprecations.ts b/packages/kbn-config/src/deprecation/apply_deprecations.ts index 9b0c4092044140..09e8efcdbd0111 100644 --- a/packages/kbn-config/src/deprecation/apply_deprecations.ts +++ b/packages/kbn-config/src/deprecation/apply_deprecations.ts @@ -7,7 +7,7 @@ */ import { cloneDeep } from 'lodash'; -import { set } from '@elastic/safer-lodash-set'; +import { set } from '@kbn/safer-lodash-set'; import type { AddConfigDeprecation, ChangedDeprecatedPaths, diff --git a/packages/kbn-config/src/object_to_config_adapter.ts b/packages/kbn-config/src/object_to_config_adapter.ts index 6b68f71ea73997..ce186d7b02c343 100644 --- a/packages/kbn-config/src/object_to_config_adapter.ts +++ b/packages/kbn-config/src/object_to_config_adapter.ts @@ -7,7 +7,7 @@ */ import { cloneDeep, get, has } from 'lodash'; -import { set } from '@elastic/safer-lodash-set'; +import { set } from '@kbn/safer-lodash-set'; import { getFlattenedObject } from '@kbn/std'; import { Config, ConfigPath } from '.'; diff --git a/packages/kbn-config/src/raw/read_config.ts b/packages/kbn-config/src/raw/read_config.ts index 307ce4e4a0f95a..1c842961838f2f 100644 --- a/packages/kbn-config/src/raw/read_config.ts +++ b/packages/kbn-config/src/raw/read_config.ts @@ -9,7 +9,7 @@ import { readFileSync } from 'fs'; import { safeLoad } from 'js-yaml'; -import { set } from '@elastic/safer-lodash-set'; +import { set } from '@kbn/safer-lodash-set'; import { isPlainObject } from 'lodash'; import { ensureDeepObject } from './ensure_deep_object'; diff --git a/packages/kbn-eslint-config/.eslintrc.js b/packages/kbn-eslint-config/.eslintrc.js index 97100635ac0ee0..f2b6e93649cddb 100644 --- a/packages/kbn-eslint-config/.eslintrc.js +++ b/packages/kbn-eslint-config/.eslintrc.js @@ -123,6 +123,14 @@ module.exports = { to: '@kbn/kibana-utils-plugin/common', exact: true, }, + { + from: '@elastic/safer-lodash-set', + to: '@kbn/safer-lodash-set', + }, + { + from: '@elastic/apm-synthtrace', + to: '@kbn/apm-synthtrace', + }, ], ], diff --git a/packages/kbn-generate/src/commands/package_command.ts b/packages/kbn-generate/src/commands/package_command.ts index 4f5d58184aeac7..32d5ff008c79f4 100644 --- a/packages/kbn-generate/src/commands/package_command.ts +++ b/packages/kbn-generate/src/commands/package_command.ts @@ -162,7 +162,7 @@ ${BAZEL_PACKAGE_DIRS.map((dir) => ` ./${dir}/*\n`).join Path.resolve(TEMPLATE_DIR, 'packages_BUILD.bazel.ejs'), Path.resolve(REPO_ROOT, 'packages/BUILD.bazel'), { - packages: await discoverBazelPackages(), + packages: await discoverBazelPackages(REPO_ROOT), } ); log.info('Updated packages/BUILD.bazel'); diff --git a/packages/kbn-generate/src/commands/packages_build_manifest_command.ts b/packages/kbn-generate/src/commands/packages_build_manifest_command.ts index 9103d56d42a1db..9b05c1aed332de 100644 --- a/packages/kbn-generate/src/commands/packages_build_manifest_command.ts +++ b/packages/kbn-generate/src/commands/packages_build_manifest_command.ts @@ -31,7 +31,7 @@ export const PackagesBuildManifestCommand: GenerateCommand = { async run({ log, render, flags }) { const validate = !!flags.validate; - const packages = await discoverBazelPackages(); + const packages = await discoverBazelPackages(REPO_ROOT); const dest = Path.resolve(REPO_ROOT, 'packages/BUILD.bazel'); const relDest = Path.relative(process.cwd(), dest); diff --git a/packages/kbn-optimizer/limits.yml b/packages/kbn-optimizer/limits.yml index 2a116d9ab60ed1..d41a5356af0825 100644 --- a/packages/kbn-optimizer/limits.yml +++ b/packages/kbn-optimizer/limits.yml @@ -70,7 +70,7 @@ pageLoadAssetSize: visTypeTimeseries: 55203 visTypeVega: 153573 visTypeVislib: 242838 - visTypeXy: 113478 + visTypeXy: 30000 visualizations: 90000 watcher: 43598 runtimeFields: 41752 @@ -119,13 +119,13 @@ pageLoadAssetSize: expressionGauge: 25000 controls: 40000 expressionPartitionVis: 26338 - sharedUX: 16225 savedSearch: 16225 ux: 20784 sessionView: 77750 cloudSecurityPosture: 19109 visTypeGauge: 24113 unifiedSearch: 71059 + unifiedFieldList: 65500 data: 454087 eventAnnotation: 19334 screenshotting: 22870 diff --git a/packages/elastic-safer-lodash-set/.gitignore b/packages/kbn-safer-lodash-set/.gitignore similarity index 100% rename from packages/elastic-safer-lodash-set/.gitignore rename to packages/kbn-safer-lodash-set/.gitignore diff --git a/packages/elastic-safer-lodash-set/.npmignore b/packages/kbn-safer-lodash-set/.npmignore similarity index 100% rename from packages/elastic-safer-lodash-set/.npmignore rename to packages/kbn-safer-lodash-set/.npmignore diff --git a/packages/elastic-safer-lodash-set/BUILD.bazel b/packages/kbn-safer-lodash-set/BUILD.bazel similarity index 92% rename from packages/elastic-safer-lodash-set/BUILD.bazel rename to packages/kbn-safer-lodash-set/BUILD.bazel index 4a1c8b4290f334..893719c8228592 100644 --- a/packages/elastic-safer-lodash-set/BUILD.bazel +++ b/packages/kbn-safer-lodash-set/BUILD.bazel @@ -1,7 +1,7 @@ load("@build_bazel_rules_nodejs//:index.bzl", "js_library", "pkg_npm") -PKG_BASE_NAME = "elastic-safer-lodash-set" -PKG_REQUIRE_NAME = "@elastic/safer-lodash-set" +PKG_BASE_NAME = "kbn-safer-lodash-set" +PKG_REQUIRE_NAME = "@kbn/safer-lodash-set" SOURCE_FILES = glob( [ diff --git a/packages/elastic-safer-lodash-set/LICENSE b/packages/kbn-safer-lodash-set/LICENSE similarity index 95% rename from packages/elastic-safer-lodash-set/LICENSE rename to packages/kbn-safer-lodash-set/LICENSE index bae69c938a74cc..8c34c9393aec7c 100644 --- a/packages/elastic-safer-lodash-set/LICENSE +++ b/packages/kbn-safer-lodash-set/LICENSE @@ -31,4 +31,4 @@ individuals. For exact contribution history, see the revision history available at the following locations: - https://github.com/lodash/lodash - https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/lodash - - https://github.com/elastic/kibana/tree/main/packages/elastic-safer-lodash-set + - https://github.com/elastic/kibana/tree/main/packages/kbn-safer-lodash-set diff --git a/packages/elastic-safer-lodash-set/README.md b/packages/kbn-safer-lodash-set/README.md similarity index 86% rename from packages/elastic-safer-lodash-set/README.md rename to packages/kbn-safer-lodash-set/README.md index aae17b35ac1306..08df12ff01ec37 100644 --- a/packages/elastic-safer-lodash-set/README.md +++ b/packages/kbn-safer-lodash-set/README.md @@ -1,4 +1,4 @@ -# @elastic/safer-lodash-set +# @kbn/safer-lodash-set This module adds protection against prototype pollution to the [`set`] and [`setWith`] functions from [Lodash] and are API compatible with @@ -23,15 +23,15 @@ console.log(object.x[0].y.z); // => 5 The main module exposes two functions, `set` and `setWith`: ```js -const { set, setWith } = require('@elastic/safer-lodash-set'); +const { set, setWith } = require('@kbn/safer-lodash-set'); ``` Besides the main module, it's also possible to require each function individually: ```js -const set = require('@elastic/safer-lodash-set/set'); -const setWith = require('@elastic/safer-lodash-set/setWith'); +const set = require('@kbn/safer-lodash-set/set'); +const setWith = require('@kbn/safer-lodash-set/setWith'); ``` The APIs of these functions are identical to the equivalent Lodash @@ -44,15 +44,15 @@ This module also supports the `lodash/fp` api and hence exposes the following fp compatible functions: ```js -const { set, setWith } = require('@elastic/safer-lodash-set/fp'); +const { set, setWith } = require('@kbn/safer-lodash-set/fp'); ``` Besides the main fp module, it's also possible to require each function individually: ```js -const set = require('@elastic/safer-lodash-set/fp/set'); -const setWith = require('@elastic/safer-lodash-set/fp/setWith'); +const set = require('@kbn/safer-lodash-set/fp/set'); +const setWith = require('@kbn/safer-lodash-set/fp/setWith'); ``` ## Limitations diff --git a/packages/elastic-safer-lodash-set/fp/assoc.d.ts b/packages/kbn-safer-lodash-set/fp/assoc.d.ts similarity index 80% rename from packages/elastic-safer-lodash-set/fp/assoc.d.ts rename to packages/kbn-safer-lodash-set/fp/assoc.d.ts index c04c85f63a8708..45e5800a3a33b6 100644 --- a/packages/elastic-safer-lodash-set/fp/assoc.d.ts +++ b/packages/kbn-safer-lodash-set/fp/assoc.d.ts @@ -2,7 +2,7 @@ * This file is forked from the DefinitelyTyped project (https://github.com/DefinitelyTyped/DefinitelyTyped), * and may include modifications made by Elasticsearch B.V. * Elasticsearch B.V. licenses this file to you under the MIT License. - * See `packages/elastic-safer-lodash-set/LICENSE` for more information. + * See `packages/kbn-safer-lodash-set/LICENSE` for more information. */ import { assoc } from '.'; diff --git a/packages/elastic-safer-lodash-set/fp/assoc.js b/packages/kbn-safer-lodash-set/fp/assoc.js similarity index 76% rename from packages/elastic-safer-lodash-set/fp/assoc.js rename to packages/kbn-safer-lodash-set/fp/assoc.js index 851e11690ea35d..d6ea0c9c74b777 100644 --- a/packages/elastic-safer-lodash-set/fp/assoc.js +++ b/packages/kbn-safer-lodash-set/fp/assoc.js @@ -2,7 +2,7 @@ * This file is forked from the lodash project (https://lodash.com/), * and may include modifications made by Elasticsearch B.V. * Elasticsearch B.V. licenses this file to you under the MIT License. - * See `packages/elastic-safer-lodash-set/LICENSE` for more information. + * See `packages/kbn-safer-lodash-set/LICENSE` for more information. */ module.exports = require('./set'); diff --git a/packages/elastic-safer-lodash-set/fp/assocPath.d.ts b/packages/kbn-safer-lodash-set/fp/assocPath.d.ts similarity index 80% rename from packages/elastic-safer-lodash-set/fp/assocPath.d.ts rename to packages/kbn-safer-lodash-set/fp/assocPath.d.ts index 534128331f1420..334c21ca7e707e 100644 --- a/packages/elastic-safer-lodash-set/fp/assocPath.d.ts +++ b/packages/kbn-safer-lodash-set/fp/assocPath.d.ts @@ -2,7 +2,7 @@ * This file is forked from the DefinitelyTyped project (https://github.com/DefinitelyTyped/DefinitelyTyped), * and may include modifications made by Elasticsearch B.V. * Elasticsearch B.V. licenses this file to you under the MIT License. - * See `packages/elastic-safer-lodash-set/LICENSE` for more information. + * See `packages/kbn-safer-lodash-set/LICENSE` for more information. */ import { assocPath } from '.'; diff --git a/packages/elastic-safer-lodash-set/fp/assocPath.js b/packages/kbn-safer-lodash-set/fp/assocPath.js similarity index 76% rename from packages/elastic-safer-lodash-set/fp/assocPath.js rename to packages/kbn-safer-lodash-set/fp/assocPath.js index 851e11690ea35d..d6ea0c9c74b777 100644 --- a/packages/elastic-safer-lodash-set/fp/assocPath.js +++ b/packages/kbn-safer-lodash-set/fp/assocPath.js @@ -2,7 +2,7 @@ * This file is forked from the lodash project (https://lodash.com/), * and may include modifications made by Elasticsearch B.V. * Elasticsearch B.V. licenses this file to you under the MIT License. - * See `packages/elastic-safer-lodash-set/LICENSE` for more information. + * See `packages/kbn-safer-lodash-set/LICENSE` for more information. */ module.exports = require('./set'); diff --git a/packages/elastic-safer-lodash-set/fp/index.d.ts b/packages/kbn-safer-lodash-set/fp/index.d.ts similarity index 99% rename from packages/elastic-safer-lodash-set/fp/index.d.ts rename to packages/kbn-safer-lodash-set/fp/index.d.ts index fcd7ff01e3cc88..777c7c0df980ad 100644 --- a/packages/elastic-safer-lodash-set/fp/index.d.ts +++ b/packages/kbn-safer-lodash-set/fp/index.d.ts @@ -2,7 +2,7 @@ * This file is forked from the DefinitelyTyped project (https://github.com/DefinitelyTyped/DefinitelyTyped), * and may include modifications made by Elasticsearch B.V. * Elasticsearch B.V. licenses this file to you under the MIT License. - * See `packages/elastic-safer-lodash-set/LICENSE` for more information. + * See `packages/kbn-safer-lodash-set/LICENSE` for more information. */ import lodash = require('lodash'); diff --git a/packages/elastic-safer-lodash-set/fp/index.js b/packages/kbn-safer-lodash-set/fp/index.js similarity index 81% rename from packages/elastic-safer-lodash-set/fp/index.js rename to packages/kbn-safer-lodash-set/fp/index.js index 7d9cdb099dfd76..aea3e4600d7c65 100644 --- a/packages/elastic-safer-lodash-set/fp/index.js +++ b/packages/kbn-safer-lodash-set/fp/index.js @@ -2,7 +2,7 @@ * This file is forked from the lodash project (https://lodash.com/), * and may include modifications made by Elasticsearch B.V. * Elasticsearch B.V. licenses this file to you under the MIT License. - * See `packages/elastic-safer-lodash-set/LICENSE` for more information. + * See `packages/kbn-safer-lodash-set/LICENSE` for more information. */ exports.set = exports.assoc = exports.assocPath = require('./set'); diff --git a/packages/elastic-safer-lodash-set/fp/set.d.ts b/packages/kbn-safer-lodash-set/fp/set.d.ts similarity index 79% rename from packages/elastic-safer-lodash-set/fp/set.d.ts rename to packages/kbn-safer-lodash-set/fp/set.d.ts index b676d271e05562..3e5730bb1ec42a 100644 --- a/packages/elastic-safer-lodash-set/fp/set.d.ts +++ b/packages/kbn-safer-lodash-set/fp/set.d.ts @@ -2,7 +2,7 @@ * This file is forked from the DefinitelyTyped project (https://github.com/DefinitelyTyped/DefinitelyTyped), * and may include modifications made by Elasticsearch B.V. * Elasticsearch B.V. licenses this file to you under the MIT License. - * See `packages/elastic-safer-lodash-set/LICENSE` for more information. + * See `packages/kbn-safer-lodash-set/LICENSE` for more information. */ import { set } from '.'; diff --git a/packages/elastic-safer-lodash-set/fp/set.js b/packages/kbn-safer-lodash-set/fp/set.js similarity index 84% rename from packages/elastic-safer-lodash-set/fp/set.js rename to packages/kbn-safer-lodash-set/fp/set.js index 0fb48694d736df..3a54fcacec959d 100644 --- a/packages/elastic-safer-lodash-set/fp/set.js +++ b/packages/kbn-safer-lodash-set/fp/set.js @@ -2,7 +2,7 @@ * This file is forked from the lodash project (https://lodash.com/), * and may include modifications made by Elasticsearch B.V. * Elasticsearch B.V. licenses this file to you under the MIT License. - * See `packages/elastic-safer-lodash-set/LICENSE` for more information. + * See `packages/kbn-safer-lodash-set/LICENSE` for more information. */ /*eslint no-var:0 */ diff --git a/packages/elastic-safer-lodash-set/fp/setWith.d.ts b/packages/kbn-safer-lodash-set/fp/setWith.d.ts similarity index 80% rename from packages/elastic-safer-lodash-set/fp/setWith.d.ts rename to packages/kbn-safer-lodash-set/fp/setWith.d.ts index 812437adc165a6..20eadd898fa522 100644 --- a/packages/elastic-safer-lodash-set/fp/setWith.d.ts +++ b/packages/kbn-safer-lodash-set/fp/setWith.d.ts @@ -2,7 +2,7 @@ * This file is forked from the DefinitelyTyped project (https://github.com/DefinitelyTyped/DefinitelyTyped), * and may include modifications made by Elasticsearch B.V. * Elasticsearch B.V. licenses this file to you under the MIT License. - * See `packages/elastic-safer-lodash-set/LICENSE` for more information. + * See `packages/kbn-safer-lodash-set/LICENSE` for more information. */ import { setWith } from '.'; diff --git a/packages/elastic-safer-lodash-set/fp/setWith.js b/packages/kbn-safer-lodash-set/fp/setWith.js similarity index 84% rename from packages/elastic-safer-lodash-set/fp/setWith.js rename to packages/kbn-safer-lodash-set/fp/setWith.js index e477d4b4bc7bab..9842e1ecf93b27 100644 --- a/packages/elastic-safer-lodash-set/fp/setWith.js +++ b/packages/kbn-safer-lodash-set/fp/setWith.js @@ -2,7 +2,7 @@ * This file is forked from the lodash project (https://lodash.com/), * and may include modifications made by Elasticsearch B.V. * Elasticsearch B.V. licenses this file to you under the MIT License. - * See `packages/elastic-safer-lodash-set/LICENSE` for more information. + * See `packages/kbn-safer-lodash-set/LICENSE` for more information. */ /*eslint no-var:0 */ diff --git a/packages/elastic-safer-lodash-set/index.d.ts b/packages/kbn-safer-lodash-set/index.d.ts similarity index 96% rename from packages/elastic-safer-lodash-set/index.d.ts rename to packages/kbn-safer-lodash-set/index.d.ts index aaff01f11a7af9..198df549e07043 100644 --- a/packages/elastic-safer-lodash-set/index.d.ts +++ b/packages/kbn-safer-lodash-set/index.d.ts @@ -2,7 +2,7 @@ * This file is forked from the DefinitelyTyped project (https://github.com/DefinitelyTyped/DefinitelyTyped), * and may include modifications made by Elasticsearch B.V. * Elasticsearch B.V. licenses this file to you under the MIT License. - * See `packages/elastic-safer-lodash-set/LICENSE` for more information. + * See `packages/kbn-safer-lodash-set/LICENSE` for more information. */ export = SaferLodashSet; diff --git a/packages/elastic-safer-lodash-set/index.js b/packages/kbn-safer-lodash-set/index.js similarity index 80% rename from packages/elastic-safer-lodash-set/index.js rename to packages/kbn-safer-lodash-set/index.js index d9edb25476c126..9ed12a77aa163f 100644 --- a/packages/elastic-safer-lodash-set/index.js +++ b/packages/kbn-safer-lodash-set/index.js @@ -2,7 +2,7 @@ * This file is forked from the lodash project (https://lodash.com/), * and may include modifications made by Elasticsearch B.V. * Elasticsearch B.V. licenses this file to you under the MIT License. - * See `packages/elastic-safer-lodash-set/LICENSE` for more information. + * See `packages/kbn-safer-lodash-set/LICENSE` for more information. */ exports.set = require('./lodash/set'); diff --git a/packages/elastic-safer-lodash-set/lodash/_baseSet.js b/packages/kbn-safer-lodash-set/lodash/_baseSet.js similarity index 96% rename from packages/elastic-safer-lodash-set/lodash/_baseSet.js rename to packages/kbn-safer-lodash-set/lodash/_baseSet.js index f2ac3351b5afa1..be037ecc344b9d 100644 --- a/packages/elastic-safer-lodash-set/lodash/_baseSet.js +++ b/packages/kbn-safer-lodash-set/lodash/_baseSet.js @@ -2,7 +2,7 @@ * This file is forked from the lodash project (https://lodash.com/), * and may include modifications made by Elasticsearch B.V. * Elasticsearch B.V. licenses this file to you under the MIT License. - * See `packages/elastic-safer-lodash-set/LICENSE` for more information. + * See `packages/kbn-safer-lodash-set/LICENSE` for more information. */ /* eslint-disable one-var,prettier/prettier,no-var,eqeqeq,no-nested-ternary */ diff --git a/packages/elastic-safer-lodash-set/lodash/set.js b/packages/kbn-safer-lodash-set/lodash/set.js similarity index 94% rename from packages/elastic-safer-lodash-set/lodash/set.js rename to packages/kbn-safer-lodash-set/lodash/set.js index e911e853d64fbf..aacd1edf0f50f9 100644 --- a/packages/elastic-safer-lodash-set/lodash/set.js +++ b/packages/kbn-safer-lodash-set/lodash/set.js @@ -2,7 +2,7 @@ * This file is forked from the lodash project (https://lodash.com/), * and may include modifications made by Elasticsearch B.V. * Elasticsearch B.V. licenses this file to you under the MIT License. - * See `packages/elastic-safer-lodash-set/LICENSE` for more information. + * See `packages/kbn-safer-lodash-set/LICENSE` for more information. */ /* eslint-disable no-var */ diff --git a/packages/elastic-safer-lodash-set/lodash/setWith.js b/packages/kbn-safer-lodash-set/lodash/setWith.js similarity index 94% rename from packages/elastic-safer-lodash-set/lodash/setWith.js rename to packages/kbn-safer-lodash-set/lodash/setWith.js index 0295c9ae137d64..2bfd9dd354fdee 100644 --- a/packages/elastic-safer-lodash-set/lodash/setWith.js +++ b/packages/kbn-safer-lodash-set/lodash/setWith.js @@ -2,7 +2,7 @@ * This file is forked from the lodash project (https://lodash.com/), * and may include modifications made by Elasticsearch B.V. * Elasticsearch B.V. licenses this file to you under the MIT License. - * See `packages/elastic-safer-lodash-set/LICENSE` for more information. + * See `packages/kbn-safer-lodash-set/LICENSE` for more information. */ /* eslint-disable no-var,eqeqeq */ diff --git a/packages/elastic-safer-lodash-set/package.json b/packages/kbn-safer-lodash-set/package.json similarity index 83% rename from packages/elastic-safer-lodash-set/package.json rename to packages/kbn-safer-lodash-set/package.json index 72b908911000d5..f850b5fe0fc480 100644 --- a/packages/elastic-safer-lodash-set/package.json +++ b/packages/kbn-safer-lodash-set/package.json @@ -1,11 +1,11 @@ { - "name": "@elastic/safer-lodash-set", + "name": "@kbn/safer-lodash-set", "version": "0.0.0", "description": "A safer version of the lodash set and setWith functions", "main": "index.js", "types": "index.d.ts", "scripts": { - "lint": "../../node_modules/.bin/dependency-check --missing ../../package.json ./packages/elastic-safer-lodash-set/set.js ./packages/elastic-safer-lodash-set/setWith.js ./packages/elastic-safer-lodash-set/fp/*.js", + "lint": "../../node_modules/.bin/dependency-check --missing ../../package.json ./packages/kbn-safer-lodash-set/set.js ./packages/kbn-safer-lodash-set/setWith.js ./packages/kbn-safer-lodash-set/fp/*.js", "test": "npm run lint && ../../node_modules/.bin/tape test/*.js && npm run test:types", "test:types": "../../node_modules/.bin/tsc --noEmit", "update": "./scripts/update.sh", diff --git a/packages/elastic-safer-lodash-set/scripts/_get_lodash.sh b/packages/kbn-safer-lodash-set/scripts/_get_lodash.sh similarity index 82% rename from packages/elastic-safer-lodash-set/scripts/_get_lodash.sh rename to packages/kbn-safer-lodash-set/scripts/_get_lodash.sh index 50d3edaf347170..7fd3a056cf1f95 100755 --- a/packages/elastic-safer-lodash-set/scripts/_get_lodash.sh +++ b/packages/kbn-safer-lodash-set/scripts/_get_lodash.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash # Elasticsearch B.V licenses this file to you under the MIT License. -# See `packages/elastic-safer-lodash-set/LICENSE` for more information. +# See `packages/kbn-safer-lodash-set/LICENSE` for more information. clean_up () { exit_code=$? diff --git a/packages/elastic-safer-lodash-set/scripts/license-header.txt b/packages/kbn-safer-lodash-set/scripts/license-header.txt similarity index 74% rename from packages/elastic-safer-lodash-set/scripts/license-header.txt rename to packages/kbn-safer-lodash-set/scripts/license-header.txt index 4d0aedf74bb0ff..e546841be3a2bd 100644 --- a/packages/elastic-safer-lodash-set/scripts/license-header.txt +++ b/packages/kbn-safer-lodash-set/scripts/license-header.txt @@ -2,6 +2,6 @@ * This file is forked from the lodash project (https://lodash.com/), * and may include modifications made by Elasticsearch B.V. * Elasticsearch B.V. licenses this file to you under the MIT License. - * See `packages/elastic-safer-lodash-set/LICENSE` for more information. + * See `packages/kbn-safer-lodash-set/LICENSE` for more information. */ diff --git a/packages/elastic-safer-lodash-set/scripts/patches/_baseSet.js.patch b/packages/kbn-safer-lodash-set/scripts/patches/_baseSet.js.patch similarity index 93% rename from packages/elastic-safer-lodash-set/scripts/patches/_baseSet.js.patch rename to packages/kbn-safer-lodash-set/scripts/patches/_baseSet.js.patch index c7cf2041355d07..9a1ed2892d0d79 100644 --- a/packages/elastic-safer-lodash-set/scripts/patches/_baseSet.js.patch +++ b/packages/kbn-safer-lodash-set/scripts/patches/_baseSet.js.patch @@ -9,7 +9,7 @@ > * This file is forked from the lodash project (https://lodash.com/), > * and may include modifications made by Elasticsearch B.V. > * Elasticsearch B.V. licenses this file to you under the MIT License. -> * See `packages/elastic-safer-lodash-set/LICENSE` for more information. +> * See `packages/kbn-safer-lodash-set/LICENSE` for more information. > */ > > /* eslint-disable */ diff --git a/packages/elastic-safer-lodash-set/scripts/save_state.sh b/packages/kbn-safer-lodash-set/scripts/save_state.sh similarity index 84% rename from packages/elastic-safer-lodash-set/scripts/save_state.sh rename to packages/kbn-safer-lodash-set/scripts/save_state.sh index ead99c3d1de48f..72bca0288f5064 100755 --- a/packages/elastic-safer-lodash-set/scripts/save_state.sh +++ b/packages/kbn-safer-lodash-set/scripts/save_state.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash # Elasticsearch B.V licenses this file to you under the MIT License. -# See `packages/elastic-safer-lodash-set/LICENSE` for more information. +# See `packages/kbn-safer-lodash-set/LICENSE` for more information. set -e diff --git a/packages/elastic-safer-lodash-set/scripts/update.sh b/packages/kbn-safer-lodash-set/scripts/update.sh similarity index 94% rename from packages/elastic-safer-lodash-set/scripts/update.sh rename to packages/kbn-safer-lodash-set/scripts/update.sh index 58fd89eb43e33c..e16b03edbe13b9 100755 --- a/packages/elastic-safer-lodash-set/scripts/update.sh +++ b/packages/kbn-safer-lodash-set/scripts/update.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash # Elasticsearch B.V licenses this file to you under the MIT License. -# See `packages/elastic-safer-lodash-set/LICENSE` for more information. +# See `packages/kbn-safer-lodash-set/LICENSE` for more information. set -e diff --git a/packages/elastic-safer-lodash-set/set.d.ts b/packages/kbn-safer-lodash-set/set.d.ts similarity index 79% rename from packages/elastic-safer-lodash-set/set.d.ts rename to packages/kbn-safer-lodash-set/set.d.ts index b676d271e05562..3e5730bb1ec42a 100644 --- a/packages/elastic-safer-lodash-set/set.d.ts +++ b/packages/kbn-safer-lodash-set/set.d.ts @@ -2,7 +2,7 @@ * This file is forked from the DefinitelyTyped project (https://github.com/DefinitelyTyped/DefinitelyTyped), * and may include modifications made by Elasticsearch B.V. * Elasticsearch B.V. licenses this file to you under the MIT License. - * See `packages/elastic-safer-lodash-set/LICENSE` for more information. + * See `packages/kbn-safer-lodash-set/LICENSE` for more information. */ import { set } from '.'; diff --git a/packages/elastic-safer-lodash-set/set.js b/packages/kbn-safer-lodash-set/set.js similarity index 77% rename from packages/elastic-safer-lodash-set/set.js rename to packages/kbn-safer-lodash-set/set.js index 69770629085496..a02607a433efbc 100644 --- a/packages/elastic-safer-lodash-set/set.js +++ b/packages/kbn-safer-lodash-set/set.js @@ -2,7 +2,7 @@ * This file is forked from the lodash project (https://lodash.com/), * and may include modifications made by Elasticsearch B.V. * Elasticsearch B.V. licenses this file to you under the MIT License. - * See `packages/elastic-safer-lodash-set/LICENSE` for more information. + * See `packages/kbn-safer-lodash-set/LICENSE` for more information. */ module.exports = require('./lodash/set'); diff --git a/packages/elastic-safer-lodash-set/setWith.d.ts b/packages/kbn-safer-lodash-set/setWith.d.ts similarity index 80% rename from packages/elastic-safer-lodash-set/setWith.d.ts rename to packages/kbn-safer-lodash-set/setWith.d.ts index 812437adc165a6..20eadd898fa522 100644 --- a/packages/elastic-safer-lodash-set/setWith.d.ts +++ b/packages/kbn-safer-lodash-set/setWith.d.ts @@ -2,7 +2,7 @@ * This file is forked from the DefinitelyTyped project (https://github.com/DefinitelyTyped/DefinitelyTyped), * and may include modifications made by Elasticsearch B.V. * Elasticsearch B.V. licenses this file to you under the MIT License. - * See `packages/elastic-safer-lodash-set/LICENSE` for more information. + * See `packages/kbn-safer-lodash-set/LICENSE` for more information. */ import { setWith } from '.'; diff --git a/packages/elastic-safer-lodash-set/setWith.js b/packages/kbn-safer-lodash-set/setWith.js similarity index 77% rename from packages/elastic-safer-lodash-set/setWith.js rename to packages/kbn-safer-lodash-set/setWith.js index aafa8a4db4be64..c957b03e349e05 100644 --- a/packages/elastic-safer-lodash-set/setWith.js +++ b/packages/kbn-safer-lodash-set/setWith.js @@ -2,7 +2,7 @@ * This file is forked from the lodash project (https://lodash.com/), * and may include modifications made by Elasticsearch B.V. * Elasticsearch B.V. licenses this file to you under the MIT License. - * See `packages/elastic-safer-lodash-set/LICENSE` for more information. + * See `packages/kbn-safer-lodash-set/LICENSE` for more information. */ module.exports = require('./lodash/setWith'); diff --git a/packages/elastic-safer-lodash-set/test/fp.ts b/packages/kbn-safer-lodash-set/test/fp.ts similarity index 98% rename from packages/elastic-safer-lodash-set/test/fp.ts rename to packages/kbn-safer-lodash-set/test/fp.ts index 7a1d6601b5e263..79fda77cbd1488 100644 --- a/packages/elastic-safer-lodash-set/test/fp.ts +++ b/packages/kbn-safer-lodash-set/test/fp.ts @@ -1,6 +1,6 @@ /* * Elasticsearch B.V licenses this file to you under the MIT License. - * See `packages/elastic-safer-lodash-set/LICENSE` for more information. + * See `packages/kbn-safer-lodash-set/LICENSE` for more information. */ import { expectType } from 'tsd'; diff --git a/packages/elastic-safer-lodash-set/test/fp_assoc.ts b/packages/kbn-safer-lodash-set/test/fp_assoc.ts similarity index 92% rename from packages/elastic-safer-lodash-set/test/fp_assoc.ts rename to packages/kbn-safer-lodash-set/test/fp_assoc.ts index 8244458cd11803..edc57bc29e8e6e 100644 --- a/packages/elastic-safer-lodash-set/test/fp_assoc.ts +++ b/packages/kbn-safer-lodash-set/test/fp_assoc.ts @@ -1,6 +1,6 @@ /* * Elasticsearch B.V licenses this file to you under the MIT License. - * See `packages/elastic-safer-lodash-set/LICENSE` for more information. + * See `packages/kbn-safer-lodash-set/LICENSE` for more information. */ import { expectType } from 'tsd'; diff --git a/packages/elastic-safer-lodash-set/test/fp_assocPath.ts b/packages/kbn-safer-lodash-set/test/fp_assocPath.ts similarity index 93% rename from packages/elastic-safer-lodash-set/test/fp_assocPath.ts rename to packages/kbn-safer-lodash-set/test/fp_assocPath.ts index abbfa57eeb9635..1dfb667fd66115 100644 --- a/packages/elastic-safer-lodash-set/test/fp_assocPath.ts +++ b/packages/kbn-safer-lodash-set/test/fp_assocPath.ts @@ -1,6 +1,6 @@ /* * Elasticsearch B.V licenses this file to you under the MIT License. - * See `packages/elastic-safer-lodash-set/LICENSE` for more information. + * See `packages/kbn-safer-lodash-set/LICENSE` for more information. */ import { expectType } from 'tsd'; diff --git a/packages/elastic-safer-lodash-set/test/fp_patch_test.js b/packages/kbn-safer-lodash-set/test/fp_patch_test.js similarity index 99% rename from packages/elastic-safer-lodash-set/test/fp_patch_test.js rename to packages/kbn-safer-lodash-set/test/fp_patch_test.js index 362ecf6f9d8660..a7a900bd7601f8 100644 --- a/packages/elastic-safer-lodash-set/test/fp_patch_test.js +++ b/packages/kbn-safer-lodash-set/test/fp_patch_test.js @@ -1,6 +1,6 @@ /* * Elasticsearch B.V licenses this file to you under the MIT License. - * See `packages/elastic-safer-lodash-set/LICENSE` for more information. + * See `packages/kbn-safer-lodash-set/LICENSE` for more information. */ const test = require('tape'); diff --git a/packages/elastic-safer-lodash-set/test/fp_set.ts b/packages/kbn-safer-lodash-set/test/fp_set.ts similarity index 92% rename from packages/elastic-safer-lodash-set/test/fp_set.ts rename to packages/kbn-safer-lodash-set/test/fp_set.ts index a5dbb24d33a052..b530314b561d93 100644 --- a/packages/elastic-safer-lodash-set/test/fp_set.ts +++ b/packages/kbn-safer-lodash-set/test/fp_set.ts @@ -1,6 +1,6 @@ /* * Elasticsearch B.V licenses this file to you under the MIT License. - * See `packages/elastic-safer-lodash-set/LICENSE` for more information. + * See `packages/kbn-safer-lodash-set/LICENSE` for more information. */ import { expectType } from 'tsd'; diff --git a/packages/elastic-safer-lodash-set/test/fp_setWith.ts b/packages/kbn-safer-lodash-set/test/fp_setWith.ts similarity index 96% rename from packages/elastic-safer-lodash-set/test/fp_setWith.ts rename to packages/kbn-safer-lodash-set/test/fp_setWith.ts index 70a5197f72176d..c86c9267e07ec2 100644 --- a/packages/elastic-safer-lodash-set/test/fp_setWith.ts +++ b/packages/kbn-safer-lodash-set/test/fp_setWith.ts @@ -1,6 +1,6 @@ /* * Elasticsearch B.V licenses this file to you under the MIT License. - * See `packages/elastic-safer-lodash-set/LICENSE` for more information. + * See `packages/kbn-safer-lodash-set/LICENSE` for more information. */ import { expectType } from 'tsd'; diff --git a/packages/elastic-safer-lodash-set/test/index.ts b/packages/kbn-safer-lodash-set/test/index.ts similarity index 92% rename from packages/elastic-safer-lodash-set/test/index.ts rename to packages/kbn-safer-lodash-set/test/index.ts index 2090c1adcfce14..cbaefb250598c2 100644 --- a/packages/elastic-safer-lodash-set/test/index.ts +++ b/packages/kbn-safer-lodash-set/test/index.ts @@ -1,6 +1,6 @@ /* * Elasticsearch B.V licenses this file to you under the MIT License. - * See `packages/elastic-safer-lodash-set/LICENSE` for more information. + * See `packages/kbn-safer-lodash-set/LICENSE` for more information. */ import { expectType } from 'tsd'; diff --git a/packages/elastic-safer-lodash-set/test/patch_test.js b/packages/kbn-safer-lodash-set/test/patch_test.js similarity index 98% rename from packages/elastic-safer-lodash-set/test/patch_test.js rename to packages/kbn-safer-lodash-set/test/patch_test.js index 80a44eb0c5b6b4..f83cbe1e40b85f 100644 --- a/packages/elastic-safer-lodash-set/test/patch_test.js +++ b/packages/kbn-safer-lodash-set/test/patch_test.js @@ -1,6 +1,6 @@ /* * Elasticsearch B.V licenses this file to you under the MIT License. - * See `packages/elastic-safer-lodash-set/LICENSE` for more information. + * See `packages/kbn-safer-lodash-set/LICENSE` for more information. */ const test = require('tape'); diff --git a/packages/elastic-safer-lodash-set/test/set.ts b/packages/kbn-safer-lodash-set/test/set.ts similarity index 84% rename from packages/elastic-safer-lodash-set/test/set.ts rename to packages/kbn-safer-lodash-set/test/set.ts index 9829ac3f04ce53..b07bc407d6a8c7 100644 --- a/packages/elastic-safer-lodash-set/test/set.ts +++ b/packages/kbn-safer-lodash-set/test/set.ts @@ -1,6 +1,6 @@ /* * Elasticsearch B.V licenses this file to you under the MIT License. - * See `packages/elastic-safer-lodash-set/LICENSE` for more information. + * See `packages/kbn-safer-lodash-set/LICENSE` for more information. */ import { expectType } from 'tsd'; diff --git a/packages/elastic-safer-lodash-set/test/setWith.ts b/packages/kbn-safer-lodash-set/test/setWith.ts similarity index 91% rename from packages/elastic-safer-lodash-set/test/setWith.ts rename to packages/kbn-safer-lodash-set/test/setWith.ts index b3ed93443c4fbb..c61aa2d8ec2b15 100644 --- a/packages/elastic-safer-lodash-set/test/setWith.ts +++ b/packages/kbn-safer-lodash-set/test/setWith.ts @@ -1,6 +1,6 @@ /* * Elasticsearch B.V licenses this file to you under the MIT License. - * See `packages/elastic-safer-lodash-set/LICENSE` for more information. + * See `packages/kbn-safer-lodash-set/LICENSE` for more information. */ import { expectType } from 'tsd'; diff --git a/packages/elastic-safer-lodash-set/tsconfig.json b/packages/kbn-safer-lodash-set/tsconfig.json similarity index 100% rename from packages/elastic-safer-lodash-set/tsconfig.json rename to packages/kbn-safer-lodash-set/tsconfig.json diff --git a/packages/kbn-shared-ux-components/README.mdx b/packages/kbn-shared-ux-components/README.mdx deleted file mode 100644 index f4673a0804f317..00000000000000 --- a/packages/kbn-shared-ux-components/README.mdx +++ /dev/null @@ -1,10 +0,0 @@ ---- -id: kibSharedUXComponents -slug: /kibana-dev-docs/shared-ux/packages/kbn-shared-ux-components -title: Shared UX Components -description: -date: 2022-03-11 -tags: ['kibana', 'dev', 'sharedUX'] ---- - -> TODO diff --git a/packages/kbn-shared-ux-components/src/index.ts b/packages/kbn-shared-ux-components/src/index.ts deleted file mode 100644 index 9e11d9341fe59f..00000000000000 --- a/packages/kbn-shared-ux-components/src/index.ts +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -// TODO: clintandrewhall - NoDataPageProps is a temporary addition until it is split into its own package -export type { KibanaPageTemplateProps, NoDataPageProps } from './page_template'; - -// TODO: clintandrewhall - NoDataConfigPage is a temporary addition until it is split into its own package -export { KibanaPageTemplate, NoDataConfigPage } from './page_template'; diff --git a/packages/kbn-shared-ux-components/src/page_template/assets/kibana_template_no_data_config.png b/packages/kbn-shared-ux-components/src/page_template/assets/kibana_template_no_data_config.png deleted file mode 100644 index e69de29bb2d1d6..00000000000000 diff --git a/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_config_page/__snapshots__/no_data_config_page.test.tsx.snap b/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_config_page/__snapshots__/no_data_config_page.test.tsx.snap deleted file mode 100644 index 047f44e0d319cb..00000000000000 --- a/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_config_page/__snapshots__/no_data_config_page.test.tsx.snap +++ /dev/null @@ -1,31 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`NoDataConfigPage renders 1`] = ` - - - -`; diff --git a/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_page.tsx b/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_page.tsx deleted file mode 100644 index 724570d4baccd6..00000000000000 --- a/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_page.tsx +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import React, { useMemo, FunctionComponent } from 'react'; -import useObservable from 'react-use/lib/useObservable'; -import classNames from 'classnames'; - -import { EuiLink, EuiSpacer, EuiText, EuiTextColor } from '@elastic/eui'; -import { i18n } from '@kbn/i18n'; -import { FormattedMessage } from '@kbn/i18n-react'; -import { KibanaSolutionAvatar } from '@kbn/shared-ux-avatar-solution'; - -import { useSharedUxServices } from '@kbn/shared-ux-services'; -import { NoDataCard, NoDataCardProvider } from '@kbn/shared-ux-card-no-data'; -import { NoDataPageProps } from './types'; - -export const NoDataPage: FunctionComponent = ({ - solution, - logo, - action, - docsLink, - pageTitle, - ...rest -}) => { - const services = useSharedUxServices(); - - // TODO: clintandrewhall - including the `NoDataCardProvider` here is a temporary solution - // to consumers using this context to populate the NoDataPage. This will likely be removed soon, - // when NoDataPage is moved to its own package. - const currentAppId = useObservable(services.application.currentAppId$); - const noDataCardServices = { - currentAppId, - addBasePath: services.http.addBasePath, - canAccessFleet: services.permissions.canAccessFleet, - navigateToUrl: services.application.navigateToUrl, - }; - - const actionKeys = Object.keys(action); - - const actionCard = useMemo(() => { - if (actionKeys.length !== 1) { - return null; - } - const actionKey = actionKeys[0]; - const key = - actionKey === 'elasticAgent' ? 'empty-page-agent-action' : `empty-page-${actionKey}-action`; - return ; - }, [action, actionKeys]); - - const title = - pageTitle || - i18n.translate('sharedUXComponents.noDataPage.welcomeTitle', { - defaultMessage: 'Welcome to Elastic {solution}!', - values: { solution }, - }); - - return ( -
- - - -

{title}

- -

- - - - ), - }} - /> -

-
-
- - {actionCard} -
- ); -}; diff --git a/packages/kbn-shared-ux-components/src/page_template/page_template.stories.tsx b/packages/kbn-shared-ux-components/src/page_template/page_template.stories.tsx deleted file mode 100644 index ae6be1297f018c..00000000000000 --- a/packages/kbn-shared-ux-components/src/page_template/page_template.stories.tsx +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import React from 'react'; -import { EuiButton, EuiText } from '@elastic/eui'; -import { SolutionNavProps } from '@kbn/shared-ux-page-solution-nav'; - -import { KibanaPageTemplate } from './page_template'; -import mdx from './page_template.mdx'; -import { KibanaPageTemplateProps } from './types'; - -export default { - title: 'Page Template/Page Template', - description: - 'A thin wrapper around `EuiTemplate`. Takes care of styling, empty state and no data config', - parameters: { - docs: { - page: mdx, - }, - }, -}; - -type Params = Pick & { - canBeCollapsed: boolean; -}; - -const noDataConfig = { - solution: 'Kibana', - action: { - elasticAgent: {}, - }, - docsLink: 'http://wwww.docs.elastic.co', -}; - -const items: SolutionNavProps['items'] = [ - { - name: 'Ingest', - id: '1', - items: [ - { - name: 'Ingest Node Pipelines', - id: '1.1', - }, - { - name: 'Logstash Pipelines', - id: '1.2', - }, - { - name: 'Beats Central Management', - id: '1.3', - }, - ], - }, - { - name: 'Data', - id: '2', - items: [ - { - name: 'Index Management', - id: '2.1', - }, - { - name: 'Index Lifecycle Policies', - id: '2.2', - }, - { - name: 'Snapshot and Restore', - id: '2.3', - }, - ], - }, -]; - -const solutionNavBar = { - items, - logo: 'logoKibana', - name: 'Kibana', - action: { elasticAgent: {} }, -}; - -const content = ( - -

- Page Content goes here -

-
-); - -const header = { - iconType: 'logoKibana', - pageTitle: 'Kibana', - description: 'Welcome to Kibana!', - rightSideItems: [Add something, Do something], -}; - -export const WithNoDataConfig = () => { - return ; -}; - -export const WithNoDataConfigAndSolutionNav = () => { - return ; -}; - -export const PureComponent = (params: Params) => { - return ( - - {content} - - ); -}; - -PureComponent.argTypes = { - isEmptyState: { - control: 'boolean', - defaultValue: false, - }, - pageHeader: { - control: 'boolean', - defaultValue: true, - }, - solutionNav: { - control: 'boolean', - defaultValue: true, - }, - canBeCollapsed: { - control: 'boolean', - defaultValue: true, - }, -}; - -PureComponent.parameters = { - layout: 'fullscreen', -}; - -WithNoDataConfig.parameters = { - layout: 'fullscreen', -}; - -WithNoDataConfigAndSolutionNav.parameters = { - layout: 'fullscreen', -}; diff --git a/packages/kbn-shared-ux-services/README.mdx b/packages/kbn-shared-ux-services/README.mdx deleted file mode 100755 index 589aae4cc7ed2b..00000000000000 --- a/packages/kbn-shared-ux-services/README.mdx +++ /dev/null @@ -1,203 +0,0 @@ ---- -id: kibSharedUXServices -slug: /kibana-dev-docs/shared-ux/packages/kbn-shared-ux-services -title: Shared UX Services -description: The `@kbn/shared-ux-services` package provides a thin service abstraction for components and solutions created by the Shared UX team. -date: 2022-03-11 -tags: ['kibana', 'dev', 'sharedUX'] ---- - -## About Shared UX Services - -This package contains a set of services that are used by Shared UX components and solutions. This package serves as a thin abstraction layer between Kibana dependencies and the components in Shared UX that use them. It also allows us to "swap out" different implementations of the interfaces for different environments, (e.g. Storybook, Jest, etc). This decouples the components from what could be complicated or heavily-dependent logic that is difficult to mock. - -## Implementations - -Several implementations of these interfaces exist: - -- `@kbn/shared-ux-services/src/services/stub`: A stub implementation free of dependencies, (and functionality). -- `@kbn/shared-ux-services/src/services/mock`: A Jest mock implementation used in `jest` tests. -- `@kbn/shared-ux-storybook/src/services/`: A Storybook implementation used in Storybook decorators and stories. -- `src/plugins/shared_ux/src/services/`: A Kibana implementation used in Kibana plugins. - -Other implementations could easily be written to support other environments. - -## Architecture - -Lots of components require access to the services provided by other plugins. When we identify a routine that relies on these dependencies, we can write a new method and add it to a namespace, (e.g. `platform`, `user`, etc). These namespaces become interfaces of simple methods stored in `@kbn/shared-ux-services`. From there, we can create implementations for each environment we support. - -Suppose we're creating a new service, `SharedUxFooService`: - -```ts -interface SharedUxFooService { - getFoo(): string; - setBar(bar: string): void; - isBaz(): boolean; -} -``` - -Once defined, we create factories to create those services. - -### Creating a `ServiceFactory` - -A `ServiceFactory` is a simple type that describes 1/ what service is being created, and 2/ what parameters are required to create that service for a given environment. - -### Stub and Mock Factories - -Given the service definition above, we can create a `ServiceFactory` for a stubbed service that gives the bare minimum of functionality: - -```ts -/** - * A factory function for creating a stubbed implementation of `SharedUxFooService`. - */ -export type FooServiceFactory = ServiceFactory; - -/** - * A factory function for creating a stubbed implementation of `SharedUxFooService`. - */ -export const fooServiceFactory: FooServiceFactory = () => ({ - getFoo: () => 'foo', - setBar: () => {}, - isBaz: () => false, -}); -``` - -We can also create a mock for Jest: - -```ts -/** - * A factory function for creating a mock implementation of `SharedUxFooService`. - */ -export type FooServiceFactory = ServiceFactory; - -/** - * A factory function for creating a stubbed implementation of `SharedUxFooService`. - */ -export const fooServiceFactory: FooServiceFactory = () => ({ - getFoo: () => jest.fn(), - setBar: () => jest.fn(), - isBaz: () => jest.fn(), -}); -``` - -### Storybook Factories - -Storybook is where we can begin to take advantage of `Parameters` for a given service. Since stories can use controls to provide parameters, we can create a `ServiceFactory` that uses the `Parameters` generic and returns a `SharedUxFooService` that uses their values. - -```ts -import { action } from '@storybook/addon-actions'; - -interface FooServiceStorybookParameters { - foo: string; - baz: boolean; -} - -/** - * A factory function for creating a Storybook implementation of `SharedUxFooService`. - */ -export type FooServiceFactory = ServiceFactory; - -/** - * A factory function for creating a stubbed implementation of `SharedUxFooService`. - */ -export const fooServiceFactory: FooServiceFactory = ({ foo, baz }) => ({ - getFoo: () => foo, - setBar: () => action('setBar'), - isBaz: () => baz, -}); -``` - -A story can then optionally provide values for those parameters as part of its controls. - -```ts -type Params = Pick; - -export const ComponentStory = ({ foo }: Params) => { - const service = fooServiceFactory({ foo, baz: false }); - - return ( - ; -}; - -PureComponent.argTypes = { - foo: { - options: ['alpha', 'beta', 'gamma', 'delta'], - control: { type: 'radio' }, - }, -}; -``` - -### Kibana Factories - -Using these services in Kibana is a bit more complex, but is still relatively simple. First, we define what dependencies we'll need, (we use this interface in `src/plugins/shared_ux` as it relies on types found only in plugins, where packages cannot use them): - -```ts -/** - * Parameters necessary to create a Kibana-based service, (e.g. during Plugin - * startup or setup). - * - * The `Start` generic refers to the specific Plugin `TPluginsStart`. - */ -export interface KibanaPluginServiceParams { - coreStart: CoreStart; - startPlugins: Start; - appUpdater?: BehaviorSubject; - initContext?: PluginInitializerContext; -} - -/** - * A factory function for creating a Kibana-based service. - * - * The `Service` generic determines the shape of the Service being produced. - * The `Start` generic refers to the specific Plugin `TPluginsStart`. - */ -export type KibanaPluginServiceFactory = ( - params: KibanaPluginServiceParams -) => Service; -``` - -From there, a plugin might have a collection of dependencies on core or other plugins: - -```ts -export interface MyPluginStartDeps { - bar: BarPluginStart; - baz: BazPluginStart; -} -``` - -We'd then use this dependency interface to create a `ServiceFactory` for our service in Kibana: - -```ts -export type FooServiceFactory = KibanaPluginServiceFactory< - SharedUxFooService, - MyPluginStartDeps ->; - -/** - * A factory function for creating a Kibana-based implementation of `SharedUxFooService`. - */ -export const fooServiceFactory: FooServiceFactory = ({ coreStart, startPlugins }) => ({ - getFoo: startPlugins.bar.getSomeOtherFoo, - setBar: startPlugins.baz.setHappyPathBar, - isBaz: () => { - return coreStart.uiSettings.get('someSetting') === 'expectedValue'; - } -}); -``` - -From there, the pattern is the same: invoke the service factory with the required dependencies and provide them to the `SharedUxServicesContext` Provider: - -```ts - -// plugin.tsx -public start(coreStart: CoreStart, startPlugins: SharedUXPluginStartDeps): SharedUXPluginStart { - const fooService = fooServiceFactory({ coreStart, startPlugins }); - const Context = {children}; - - // ...wrap React content with the context.. -} -``` - -## Use in Kibana plugins - -In order to make consumption of these services easy by Kibana plugins, `src/plugins/shared_ux` provides a pre-wired set of services as part of the `start` lifecycle. Plugins can simply make `sharedUX` a dependency, import `SharedUxServicesProvider` and wrap their solution root (or any component). See the documentation for `sharedUX` for more details. diff --git a/packages/kbn-shared-ux-services/src/context.tsx b/packages/kbn-shared-ux-services/src/context.tsx deleted file mode 100644 index 6131c23e273704..00000000000000 --- a/packages/kbn-shared-ux-services/src/context.tsx +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import React, { FC, createContext, useContext } from 'react'; - -import type { SharedUxServices } from './types'; - -// The React Context used to provide the services to the SharedUX components. -const SharedUxServicesContext = createContext(null); - -/** - * The `React.Context` Provider component for the `SharedUxServices` context. Any - * plugin or environment that consumes SharedUX components needs to wrap their React - * tree with this provider. - * - * Within a plugin, you can use use the Shared UX plugin and retrieve a fully-configured - * context from the `start` contract. - */ -export const SharedUxServicesProvider: FC = ({ children, ...services }) => ( - {children} -); - -/** - * React hook for accessing pre-wired `SharedUxServices`. - */ -export function useSharedUxServices() { - const context = useContext(SharedUxServicesContext); - - if (!context) { - throw new Error( - 'SharedUxServicesContext missing. Ensure your component or React root is wrapped with SharedUxServicesProvider.' - ); - } - - return context; -} - -/** - * React hook for accessing the pre-wired `SharedUxPlatformService`. - */ -export const usePlatformService = () => useSharedUxServices().platform; - -/** - * React hook for accessing the pre-wired `SharedUxPermissionsService`. - */ -export const usePermissions = () => useSharedUxServices().permissions; - -/** - * React hook for accessing the pre-wired `SharedUxEditorsService`. - */ -export const useEditors = () => useSharedUxServices().editors; - -/** - * React hook for accessing the pre-wired `SharedUxDocLinksService`. - */ -export const useDocLinks = () => useSharedUxServices().docLinks; - -export const useHttp = () => useSharedUxServices().http; - -export const useApplication = () => useSharedUxServices().application; - -/** - * React hook for accessing the pre-wired `SharedUxDataService`. - */ -export const useData = () => useSharedUxServices().data; diff --git a/packages/kbn-shared-ux-services/src/index.ts b/packages/kbn-shared-ux-services/src/index.ts deleted file mode 100755 index 47f9d61ff88ac5..00000000000000 --- a/packages/kbn-shared-ux-services/src/index.ts +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -export type { ServiceFactory, SharedUxServices, SharedUxServicesContext } from './types'; -export type { - MockServicesFactoryParams, - SharedUxApplicationService, - SharedUxDocLinksService, - SharedUxEditorsService, - SharedUxHttpService, - SharedUxPlatformService, - SharedUxUserPermissionsService, - SharedUxDataService, -} from './services'; - -export { - SharedUxServicesProvider, - useApplication, - useDocLinks, - useEditors, - useHttp, - usePermissions, - usePlatformService, - useData, - useSharedUxServices, -} from './context'; - -export { - mockServiceFactories, - mockServicesFactory, - stubServiceFactories, - stubServicesFactory, -} from './services'; diff --git a/packages/kbn-shared-ux-services/src/services/data.ts b/packages/kbn-shared-ux-services/src/services/data.ts deleted file mode 100644 index 2750c9bd32085b..00000000000000 --- a/packages/kbn-shared-ux-services/src/services/data.ts +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -/** - * A service providing data information. Typically used for handling of empty state.. - */ -export interface SharedUxDataService { - /** True if the cluster contains data, false otherwise. */ - hasESData: () => Promise; - /** True if Kibana instance contains user-created data view, false otherwise. */ - hasUserDataView: () => Promise; - /** True if Kibana instance contains any data view, including system-created ones. */ - hasDataView: () => Promise; -} diff --git a/packages/kbn-shared-ux-services/src/services/doc_links.ts b/packages/kbn-shared-ux-services/src/services/doc_links.ts deleted file mode 100644 index 3b8eb4748d76fe..00000000000000 --- a/packages/kbn-shared-ux-services/src/services/doc_links.ts +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -/** - * A service providing links to documentation about various features in Kibana. - */ -export interface SharedUxDocLinksService { - /** A link to information about Data Views in Kibana */ - dataViewsDocLink: string; -} diff --git a/packages/kbn-shared-ux-services/src/services/editors.ts b/packages/kbn-shared-ux-services/src/services/editors.ts deleted file mode 100644 index 4dc5b7d9bc2694..00000000000000 --- a/packages/kbn-shared-ux-services/src/services/editors.ts +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -/** - * TODO: `DataView` is a class exported by `src/plugins/data_views/public`. Since this service - * is contained in this package-- and packages can only depend on other packages and never on - * plugins-- we have to set this to `unknown`. If and when `DataView` is exported from a - * stateless package, we can remove this. - * - * @see: https://github.com/elastic/kibana/issues/127695 - */ -type DataView = unknown; - -/** - * A subset of the `DataViewEditorOptions` interface relevant to our service and components. - * - * @see: src/plugins/data_view_editor/public/types.ts - */ -interface DataViewEditorOptions { - /** Handler to be invoked when the Data View Editor completes a save operation. */ - onSave: (dataView: DataView) => void; -} - -/** - * A service providing methods to invoke and interact with various editors provided - * in Kibana. - */ -export interface SharedUxEditorsService { - /** A method to open the Data View Editor flow. */ - openDataViewEditor: (options: DataViewEditorOptions) => () => void; -} diff --git a/packages/kbn-shared-ux-services/src/services/index.ts b/packages/kbn-shared-ux-services/src/services/index.ts deleted file mode 100644 index 0e4e4e473028df..00000000000000 --- a/packages/kbn-shared-ux-services/src/services/index.ts +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -export type { SharedUxApplicationService } from './application'; -export type { SharedUxDocLinksService } from './doc_links'; -export type { SharedUxEditorsService } from './editors'; -export type { SharedUxHttpService } from './http'; -export type { SharedUxUserPermissionsService } from './permissions'; -export type { SharedUxPlatformService } from './platform'; -export type { SharedUxDataService } from './data'; -export type { MockServicesFactoryParams } from './mock'; - -// eslint-disable-next-line @kbn/imports/no_boundary_crossing -export { mockServicesFactory, mockServiceFactories } from './mock'; -// eslint-disable-next-line @kbn/imports/no_boundary_crossing -export { stubServicesFactory, stubServiceFactories } from './stub'; diff --git a/packages/kbn-shared-ux-services/src/services/mock/application.mock.ts b/packages/kbn-shared-ux-services/src/services/mock/application.mock.ts deleted file mode 100644 index 947113c4a31686..00000000000000 --- a/packages/kbn-shared-ux-services/src/services/mock/application.mock.ts +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { Observable } from 'rxjs'; -import { ServiceFactory } from '../../types'; -import { SharedUxApplicationService } from '../application'; - -export type MockApplicationServiceFactory = ServiceFactory; - -/** - * A factory function for creating a Jest-based implementation of `SharedUXApplicationService`. - */ -export const applicationServiceFactory: MockApplicationServiceFactory = () => ({ - navigateToUrl: () => Promise.resolve(), - currentAppId$: new Observable((subscriber) => { - subscriber.next('abc123'); - }), -}); diff --git a/packages/kbn-shared-ux-services/src/services/mock/data.mock.ts b/packages/kbn-shared-ux-services/src/services/mock/data.mock.ts deleted file mode 100644 index bb9d59643348d5..00000000000000 --- a/packages/kbn-shared-ux-services/src/services/mock/data.mock.ts +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { ServiceFactory } from '../../types'; -import { SharedUxDataService } from '../data'; - -/** - * A factory function for creating a Jest-based implementation of `SharedUxDataService`. - */ -export type MockDataServiceFactory = ServiceFactory; - -export interface MockDataServiceFactoryConfig { - hasESData: boolean; - hasDataView: boolean; - hasUserDataView: boolean; -} - -/** - * A factory function for creating a Jest-based implementation of `SharedUxDataService`. - */ -export const dataServiceFactory: (config?: MockDataServiceFactoryConfig) => SharedUxDataService = ( - config?: MockDataServiceFactoryConfig -) => ({ - hasESData: () => Promise.resolve(config?.hasESData || false), - hasDataView: () => Promise.resolve(config?.hasDataView || false), - hasUserDataView: () => Promise.resolve(config?.hasUserDataView || false), -}); diff --git a/packages/kbn-shared-ux-services/src/services/mock/doc_links.mock.ts b/packages/kbn-shared-ux-services/src/services/mock/doc_links.mock.ts deleted file mode 100644 index 2ee0985d0a4132..00000000000000 --- a/packages/kbn-shared-ux-services/src/services/mock/doc_links.mock.ts +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import type { ServiceFactory } from '../../types'; -import type { SharedUxDocLinksService } from '../doc_links'; - -/** - * A factory function for creating a Jest implementation of `SharedUxDocLinksService`. - */ -export type MockDocLinksServiceFactory = ServiceFactory; - -/** - * A factory function for creating a Jest-based implementation of `SharedUxDocLinksService`. - */ -export const docLinksServiceFactory: MockDocLinksServiceFactory = () => ({ - dataViewsDocLink: 'dummy link', -}); diff --git a/packages/kbn-shared-ux-services/src/services/mock/editors.mock.ts b/packages/kbn-shared-ux-services/src/services/mock/editors.mock.ts deleted file mode 100644 index 80742f15d93cda..00000000000000 --- a/packages/kbn-shared-ux-services/src/services/mock/editors.mock.ts +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import type { ServiceFactory } from '../../types'; -import type { SharedUxEditorsService } from '../editors'; - -/** - * A factory function for creating a Jest-based implementation of `SharedUxEditorsService`. - */ -export type MockEditorsServiceFactory = ServiceFactory; - -/** - * A factory function for creating a Jest-based implementation of `SharedUxEditorsService`. - */ -export const editorsServiceFactory: MockEditorsServiceFactory = () => ({ - openDataViewEditor: jest.fn(), -}); diff --git a/packages/kbn-shared-ux-services/src/services/mock/http.mock.ts b/packages/kbn-shared-ux-services/src/services/mock/http.mock.ts deleted file mode 100644 index 0ef07526e5116a..00000000000000 --- a/packages/kbn-shared-ux-services/src/services/mock/http.mock.ts +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { ServiceFactory } from '../../types'; -import { SharedUxHttpService } from '../http'; - -export type MockHttpServiceFactory = ServiceFactory; - -/** - * A factory function for creating a Jest-based implementation of `SharedUXHttpService`. - */ -export const httpServiceFactory: MockHttpServiceFactory = () => ({ - addBasePath: jest.fn((path: string) => (path ? path : 'path')), -}); diff --git a/packages/kbn-shared-ux-services/src/services/mock/index.ts b/packages/kbn-shared-ux-services/src/services/mock/index.ts deleted file mode 100644 index 604a8ae677b9d0..00000000000000 --- a/packages/kbn-shared-ux-services/src/services/mock/index.ts +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import type { SharedUxServices } from '../../types'; - -import { applicationServiceFactory } from './application.mock'; -import { docLinksServiceFactory } from './doc_links.mock'; -import { editorsServiceFactory } from './editors.mock'; -import { httpServiceFactory } from './http.mock'; -import { userPermissionsServiceFactory } from './permissions.mock'; -import { platformServiceFactory } from './platform.mock'; -import { dataServiceFactory, MockDataServiceFactoryConfig } from './data.mock'; - -export type { MockApplicationServiceFactory } from './application.mock'; -export type { MockDocLinksServiceFactory } from './doc_links.mock'; -export type { MockEditorsServiceFactory } from './editors.mock'; -export type { MockHttpServiceFactory } from './http.mock'; -export type { MockUserPermissionsServiceFactory } from './permissions.mock'; -export type { MockPlatformServiceFactory } from './platform.mock'; - -export { applicationServiceFactory } from './application.mock'; -export { docLinksServiceFactory } from './doc_links.mock'; -export { editorsServiceFactory } from './editors.mock'; -export { httpServiceFactory } from './http.mock'; -export { userPermissionsServiceFactory } from './permissions.mock'; -export { platformServiceFactory } from './platform.mock'; -export { dataServiceFactory } from './data.mock'; - -export interface MockServicesFactoryParams { - config: MockDataServiceFactoryConfig; -} - -/** - * A factory function for creating a Jest-based implementation of `SharedUxServices`. - */ -export const mockServicesFactory: (params?: MockServicesFactoryParams) => SharedUxServices = ( - params?: MockServicesFactoryParams -) => ({ - application: applicationServiceFactory(), - docLinks: docLinksServiceFactory(), - editors: editorsServiceFactory(), - http: httpServiceFactory(), - permissions: userPermissionsServiceFactory(), - platform: platformServiceFactory(), - data: dataServiceFactory(params?.config), -}); - -/** - * A collection of mock Service Factories. - */ -export const mockServiceFactories = { - applicationServiceFactory, - docLinksServiceFactory, - editorsServiceFactory, - httpServiceFactory, - platformServiceFactory, - userPermissionsServiceFactory, - dataServiceFactory, -}; diff --git a/packages/kbn-shared-ux-services/src/services/mock/permissions.mock.ts b/packages/kbn-shared-ux-services/src/services/mock/permissions.mock.ts deleted file mode 100644 index 3fb5e78a5b839f..00000000000000 --- a/packages/kbn-shared-ux-services/src/services/mock/permissions.mock.ts +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import type { ServiceFactory } from '../../types'; -import type { SharedUxUserPermissionsService } from '../permissions'; - -/** - * A factory function for creating a Jest-based implementation of `SharedUxUserPermissionsService`. - */ -export type MockUserPermissionsServiceFactory = ServiceFactory; - -/** - * A factory function for creating a Jest-based implementation of `SharedUxUserPermissionsService`. - */ -export const userPermissionsServiceFactory: MockUserPermissionsServiceFactory = () => ({ - canCreateNewDataView: true, - canAccessFleet: true, -}); diff --git a/packages/kbn-shared-ux-services/src/services/mock/platform.mock.ts b/packages/kbn-shared-ux-services/src/services/mock/platform.mock.ts deleted file mode 100644 index 8e6ec205d28569..00000000000000 --- a/packages/kbn-shared-ux-services/src/services/mock/platform.mock.ts +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import type { ServiceFactory } from '../../types'; -import type { SharedUxPlatformService } from '../platform'; - -/** - * A factory function for creating a Jest-based implementation of `SharedUxPlatformService`. - */ -export type MockPlatformServiceFactory = ServiceFactory; - -/** - * A factory function for creating a Jest-based implementation of `SharedUxPlatformService`. - */ -export const platformServiceFactory: MockPlatformServiceFactory = () => ({ - setIsFullscreen: jest.fn(), -}); diff --git a/packages/kbn-shared-ux-services/src/services/permissions.ts b/packages/kbn-shared-ux-services/src/services/permissions.ts deleted file mode 100644 index d6fcabd8ccedf2..00000000000000 --- a/packages/kbn-shared-ux-services/src/services/permissions.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -/** - * A service providing permissions information, typically for the current user. - */ -export interface SharedUxUserPermissionsService { - /** True if the user has permission to create a new Data View, false otherwise. */ - canCreateNewDataView: boolean; - canAccessFleet: boolean; -} diff --git a/packages/kbn-shared-ux-services/src/services/platform.ts b/packages/kbn-shared-ux-services/src/services/platform.ts deleted file mode 100644 index 83148abac8643e..00000000000000 --- a/packages/kbn-shared-ux-services/src/services/platform.ts +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -/** - * A service providing methods to interact with the platform in which this code is - * running, (almost always Kibana). - * - * Rather than provide the entire `CoreStart` contract to components, we provide simplified - * abstractions around a use case specific to Shared UX. This way, we know exactly how the - * `CoreStart` and other plugins are used. This makes mocking and refactoring easier when - * upstream dependencies change. - */ -export interface SharedUxPlatformService { - /** - * Sets the fullscreen state of the chrome. - * @param isFullscreen True if the chrome should be fullscreen, false otherwise. - */ - setIsFullscreen: (isFullscreen: boolean) => void; -} diff --git a/packages/kbn-shared-ux-services/src/services/stub/application.ts b/packages/kbn-shared-ux-services/src/services/stub/application.ts deleted file mode 100644 index 72c1f3db30089b..00000000000000 --- a/packages/kbn-shared-ux-services/src/services/stub/application.ts +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { Observable } from 'rxjs'; -import { ServiceFactory } from '../../types'; -import { SharedUxApplicationService } from '../application'; - -export type ApplicationServiceFactory = ServiceFactory; - -/** - * A factory function for creating for creating a simple stubbed implementation of `SharedUXApplicationService`. - */ -export const applicationServiceFactory: ApplicationServiceFactory = () => ({ - navigateToUrl: (url) => { - // eslint-disable-next-line no-console - console.log(url); - return Promise.resolve(); - }, - currentAppId$: new Observable((subscriber) => { - subscriber.next('123'); - }), -}); diff --git a/packages/kbn-shared-ux-services/src/services/stub/data.ts b/packages/kbn-shared-ux-services/src/services/stub/data.ts deleted file mode 100644 index 833c64e1f9d8d0..00000000000000 --- a/packages/kbn-shared-ux-services/src/services/stub/data.ts +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { ServiceFactory } from '../../types'; -import { SharedUxDataService } from '../data'; - -/** - * A factory function for creating a simple stubbed implementation of `SharedUxDataSevice`. - */ -export type DataServiceFactory = ServiceFactory; - -/** - * A factory function for creating a simple stubbed implementation of `SharedUxDataSevice`. - */ -export const dataServiceFactory: DataServiceFactory = () => ({ - hasESData: () => Promise.resolve(true), - hasDataView: () => Promise.resolve(false), - hasUserDataView: () => Promise.resolve(false), -}); diff --git a/packages/kbn-shared-ux-services/src/services/stub/doc_links.ts b/packages/kbn-shared-ux-services/src/services/stub/doc_links.ts deleted file mode 100644 index 9bcfd7db78cfa1..00000000000000 --- a/packages/kbn-shared-ux-services/src/services/stub/doc_links.ts +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import type { ServiceFactory } from '../../types'; -import type { SharedUxDocLinksService } from '../doc_links'; - -/** - * A factory function for creating a stubbed implementation of `SharedUxDocLinksService`. - */ -export type DocLinksServiceFactory = ServiceFactory; - -/** - * A factory function for creating a stubbed implementation of `SharedUxDocLinksService`. - */ -export const docLinksServiceFactory: DocLinksServiceFactory = () => ({ - dataViewsDocLink: 'docs', -}); diff --git a/packages/kbn-shared-ux-services/src/services/stub/editors.ts b/packages/kbn-shared-ux-services/src/services/stub/editors.ts deleted file mode 100644 index 545539d873941e..00000000000000 --- a/packages/kbn-shared-ux-services/src/services/stub/editors.ts +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import type { ServiceFactory } from '../../types'; -import type { SharedUxEditorsService } from '../editors'; - -/** - * A factory function for creating a simple stubbed implementation of `SharedUxEditorsService`. - */ -export type EditorsServiceFactory = ServiceFactory; - -/** - * A factory function for creating a simple stubbed implementation of `SharedUxEditorsService`. - */ -export const editorsServiceFactory: EditorsServiceFactory = () => ({ - openDataViewEditor: () => () => {}, -}); diff --git a/packages/kbn-shared-ux-services/src/services/stub/http.ts b/packages/kbn-shared-ux-services/src/services/stub/http.ts deleted file mode 100644 index 08dae62ecdb7f7..00000000000000 --- a/packages/kbn-shared-ux-services/src/services/stub/http.ts +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { ServiceFactory } from '../../types'; -import { SharedUxHttpService } from '../http'; - -/** - * A factory function for creating a simple stubbed implementation of `SharedUXHttpService`. - */ -export type HttpServiceFactory = ServiceFactory; - -/** - * A factory function for creating a simple stubbed implementation of `SharedUXHttpService`. - */ -export const httpServiceFactory: HttpServiceFactory = () => ({ - addBasePath: (url: string) => { - return url; - }, -}); diff --git a/packages/kbn-shared-ux-services/src/services/stub/index.ts b/packages/kbn-shared-ux-services/src/services/stub/index.ts deleted file mode 100644 index ab8b0ca3f4d9c5..00000000000000 --- a/packages/kbn-shared-ux-services/src/services/stub/index.ts +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import type { SharedUxServices, ServiceFactory } from '../../types'; - -import { applicationServiceFactory } from './application'; -import { docLinksServiceFactory } from './doc_links'; -import { editorsServiceFactory } from './editors'; -import { httpServiceFactory } from './http'; -import { platformServiceFactory } from './platform'; -import { userPermissionsServiceFactory } from './permissions'; -import { dataServiceFactory } from './data'; - -/** - * A factory function for creating simple stubbed implementations of all `SharedUxServices`. - */ -export const stubServicesFactory: ServiceFactory = () => ({ - application: applicationServiceFactory(), - docLinks: docLinksServiceFactory(), - editors: editorsServiceFactory(), - http: httpServiceFactory(), - permissions: userPermissionsServiceFactory(), - platform: platformServiceFactory(), - data: dataServiceFactory(), -}); - -/** - * A collection of stubbed service factories. - */ -export const stubServiceFactories = { - applicationServiceFactory, - docLinksServiceFactory, - editorsServiceFactory, - httpServiceFactory, - platformServiceFactory, - userPermissionsServiceFactory, - dataServiceFactory, -}; diff --git a/packages/kbn-shared-ux-services/src/services/stub/permissions.ts b/packages/kbn-shared-ux-services/src/services/stub/permissions.ts deleted file mode 100644 index e5588f818f82a2..00000000000000 --- a/packages/kbn-shared-ux-services/src/services/stub/permissions.ts +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import type { ServiceFactory } from '../../types'; -import type { SharedUxUserPermissionsService } from '../permissions'; - -/** - * A factory function for creating a simple stubbed implementation of `SharedUxUserPermissionsService`. - */ -export type UserPermissionsServiceFactory = ServiceFactory; - -/** - * A factory function for creating a simple stubbed implementation of `SharedUxUserPermissionsService`. - */ -export const userPermissionsServiceFactory: UserPermissionsServiceFactory = () => ({ - canCreateNewDataView: true, - canAccessFleet: true, -}); diff --git a/packages/kbn-shared-ux-services/src/services/stub/platform.ts b/packages/kbn-shared-ux-services/src/services/stub/platform.ts deleted file mode 100644 index 2e31238347307c..00000000000000 --- a/packages/kbn-shared-ux-services/src/services/stub/platform.ts +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import type { ServiceFactory } from '../../types'; -import type { SharedUxPlatformService } from '../platform'; - -/** - * A factory function for creating a simple stubbed implementation of `SharedUxPlatformService`. - */ -export type PlatformServiceFactory = ServiceFactory; - -/** - * A factory function for creating a simple stubbed implementation of `SharedUxPlatformService`. - */ -export const platformServiceFactory: PlatformServiceFactory = () => ({ - setIsFullscreen: (_isFullscreen) => {}, -}); diff --git a/packages/kbn-shared-ux-services/src/types.ts b/packages/kbn-shared-ux-services/src/types.ts deleted file mode 100755 index a0a4ec32c0e758..00000000000000 --- a/packages/kbn-shared-ux-services/src/types.ts +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { FC } from 'react'; - -import { - SharedUxApplicationService, - SharedUxDataService, - SharedUxDocLinksService, - SharedUxEditorsService, - SharedUxHttpService, - SharedUxPlatformService, - SharedUxUserPermissionsService, -} from './services'; - -/** - * A collection of services utilized by SharedUX. This serves as a thin - * abstraction layer between services provided by Kibana and other plugins - * while allowing this plugin to be developed independently of those contracts. - * - * It also allows us to "swap out" differenct implementations of these services - * for different environments, (e.g. Jest, Storybook, etc.) - */ -export interface SharedUxServices { - application: SharedUxApplicationService; - docLinks: SharedUxDocLinksService; - editors: SharedUxEditorsService; - http: SharedUxHttpService; - permissions: SharedUxUserPermissionsService; - platform: SharedUxPlatformService; - data: SharedUxDataService; -} - -/** - * A type representing a component that provides the `SharedUxServices` through a - * React Context. - */ -export type SharedUxServicesContext = FC<{}>; - -/** - * A factory function for creating one or more services. - * - * The `S` generic determines the shape of the API being produced. - * The `Parameters` generic determines what parameters are expected to - * create the service. - */ -export type ServiceFactory = (params: Parameters) => S; diff --git a/packages/kbn-shared-ux-storybook/README.mdx b/packages/kbn-shared-ux-storybook/README.mdx deleted file mode 100644 index 11992e336e627c..00000000000000 --- a/packages/kbn-shared-ux-storybook/README.mdx +++ /dev/null @@ -1,34 +0,0 @@ ---- -id: kibSharedUXStorybook -slug: /kibana-dev-docs/shared-ux/packages/kbn-shared-ux-storybook -title: Shared UX Storybook -description: The `@kbn/shared-ux-storybook` package provides Storybook assets for Shared UX and other teams. -date: 2022-03-11 -tags: ['kibana', 'dev', 'sharedUX'] ---- - -## About Shared UX Storybook - -This package provides the Storybook implementation of `@kbn/shared-ux-services` as well as the configuration for the Shared UX Storybook site. - -- `/src/services` The `@kbn/shared-ux-services` implementation. -- `src/config` The Storybook site configuration. - -## Storybook site - -Run `yarn storybook shared_ux` from `/kibana` to view the site. It pulls in `*.stories.tsx` from all Shared UX packages and plugins and combines them into a single configuration. - -## Decorator - -If you're writing stories for your own components that compose Shared UX components, you can use a pre-configured [Storybook Decorator](https://storybook.js.org/docs/react/writing-stories/decorators) in your Storybook configuration: - -```ts -// preview.ts - -import { addDecorator } from '@storybook/react'; -import { servicesDecorator } from '@kbn/shared-ux-storybook'; - -addDecorator(servicesDecorator); -``` - -This will not only expose parameters, but also wrap your story in a pre-wired `SharedUxServicesProvider`. \ No newline at end of file diff --git a/packages/kbn-shared-ux-storybook/src/decorators.tsx b/packages/kbn-shared-ux-storybook/src/decorators.tsx deleted file mode 100644 index cae87a15b54ddd..00000000000000 --- a/packages/kbn-shared-ux-storybook/src/decorators.tsx +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import React from 'react'; -import { DecoratorFn } from '@storybook/react'; - -import { SharedUxServicesProvider } from '@kbn/shared-ux-services'; - -import { servicesFactory } from './services'; - -/** - * A Storybook decorator that provides the Shared UX `ServicesProvider` with Storybook-specific - * implementations to stories. - */ -export const servicesDecorator: DecoratorFn = (storyFn) => ( - {storyFn()} -); diff --git a/packages/kbn-shared-ux-storybook/src/services/application.ts b/packages/kbn-shared-ux-storybook/src/services/application.ts deleted file mode 100644 index 1b16526bc8be85..00000000000000 --- a/packages/kbn-shared-ux-storybook/src/services/application.ts +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { BehaviorSubject } from 'rxjs'; -import { action } from '@storybook/addon-actions'; -import { ServiceFactory, SharedUxApplicationService } from '@kbn/shared-ux-services'; - -export type ApplicationServiceFactory = ServiceFactory; - -/** - * A factory function for creating for creating a storybook implementation of `SharedUXApplicationService`. - */ -export const applicationServiceFactory: ApplicationServiceFactory = () => ({ - navigateToUrl: (url) => { - action('navigateToUrl')(url); - return Promise.resolve(); - }, - currentAppId$: new BehaviorSubject('123'), -}); diff --git a/packages/kbn-shared-ux-storybook/src/services/data.ts b/packages/kbn-shared-ux-storybook/src/services/data.ts deleted file mode 100644 index dbfd2fceb4210b..00000000000000 --- a/packages/kbn-shared-ux-storybook/src/services/data.ts +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { ServiceFactory, SharedUxDataService } from '@kbn/shared-ux-services'; - -export interface DataServiceFactoryConfig { - hasESData: boolean; - hasDataView: boolean; - hasUserDataView: boolean; -} - -/** - * A factory function for creating a Storybook implementation of `SharedUxDataService`. - */ -export type SharedUxDataServiceFactory = ServiceFactory< - SharedUxDataService, - DataServiceFactoryConfig ->; - -/** - * A factory function for creating a Storybook implementation of `SharedUxDataService`. - */ -export const dataServiceFactory: SharedUxDataServiceFactory = (params) => { - return { - hasESData: () => Promise.resolve(params.hasESData || false), - hasDataView: () => Promise.resolve(params.hasDataView || false), - hasUserDataView: () => Promise.resolve(params.hasUserDataView || false), - }; -}; diff --git a/packages/kbn-shared-ux-storybook/src/services/doc_links.ts b/packages/kbn-shared-ux-storybook/src/services/doc_links.ts deleted file mode 100644 index eff942989956f7..00000000000000 --- a/packages/kbn-shared-ux-storybook/src/services/doc_links.ts +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { ServiceFactory, SharedUxDocLinksService } from '@kbn/shared-ux-services'; - -/** - * A factory function for creating a Storybook implementation of `SharedUxDocLinksService`. - */ -export type SharedUxDocLinksServiceFactory = ServiceFactory; - -/** - * A factory function for creating a Storybook implementation of `SharedUxDocLinksService`. - */ -export const docLinksServiceFactory: SharedUxDocLinksServiceFactory = () => ({ - dataViewsDocLink: 'https://www.elastic.co/guide/en/kibana/master/data-views.html', - kibanaGuideDocLink: 'https://www.elastic.co/guide/en/kibana/master/index.html', -}); diff --git a/packages/kbn-shared-ux-storybook/src/services/editors.ts b/packages/kbn-shared-ux-storybook/src/services/editors.ts deleted file mode 100644 index 69b9d7062da94d..00000000000000 --- a/packages/kbn-shared-ux-storybook/src/services/editors.ts +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { action } from '@storybook/addon-actions'; -import { ServiceFactory, SharedUxEditorsService } from '@kbn/shared-ux-services'; - -/** - * A factory function for creating a Storybook implementation of `SharedUxEditorsService`. - */ -export type SharedUxEditorsServiceFactory = ServiceFactory; - -/** - * A factory function for creating a Storybook implementation of `SharedUxEditorsService`. - */ -export const editorsServiceFactory: SharedUxEditorsServiceFactory = () => ({ - openDataViewEditor: action('openEditor') as SharedUxEditorsService['openDataViewEditor'], -}); diff --git a/packages/kbn-shared-ux-storybook/src/services/http.ts b/packages/kbn-shared-ux-storybook/src/services/http.ts deleted file mode 100644 index f44fb10566dc33..00000000000000 --- a/packages/kbn-shared-ux-storybook/src/services/http.ts +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { action } from '@storybook/addon-actions'; - -import { ServiceFactory, SharedUxHttpService } from '@kbn/shared-ux-services'; - -/** - * A factory function for creating a Storybook-based implementation of `SharedUXHttpService`. - */ -export type HttpServiceFactory = ServiceFactory; - -/** - * A factory function for creating a Storybook-based implementation of `SharedUXHttpService`. - */ -export const httpServiceFactory: HttpServiceFactory = () => ({ - addBasePath: action('addBasePath') as SharedUxHttpService['addBasePath'], -}); diff --git a/packages/kbn-shared-ux-storybook/src/services/index.ts b/packages/kbn-shared-ux-storybook/src/services/index.ts deleted file mode 100644 index ff6ad1f1f29132..00000000000000 --- a/packages/kbn-shared-ux-storybook/src/services/index.ts +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import type { ServiceFactory, SharedUxServices } from '@kbn/shared-ux-services'; - -import { applicationServiceFactory } from './application'; -import { docLinksServiceFactory } from './doc_links'; -import { editorsServiceFactory } from './editors'; -import { httpServiceFactory } from './http'; -import { platformServiceFactory } from './platform'; -import { userPermissionsServiceFactory } from './permissions'; -import { dataServiceFactory, DataServiceFactoryConfig } from './data'; - -export { applicationServiceFactory } from './application'; -export { docLinksServiceFactory } from './doc_links'; -export { editorsServiceFactory } from './editors'; -export { httpServiceFactory } from './http'; -export { platformServiceFactory } from './platform'; -export { userPermissionsServiceFactory } from './permissions'; -export { dataServiceFactory } from './data'; - -/** - * A factory function for creating a Storybook implementation of `SharedUxServices`. - */ -export const servicesFactory: ServiceFactory = (params) => ({ - application: applicationServiceFactory(), - docLinks: docLinksServiceFactory(), - editors: editorsServiceFactory(), - http: httpServiceFactory(params), - permissions: userPermissionsServiceFactory(), - platform: platformServiceFactory(params), - data: dataServiceFactory(params as DataServiceFactoryConfig), -}); - -export type { DataServiceFactoryConfig } from './data'; diff --git a/packages/kbn-shared-ux-storybook/src/services/permissions.ts b/packages/kbn-shared-ux-storybook/src/services/permissions.ts deleted file mode 100644 index 5d00ac3ee1cb24..00000000000000 --- a/packages/kbn-shared-ux-storybook/src/services/permissions.ts +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { ServiceFactory, SharedUxUserPermissionsService } from '@kbn/shared-ux-services'; - -/** - * A factory function for creating a Storybook implementation of `SharedUxUserPermissionsService`. - */ -export type SharedUxUserPermissionsServiceFactory = ServiceFactory; - -/** - * A factory function for creating a Storybook implementation of `SharedUxUserPermissionsService`. - */ -export const userPermissionsServiceFactory: SharedUxUserPermissionsServiceFactory = () => ({ - canCreateNewDataView: true, - canAccessFleet: true, -}); diff --git a/packages/kbn-shared-ux-storybook/src/services/platform.ts b/packages/kbn-shared-ux-storybook/src/services/platform.ts deleted file mode 100644 index 2a1cb6c3ff42bc..00000000000000 --- a/packages/kbn-shared-ux-storybook/src/services/platform.ts +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { action } from '@storybook/addon-actions'; -import { ServiceFactory, SharedUxPlatformService } from '@kbn/shared-ux-services'; - -/** - * A factory function for creating a Storybook implementation of `SharedUxPlatformService`. - */ -export type PlatformServiceFactory = ServiceFactory; - -/** - * A factory function for creating a Storybook implementation of `SharedUxPlatformService`. - */ -export const platformServiceFactory: PlatformServiceFactory = () => ({ - setIsFullscreen: action('setIsChromeVisible'), -}); diff --git a/packages/kbn-test/jest_integration_node/jest-preset.js b/packages/kbn-test/jest_integration_node/jest-preset.js index 8f5f433139ab7d..ff50c2de409614 100644 --- a/packages/kbn-test/jest_integration_node/jest-preset.js +++ b/packages/kbn-test/jest_integration_node/jest-preset.js @@ -8,10 +8,14 @@ const preset = require('../jest-preset'); +const presetClone = { ...preset }; + +delete presetClone.testEnvironment; // simply redefining as `testEnvironment: 'node'` has some weird side-effects (https://github.com/elastic/kibana/pull/138877) + /** @typedef {import("@jest/types").Config.InitialOptions} JestConfig */ /** @type {JestConfig} */ module.exports = { - ...preset, + ...presetClone, testMatch: ['**/integration_tests**/*.test.{js,mjs,ts,tsx}'], testPathIgnorePatterns: preset.testPathIgnorePatterns.filter( (pattern) => !pattern.includes('integration_tests') @@ -40,7 +44,6 @@ module.exports = { ? [['json', { file: 'jest-integration.json' }]] : ['html', 'text'], - testEnvironment: 'node', snapshotSerializers: [], setupFiles: ['/node_modules/@kbn/test/target_node/jest/setup/babel_polyfill.js'], haste: { diff --git a/packages/kbn-test/jest_node/jest-preset.js b/packages/kbn-test/jest_node/jest-preset.js index 78d20414b93890..a28456e0da1f56 100644 --- a/packages/kbn-test/jest_node/jest-preset.js +++ b/packages/kbn-test/jest_node/jest-preset.js @@ -8,9 +8,12 @@ const preset = require('../jest-preset'); +const presetClone = { ...preset }; + +delete presetClone.testEnvironment; // simply redefining as `testEnvironment: 'node'` has some weird side-effects (https://github.com/elastic/kibana/pull/138877#issuecomment-1222366247) + module.exports = { - ...preset, - testEnvironment: 'node', + ...presetClone, snapshotSerializers: [], setupFiles: ['/node_modules/@kbn/test/target_node/jest/setup/babel_polyfill.js'], haste: { diff --git a/packages/kbn-test/src/jest/setup/enzyme.js b/packages/kbn-test/src/jest/setup/enzyme.js index c0ebcb93fc4a2f..bf759523cfe7ab 100644 --- a/packages/kbn-test/src/jest/setup/enzyme.js +++ b/packages/kbn-test/src/jest/setup/enzyme.js @@ -7,6 +7,6 @@ */ import { configure } from 'enzyme'; -import Adapter from 'enzyme-adapter-react-16'; +import Adapter from '@wojtekmaj/enzyme-adapter-react-17'; configure({ adapter: new Adapter() }); diff --git a/packages/kbn-ui-shared-deps-src/BUILD.bazel b/packages/kbn-ui-shared-deps-src/BUILD.bazel index 18d50fdc05e633..db8d6c64fb6dbd 100644 --- a/packages/kbn-ui-shared-deps-src/BUILD.bazel +++ b/packages/kbn-ui-shared-deps-src/BUILD.bazel @@ -27,7 +27,7 @@ NPM_MODULE_EXTRA_FILES = [ ] RUNTIME_DEPS = [ - "//packages/elastic-safer-lodash-set", + "//packages/kbn-safer-lodash-set", "//packages/kbn-analytics", "//packages/kbn-babel-preset", "//packages/kbn-datemath", @@ -41,7 +41,7 @@ RUNTIME_DEPS = [ ] TYPES_DEPS = [ - "//packages/elastic-safer-lodash-set:npm_module_types", + "//packages/kbn-safer-lodash-set:npm_module_types", "//packages/kbn-analytics:npm_module_types", "//packages/kbn-datemath:npm_module_types", "//packages/kbn-i18n:npm_module_types", diff --git a/packages/kbn-ui-shared-deps-src/src/definitions.js b/packages/kbn-ui-shared-deps-src/src/definitions.js index 3e783d99b62cfe..759b1bee856d25 100644 --- a/packages/kbn-ui-shared-deps-src/src/definitions.js +++ b/packages/kbn-ui-shared-deps-src/src/definitions.js @@ -75,7 +75,7 @@ const externals = { tslib: '__kbnSharedDeps__.TsLib', '@kbn/analytics': '__kbnSharedDeps__.KbnAnalytics', '@kbn/std': '__kbnSharedDeps__.KbnStd', - '@elastic/safer-lodash-set': '__kbnSharedDeps__.SaferLodashSet', + '@kbn/safer-lodash-set': '__kbnSharedDeps__.SaferLodashSet', 'rison-node': '__kbnSharedDeps__.RisonNode', history: '__kbnSharedDeps__.History', classnames: '__kbnSharedDeps__.Classnames', diff --git a/packages/kbn-ui-shared-deps-src/src/entry.js b/packages/kbn-ui-shared-deps-src/src/entry.js index 9114a472ba53e2..233872bacff585 100644 --- a/packages/kbn-ui-shared-deps-src/src/entry.js +++ b/packages/kbn-ui-shared-deps-src/src/entry.js @@ -55,7 +55,7 @@ export const Fflate = { unzlibSync, strFromU8 }; export const TsLib = require('tslib'); export const KbnAnalytics = require('@kbn/analytics'); export const KbnStd = require('@kbn/std'); -export const SaferLodashSet = require('@elastic/safer-lodash-set'); +export const SaferLodashSet = require('@kbn/safer-lodash-set'); export const RisonNode = require('rison-node'); export const History = require('history'); export const Classnames = require('classnames'); diff --git a/packages/shared-ux/avatar/solution/src/solution_avatar.stories.tsx b/packages/shared-ux/avatar/solution/src/solution_avatar.stories.tsx index b47ff7c837f241..f7dca09fc8b1fe 100644 --- a/packages/shared-ux/avatar/solution/src/solution_avatar.stories.tsx +++ b/packages/shared-ux/avatar/solution/src/solution_avatar.stories.tsx @@ -10,7 +10,7 @@ import React from 'react'; import { KibanaSolutionAvatar, IconTypeProps, KnownSolutionProps } from './solution_avatar'; export default { - title: 'Solution Avatar', + title: 'Avatar/Solution', description: 'A wrapper around EuiAvatar, specifically to stylize Elastic Solutions', }; @@ -24,11 +24,11 @@ const argTypes = { type KnownSolutionParams = Pick; -export const SolutionAvatar = (params: KnownSolutionParams) => { +export const SolutionType = (params: KnownSolutionParams) => { return ; }; -SolutionAvatar.argTypes = { +SolutionType.argTypes = { name: { control: 'select', options: ['Cloud', 'Elastic', 'Kibana', 'Observability', 'Security', 'Enterprise Search'], @@ -39,11 +39,11 @@ SolutionAvatar.argTypes = { type IconTypeParams = Pick; -export const IconTypeAvatar = (params: IconTypeParams) => { +export const IconType = (params: IconTypeParams) => { return ; }; -IconTypeAvatar.argTypes = { +IconType.argTypes = { iconType: { control: 'select', options: [ diff --git a/packages/shared-ux/button/exit_full_screen/mocks/BUILD.bazel b/packages/shared-ux/button/exit_full_screen/mocks/BUILD.bazel index cd88ae0f1fe270..50a3e109546cda 100644 --- a/packages/shared-ux/button/exit_full_screen/mocks/BUILD.bazel +++ b/packages/shared-ux/button/exit_full_screen/mocks/BUILD.bazel @@ -10,8 +10,17 @@ SOURCE_FILES = glob( "src/**/*.ts", ], exclude = [ + "**/*.config.js", + "**/*.mock.*", "**/*.test.*", "**/*.stories.*", + "**/__snapshots__", + "**/integration_tests", + "**/mocks", + "**/scripts", + "**/storybook", + "**/test_fixtures", + "**/test_helpers", ], ) @@ -38,6 +47,7 @@ NPM_MODULE_EXTRA_FILES = [ # eg. "@npm//lodash" RUNTIME_DEPS = [ "@npm//@storybook/addon-actions", + "@npm//react", "//packages/shared-ux/storybook/mock", ] @@ -53,6 +63,7 @@ RUNTIME_DEPS = [ TYPES_DEPS = [ "@npm//@types/node", "@npm//@types/jest", + "@npm//@types/react", "@npm//@storybook/addon-actions", "//packages/shared-ux/button/exit_full_screen/types:npm_module_types", "//packages/shared-ux/storybook/mock:npm_module_types", @@ -65,6 +76,14 @@ jsts_transpiler( root_input_dir = "src", ) +jsts_transpiler( + name = "target_web", + srcs = SRCS, + build_pkg_name = package_name(), + root_input_dir = "src", + web = True, +) + ts_config( name = "tsconfig", src = "tsconfig.json", @@ -90,7 +109,7 @@ ts_project( js_library( name = PKG_DIRNAME, srcs = NPM_MODULE_EXTRA_FILES, - deps = RUNTIME_DEPS + [":target_node"], + deps = RUNTIME_DEPS + [":target_node", ":target_web"], package_name = PKG_REQUIRE_NAME, visibility = ["//visibility:public"], ) diff --git a/packages/shared-ux/button/exit_full_screen/mocks/package.json b/packages/shared-ux/button/exit_full_screen/mocks/package.json index 490d136049e1a2..1ce5731e7bee3e 100644 --- a/packages/shared-ux/button/exit_full_screen/mocks/package.json +++ b/packages/shared-ux/button/exit_full_screen/mocks/package.json @@ -3,5 +3,6 @@ "private": true, "version": "1.0.0", "main": "./target_node/index.js", + "browser": "./target_web/index.js", "license": "SSPL-1.0 OR Elastic License 2.0" } \ No newline at end of file diff --git a/packages/shared-ux/button/exit_full_screen/mocks/tsconfig.json b/packages/shared-ux/button/exit_full_screen/mocks/tsconfig.json index 894f01d3220e91..dc96ec41f9035d 100644 --- a/packages/shared-ux/button/exit_full_screen/mocks/tsconfig.json +++ b/packages/shared-ux/button/exit_full_screen/mocks/tsconfig.json @@ -9,10 +9,12 @@ "stripInternal": false, "types": [ "jest", - "node" + "node", + "react" ] }, "include": [ - "src/**/*" + "**/*.ts", + "**/*.tsx", ] } diff --git a/packages/shared-ux/card/no_data/impl/src/no_data_card.stories.tsx b/packages/shared-ux/card/no_data/impl/src/no_data_card.stories.tsx index 5c7b1a57c11f2f..8574b31da792ab 100644 --- a/packages/shared-ux/card/no_data/impl/src/no_data_card.stories.tsx +++ b/packages/shared-ux/card/no_data/impl/src/no_data_card.stories.tsx @@ -11,8 +11,7 @@ import React from 'react'; import { NoDataCardStorybookMock } from '@kbn/shared-ux-card-no-data-mocks'; import type { NoDataCardStorybookParams } from '@kbn/shared-ux-card-no-data-mocks'; -import { NoDataCard as Component } from './no_data_card.component'; -import { NoDataCard as ConnectedComponent } from './no_data_card'; +import { NoDataCard } from './no_data_card'; import { NoDataCardProvider } from './services'; import mdx from '../README.mdx'; @@ -28,21 +27,14 @@ export default { }; const mock = new NoDataCardStorybookMock(); - const argTypes = mock.getArgumentTypes(); -export const NoDataCard = (params: NoDataCardStorybookParams) => { +export const Card = (params: NoDataCardStorybookParams) => { return ( - + ); }; -NoDataCard.argTypes = argTypes; - -export const NoDataCardComponent = (params: NoDataCardStorybookParams) => { - return ; -}; - -NoDataCardComponent.argTypes = argTypes; +Card.argTypes = argTypes; diff --git a/packages/shared-ux/card/no_data/mocks/BUILD.bazel b/packages/shared-ux/card/no_data/mocks/BUILD.bazel index dbfc44a31b864f..3aec9c86207c9b 100644 --- a/packages/shared-ux/card/no_data/mocks/BUILD.bazel +++ b/packages/shared-ux/card/no_data/mocks/BUILD.bazel @@ -10,8 +10,17 @@ SOURCE_FILES = glob( "src/**/*.ts", ], exclude = [ + "**/*.config.js", + "**/*.mock.*", "**/*.test.*", "**/*.stories.*", + "**/__snapshots__", + "**/integration_tests", + "**/mocks", + "**/scripts", + "**/storybook", + "**/test_fixtures", + "**/test_helpers", ], ) @@ -39,6 +48,8 @@ NPM_MODULE_EXTRA_FILES = [ RUNTIME_DEPS = [ "@npm//@storybook/addon-actions", "@npm//deepmerge", + "@npm//lodash", + "@npm//react", "//packages/shared-ux/link/redirect_app/mocks", "//packages/shared-ux/storybook/mock", ] @@ -53,13 +64,15 @@ RUNTIME_DEPS = [ # # References to NPM packages work the same as RUNTIME_DEPS TYPES_DEPS = [ - "@npm//@types/node", - "@npm//@types/jest", "@npm//@storybook/addon-actions", + "@npm//@types/jest", + "@npm//@types/lodash", + "@npm//@types/node", + "@npm//@types/react", "@npm//deepmerge", - "//packages/shared-ux/storybook/mock:npm_module_types", - "//packages/shared-ux/link/redirect_app/mocks:npm_module_types", "//packages/shared-ux/card/no_data/types:npm_module_types", + "//packages/shared-ux/link/redirect_app/mocks:npm_module_types", + "//packages/shared-ux/storybook/mock:npm_module_types", ] jsts_transpiler( @@ -69,6 +82,14 @@ jsts_transpiler( root_input_dir = "src", ) +jsts_transpiler( + name = "target_web", + srcs = SRCS, + build_pkg_name = package_name(), + root_input_dir = "src", + web = True, +) + ts_config( name = "tsconfig", src = "tsconfig.json", @@ -94,7 +115,7 @@ ts_project( js_library( name = PKG_DIRNAME, srcs = NPM_MODULE_EXTRA_FILES, - deps = RUNTIME_DEPS + [":target_node"], + deps = RUNTIME_DEPS + [":target_node", ":target_web"], package_name = PKG_REQUIRE_NAME, visibility = ["//visibility:public"], ) diff --git a/packages/shared-ux/card/no_data/mocks/package.json b/packages/shared-ux/card/no_data/mocks/package.json index d9f12c7e81fcd6..10380b879954cd 100644 --- a/packages/shared-ux/card/no_data/mocks/package.json +++ b/packages/shared-ux/card/no_data/mocks/package.json @@ -3,5 +3,6 @@ "private": true, "version": "1.0.0", "main": "./target_node/index.js", + "browser": "./target_web/index.js", "license": "SSPL-1.0 OR Elastic License 2.0" } \ No newline at end of file diff --git a/packages/shared-ux/card/no_data/mocks/src/jest.ts b/packages/shared-ux/card/no_data/mocks/src/jest.ts index bf8ac47239bcf0..9a89d0cd3b7475 100644 --- a/packages/shared-ux/card/no_data/mocks/src/jest.ts +++ b/packages/shared-ux/card/no_data/mocks/src/jest.ts @@ -5,7 +5,10 @@ * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ + import deepmerge from 'deepmerge'; +import { isPlainObject } from 'lodash'; + import type { NoDataCardServices, NoDataCardKibanaDependencies, @@ -43,7 +46,7 @@ export const getKibanaDependenciesMock = ( const integrations = params.canAccessFleet !== undefined ? params.canAccessFleet : defaultParams.canAccessFleet; - return deepmerge( + const result = deepmerge( { coreStart: { http: { @@ -60,6 +63,11 @@ export const getKibanaDependenciesMock = ( }, }, }, - getRedirectAppLinksKibanaDependenciesMock() + getRedirectAppLinksKibanaDependenciesMock(), + { + isMergeableObject: isPlainObject, + } ); + + return result; }; diff --git a/packages/shared-ux/card/no_data/mocks/tsconfig.json b/packages/shared-ux/card/no_data/mocks/tsconfig.json index 894f01d3220e91..dc96ec41f9035d 100644 --- a/packages/shared-ux/card/no_data/mocks/tsconfig.json +++ b/packages/shared-ux/card/no_data/mocks/tsconfig.json @@ -9,10 +9,12 @@ "stripInternal": false, "types": [ "jest", - "node" + "node", + "react" ] }, "include": [ - "src/**/*" + "**/*.ts", + "**/*.tsx", ] } diff --git a/packages/shared-ux/link/redirect_app/impl/src/redirect_app_links.test.tsx b/packages/shared-ux/link/redirect_app/impl/src/redirect_app_links.test.tsx index 6342f9f6e1f6a5..56a6e1b4f74941 100644 --- a/packages/shared-ux/link/redirect_app/impl/src/redirect_app_links.test.tsx +++ b/packages/shared-ux/link/redirect_app/impl/src/redirect_app_links.test.tsx @@ -10,10 +10,14 @@ import React, { MouseEvent } from 'react'; import { mount as enzymeMount, ReactWrapper } from 'enzyme'; +import { + getRedirectAppLinksKibanaDependenciesMock, + getRedirectAppLinksServicesMock, +} from '@kbn/shared-ux-link-redirect-app-mocks'; + import { RedirectAppLinksKibanaProvider, RedirectAppLinksProvider } from './services'; import { RedirectAppLinks } from './redirect_app_links.container'; import { RedirectAppLinks as ComposedWrapper } from './redirect_app_links'; -import { Observable } from 'rxjs'; export type UnmountCallback = () => void; export type MountPoint = (element: T) => UnmountCallback; @@ -251,21 +255,8 @@ describe('RedirectAppLinks', () => { navigateToUrl.mockReset(); }); - const kibana = { - coreStart: { - application: { - currentAppId$: new Observable((subscriber) => { - subscriber.next('123'); - }), - navigateToUrl, - }, - }, - }; - - const services = { - currentAppId: 'abc123', - navigateToUrl, - }; + const kibana = getRedirectAppLinksKibanaDependenciesMock({ navigateToUrl }); + const services = getRedirectAppLinksServicesMock({ navigateToUrl }); const provider = (node: React.ReactElement) => enzymeMount({node}); diff --git a/packages/shared-ux/link/redirect_app/mocks/BUILD.bazel b/packages/shared-ux/link/redirect_app/mocks/BUILD.bazel index f0607a798c8331..2b28f97f2f639c 100644 --- a/packages/shared-ux/link/redirect_app/mocks/BUILD.bazel +++ b/packages/shared-ux/link/redirect_app/mocks/BUILD.bazel @@ -8,10 +8,20 @@ PKG_REQUIRE_NAME = "@kbn/shared-ux-link-redirect-app-mocks" SOURCE_FILES = glob( [ "src/**/*.ts", + "src/**/*.tsx", ], exclude = [ + "**/*.config.js", + "**/*.mock.*", "**/*.test.*", "**/*.stories.*", + "**/__snapshots__", + "**/integration_tests", + "**/mocks", + "**/scripts", + "**/storybook", + "**/test_fixtures", + "**/test_helpers", ], ) @@ -37,6 +47,7 @@ NPM_MODULE_EXTRA_FILES = [ # "@npm//name-of-package" # eg. "@npm//lodash" RUNTIME_DEPS = [ + "@npm//react", "@npm//@storybook/addon-actions", "@npm//rxjs", "//packages/shared-ux/storybook/mock", @@ -52,6 +63,9 @@ RUNTIME_DEPS = [ # # References to NPM packages work the same as RUNTIME_DEPS TYPES_DEPS = [ + "@npm//@types/node", + "@npm//@types/jest", + "@npm//@types/react", "@npm//@storybook/addon-actions", "@npm//rxjs", "//packages/shared-ux/link/redirect_app/types", @@ -65,6 +79,14 @@ jsts_transpiler( root_input_dir = "src", ) +jsts_transpiler( + name = "target_web", + srcs = SRCS, + build_pkg_name = package_name(), + root_input_dir = "src", + web = True, +) + ts_config( name = "tsconfig", src = "tsconfig.json", @@ -90,7 +112,7 @@ ts_project( js_library( name = PKG_DIRNAME, srcs = NPM_MODULE_EXTRA_FILES, - deps = RUNTIME_DEPS + [":target_node"], + deps = RUNTIME_DEPS + [":target_node", ":target_web"], package_name = PKG_REQUIRE_NAME, visibility = ["//visibility:public"], ) diff --git a/packages/shared-ux/link/redirect_app/mocks/jest.config.js b/packages/shared-ux/link/redirect_app/mocks/jest.config.js index 6f1b6fd89f35e9..ac5f8e5dcf92ff 100644 --- a/packages/shared-ux/link/redirect_app/mocks/jest.config.js +++ b/packages/shared-ux/link/redirect_app/mocks/jest.config.js @@ -7,7 +7,7 @@ */ module.exports = { - preset: '@kbn/test/jest_node', + preset: '@kbn/test', rootDir: '../../../../..', roots: ['/packages/shared-ux/link/redirect_app/mocks'], }; diff --git a/packages/shared-ux/link/redirect_app/mocks/package.json b/packages/shared-ux/link/redirect_app/mocks/package.json index 2281680755a9c2..adf441fb3d1347 100644 --- a/packages/shared-ux/link/redirect_app/mocks/package.json +++ b/packages/shared-ux/link/redirect_app/mocks/package.json @@ -3,5 +3,6 @@ "private": true, "version": "1.0.0", "main": "./target_node/index.js", + "browser": "./target_web/index.js", "license": "SSPL-1.0 OR Elastic License 2.0" -} \ No newline at end of file +} diff --git a/packages/shared-ux/link/redirect_app/mocks/src/jest.ts b/packages/shared-ux/link/redirect_app/mocks/src/jest.ts index 57e6650d17752d..1af5aa6e72a115 100644 --- a/packages/shared-ux/link/redirect_app/mocks/src/jest.ts +++ b/packages/shared-ux/link/redirect_app/mocks/src/jest.ts @@ -6,31 +6,53 @@ * Side Public License, v 1. */ -import { Subject } from 'rxjs'; +import { Observable } from 'rxjs'; import { RedirectAppLinksServices, RedirectAppLinksKibanaDependencies, } from '@kbn/shared-ux-link-redirect-app-types'; +type Params = Pick; + +const defaultParams: Params = { + navigateToUrl: jest.fn(), +}; + /** * Returns the Jest-compatible service abstractions for the `NoDataCard` Provider. */ -export const getRedirectAppLinksServicesMock = () => { +export const getRedirectAppLinksServicesMock = ( + params?: Partial +): RedirectAppLinksServices => { + const navigateToUrl = + params && params.navigateToUrl !== undefined + ? params.navigateToUrl + : defaultParams.navigateToUrl; + const services: RedirectAppLinksServices = { - navigateToUrl: jest.fn(), + navigateToUrl, currentAppId: 'currentAppId', }; return services; }; -export const getRedirectAppLinksKibanaDependenciesMock = (): RedirectAppLinksKibanaDependencies => { +export const getRedirectAppLinksKibanaDependenciesMock = ( + params?: Partial +): RedirectAppLinksKibanaDependencies => { + const navigateToUrl = + params && params.navigateToUrl !== undefined + ? params.navigateToUrl + : defaultParams.navigateToUrl; + return { coreStart: { application: { - currentAppId$: new Subject(), - navigateToUrl: jest.fn(), + currentAppId$: new Observable((subscriber) => { + subscriber.next('currentAppId'); + }), + navigateToUrl, }, }, }; diff --git a/packages/shared-ux/link/redirect_app/mocks/tsconfig.json b/packages/shared-ux/link/redirect_app/mocks/tsconfig.json index 041c59b490ec09..dc96ec41f9035d 100644 --- a/packages/shared-ux/link/redirect_app/mocks/tsconfig.json +++ b/packages/shared-ux/link/redirect_app/mocks/tsconfig.json @@ -10,9 +10,11 @@ "types": [ "jest", "node", + "react" ] }, "include": [ - "src/**/*" + "**/*.ts", + "**/*.tsx", ] } diff --git a/packages/shared-ux/page/analytics_no_data/impl/src/analytics_no_data_page.stories.tsx b/packages/shared-ux/page/analytics_no_data/impl/src/analytics_no_data_page.stories.tsx index 0e6a4261c8c2d6..5c9c5923bfdc65 100644 --- a/packages/shared-ux/page/analytics_no_data/impl/src/analytics_no_data_page.stories.tsx +++ b/packages/shared-ux/page/analytics_no_data/impl/src/analytics_no_data_page.stories.tsx @@ -7,7 +7,6 @@ */ import React from 'react'; -import { action } from '@storybook/addon-actions'; import { AnalyticsNoDataPageStorybookMock } from '@kbn/shared-ux-page-analytics-no-data-mocks'; import type { AnalyticsNoDataPageStorybookParams } from '@kbn/shared-ux-page-analytics-no-data-mocks'; @@ -18,7 +17,7 @@ import mdx from '../README.mdx'; const mock = new AnalyticsNoDataPageStorybookMock(); export default { - title: 'No Data/Analytics Page', + title: 'No Data/Page/Kibana', description: 'An Analytics-specific version of KibanaNoDataPage.', parameters: { docs: { @@ -27,7 +26,7 @@ export default { }, }; -export const AnalyticsNoDataPage = (params: AnalyticsNoDataPageStorybookParams) => { +export const Analytics = (params: AnalyticsNoDataPageStorybookParams) => { return ( @@ -35,22 +34,4 @@ export const AnalyticsNoDataPage = (params: AnalyticsNoDataPageStorybookParams) ); }; -AnalyticsNoDataPage.argTypes = mock.getArgumentTypes(); - -export const LoadingState = (params: AnalyticsNoDataPageStorybookParams) => { - // Simulate loading with a Promise that doesn't resolve. - const dataCheck = () => new Promise((_reject, _resolve) => {}); - - const services = { - ...mock.getServices(params), - hasESData: dataCheck, - hasUserDataView: dataCheck, - hasDataView: dataCheck, - }; - - return ( - - - - ); -}; +Analytics.argTypes = mock.getArgumentTypes(); diff --git a/packages/shared-ux/page/analytics_no_data/mocks/BUILD.bazel b/packages/shared-ux/page/analytics_no_data/mocks/BUILD.bazel index 6d78e72892bfc7..1600004860f88a 100644 --- a/packages/shared-ux/page/analytics_no_data/mocks/BUILD.bazel +++ b/packages/shared-ux/page/analytics_no_data/mocks/BUILD.bazel @@ -10,8 +10,17 @@ SOURCE_FILES = glob( "src/**/*.ts", ], exclude = [ + "**/*.config.js", + "**/*.mock.*", "**/*.test.*", "**/*.stories.*", + "**/__snapshots__", + "**/integration_tests", + "**/mocks", + "**/scripts", + "**/storybook", + "**/test_fixtures", + "**/test_helpers", ], ) @@ -37,7 +46,9 @@ NPM_MODULE_EXTRA_FILES = [ # "@npm//name-of-package" # eg. "@npm//lodash" RUNTIME_DEPS = [ + "@npm//react", "//packages/shared-ux/page/kibana_no_data/mocks", + "//packages/shared-ux/storybook/mock", ] # In this array place dependencies necessary to build the types, which will include the @@ -50,10 +61,12 @@ RUNTIME_DEPS = [ # # References to NPM packages work the same as RUNTIME_DEPS TYPES_DEPS = [ - "@npm//@types/node", "@npm//@types/jest", + "@npm//@types/node", + "@npm//@types/react", "//packages/shared-ux/page/analytics_no_data/types:npm_module_types", "//packages/shared-ux/page/kibana_no_data/mocks:npm_module_types", + "//packages/shared-ux/storybook/mock:npm_module_types", ] jsts_transpiler( @@ -63,6 +76,14 @@ jsts_transpiler( root_input_dir = "src", ) +jsts_transpiler( + name = "target_web", + srcs = SRCS, + build_pkg_name = package_name(), + root_input_dir = "src", + web = True, +) + ts_config( name = "tsconfig", src = "tsconfig.json", @@ -88,7 +109,7 @@ ts_project( js_library( name = PKG_DIRNAME, srcs = NPM_MODULE_EXTRA_FILES, - deps = RUNTIME_DEPS + [":target_node"], + deps = RUNTIME_DEPS + [":target_node", ":target_web"], package_name = PKG_REQUIRE_NAME, visibility = ["//visibility:public"], ) diff --git a/packages/shared-ux/page/analytics_no_data/mocks/package.json b/packages/shared-ux/page/analytics_no_data/mocks/package.json index 30850ab7355abb..6fc9704e831f11 100644 --- a/packages/shared-ux/page/analytics_no_data/mocks/package.json +++ b/packages/shared-ux/page/analytics_no_data/mocks/package.json @@ -3,5 +3,6 @@ "private": true, "version": "1.0.0", "main": "./target_node/index.js", + "browser": "./target_web/index.js", "license": "SSPL-1.0 OR Elastic License 2.0" } \ No newline at end of file diff --git a/packages/shared-ux/page/analytics_no_data/mocks/tsconfig.json b/packages/shared-ux/page/analytics_no_data/mocks/tsconfig.json index 894f01d3220e91..dc96ec41f9035d 100644 --- a/packages/shared-ux/page/analytics_no_data/mocks/tsconfig.json +++ b/packages/shared-ux/page/analytics_no_data/mocks/tsconfig.json @@ -9,10 +9,12 @@ "stripInternal": false, "types": [ "jest", - "node" + "node", + "react" ] }, "include": [ - "src/**/*" + "**/*.ts", + "**/*.tsx", ] } diff --git a/packages/shared-ux/page/kibana_no_data/impl/BUILD.bazel b/packages/shared-ux/page/kibana_no_data/impl/BUILD.bazel index 2fc986d65c1a46..7b1e16f9db829c 100644 --- a/packages/shared-ux/page/kibana_no_data/impl/BUILD.bazel +++ b/packages/shared-ux/page/kibana_no_data/impl/BUILD.bazel @@ -44,9 +44,8 @@ RUNTIME_DEPS = [ "@npm//@emotion/react", "@npm//react", "//packages/kbn-i18n", - "//packages/kbn-shared-ux-components", - "//packages/kbn-shared-ux-services", "//packages/shared-ux/prompt/no_data_views/impl", + "//packages/shared-ux/page/no_data_config/impl", ] # In this array place dependencies necessary to build the types, which will include the @@ -67,10 +66,10 @@ TYPES_DEPS = [ "@npm//@types/react", "//packages/kbn-ambient-ui-types", "//packages/kbn-i18n:npm_module_types", - "//packages/kbn-shared-ux-components:npm_module_types", - "//packages/kbn-shared-ux-services:npm_module_types", "//packages/shared-ux/prompt/no_data_views/impl:npm_module_types", - "//packages/shared-ux/page/kibana_no_data/types:npm_module_types", + "//packages/shared-ux/page/no_data_config/impl:npm_module_types", + "//packages/shared-ux/page/no_data_config/types", + "//packages/shared-ux/page/kibana_no_data/types", ] jsts_transpiler( diff --git a/packages/shared-ux/page/kibana_no_data/impl/README.mdx b/packages/shared-ux/page/kibana_no_data/impl/README.mdx index bc5dc37ac679a4..f74adf2465e3bb 100644 --- a/packages/shared-ux/page/kibana_no_data/impl/README.mdx +++ b/packages/shared-ux/page/kibana_no_data/impl/README.mdx @@ -14,7 +14,7 @@ The `KibanaNoDataPage` connected component uses: - `hasUserDataView` and `hasData` API from the `HasData` service in the `data_views` plugin to check for existence of data an data views. - `onDataViewCreated` callback once a data view has been created. -- (noDataConfig)[https://github.com/elastic/kibana/blob/main/packages/kbn-shared-ux-components/src/page_template/no_data_page/types.ts] as configuration for the page in case of no data. +- (noDataConfig)[https://github.com/elastic/kibana/blob/main/packages/shared-ux/page/no_data/types/index.d.ts] as configuration for the page in case of no data. ## API diff --git a/packages/shared-ux/page/kibana_no_data/impl/src/kibana_no_data_page.stories.tsx b/packages/shared-ux/page/kibana_no_data/impl/src/kibana_no_data_page.stories.tsx index f38b079dffec7c..60cc78d95215c6 100644 --- a/packages/shared-ux/page/kibana_no_data/impl/src/kibana_no_data_page.stories.tsx +++ b/packages/shared-ux/page/kibana_no_data/impl/src/kibana_no_data_page.stories.tsx @@ -17,7 +17,7 @@ import { KibanaNoDataPageProvider } from './services'; import mdx from '../README.mdx'; export default { - title: 'No Data/Kibana Page', + title: 'No Data/Page/Kibana', description: 'A component to display when there is no data available', parameters: { docs: { @@ -28,7 +28,7 @@ export default { const mock = new KibanaNoDataPageStorybookMock(); -export const KibanaNoDataPage = (params: KibanaNoDataPageStorybookParams) => { +export const Kibana = (params: KibanaNoDataPageStorybookParams) => { return ( @@ -36,7 +36,7 @@ export const KibanaNoDataPage = (params: KibanaNoDataPageStorybookParams) => { ); }; -KibanaNoDataPage.argTypes = mock.getArgumentTypes(); +Kibana.argTypes = mock.getArgumentTypes(); export const LoadingState = (params: KibanaNoDataPageStorybookParams) => { // Simulate loading with a Promise that doesn't resolve. diff --git a/packages/shared-ux/page/kibana_no_data/impl/src/kibana_no_data_page.test.tsx b/packages/shared-ux/page/kibana_no_data/impl/src/kibana_no_data_page.test.tsx index 7a0e0cd7e4f002..c15a5c061dd1ba 100644 --- a/packages/shared-ux/page/kibana_no_data/impl/src/kibana_no_data_page.test.tsx +++ b/packages/shared-ux/page/kibana_no_data/impl/src/kibana_no_data_page.test.tsx @@ -12,7 +12,7 @@ import { act } from 'react-dom/test-utils'; import { EuiLoadingElastic } from '@elastic/eui'; import { mountWithIntl } from '@kbn/test-jest-helpers'; import { NoDataViewsPrompt } from '@kbn/shared-ux-prompt-no-data-views'; -import { NoDataConfigPage } from '@kbn/shared-ux-components'; +import { NoDataConfigPage } from '@kbn/shared-ux-page-no-data-config'; import { getKibanaNoDataPageServicesMock } from '@kbn/shared-ux-page-kibana-no-data-mocks'; import { KibanaNoDataPage } from './kibana_no_data_page'; @@ -43,7 +43,7 @@ describe('Kibana No Data Page', () => { }); test('renders NoDataConfigPage', async () => { - const services = getKibanaNoDataPageServicesMock({ config: { ...config, hasESData: false } }); + const services = getKibanaNoDataPageServicesMock(config); const component = mountWithIntl( @@ -58,7 +58,7 @@ describe('Kibana No Data Page', () => { }); test('renders NoDataViews', async () => { - const services = getKibanaNoDataPageServicesMock({ config: { ...config, hasESData: true } }); + const services = getKibanaNoDataPageServicesMock({ ...config, hasESData: true }); const component = mountWithIntl( diff --git a/packages/shared-ux/page/kibana_no_data/impl/src/kibana_no_data_page.tsx b/packages/shared-ux/page/kibana_no_data/impl/src/kibana_no_data_page.tsx index f2ac573232f340..73726d7b82eaa0 100644 --- a/packages/shared-ux/page/kibana_no_data/impl/src/kibana_no_data_page.tsx +++ b/packages/shared-ux/page/kibana_no_data/impl/src/kibana_no_data_page.tsx @@ -7,7 +7,7 @@ */ import React, { useEffect, useState } from 'react'; import { EuiLoadingElastic } from '@elastic/eui'; -import { NoDataConfigPage } from '@kbn/shared-ux-components'; +import { NoDataConfigPage } from '@kbn/shared-ux-page-no-data-config'; import { NoDataViewsPrompt } from '@kbn/shared-ux-prompt-no-data-views'; import { KibanaNoDataPageProps } from '@kbn/shared-ux-page-kibana-no-data-types'; diff --git a/packages/shared-ux/page/kibana_no_data/impl/src/legacy_services.tsx b/packages/shared-ux/page/kibana_no_data/impl/src/legacy_services.tsx deleted file mode 100644 index 2a9580bb746844..00000000000000 --- a/packages/shared-ux/page/kibana_no_data/impl/src/legacy_services.tsx +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -export { SharedUxServicesProvider as LegacyServicesProvider } from '@kbn/shared-ux-services'; -export type { SharedUxServices as LegacyServices } from '@kbn/shared-ux-services'; - -import { SharedUxServices as LegacyServices } from '@kbn/shared-ux-services'; -import type { KibanaNoDataPageServices } from '@kbn/shared-ux-page-kibana-no-data-types'; - -/** - * This list is temporary, a stop-gap as we migrate to a package-based architecture, where - * services are not collected in a single package. In order to make the transition, this - * interface is intentionally "flat". - * - * Expect this list to dwindle to zero as `@kbn/shared-ux-components` are migrated to their - * own packages, (and `@kbn/shared-ux-services` is removed). - */ -export const getLegacyServices = (services: KibanaNoDataPageServices): LegacyServices => ({ - application: { - currentAppId$: services.currentAppId$, - navigateToUrl: services.navigateToUrl, - }, - data: { - hasESData: services.hasESData, - hasDataView: services.hasDataView, - hasUserDataView: services.hasUserDataView, - }, - docLinks: { - dataViewsDocLink: services.dataViewsDocLink, - }, - editors: { - openDataViewEditor: services.openDataViewEditor, - }, - http: { - addBasePath: services.addBasePath, - }, - permissions: { - canAccessFleet: services.canAccessFleet, - canCreateNewDataView: services.canCreateNewDataView, - }, - platform: { - setIsFullscreen: services.setIsFullscreen, - }, -}); diff --git a/packages/shared-ux/page/kibana_no_data/impl/src/services.tsx b/packages/shared-ux/page/kibana_no_data/impl/src/services.tsx index 0aab90ce9f5046..3ebab02d637902 100644 --- a/packages/shared-ux/page/kibana_no_data/impl/src/services.tsx +++ b/packages/shared-ux/page/kibana_no_data/impl/src/services.tsx @@ -15,13 +15,12 @@ import { import { NoDataCardProvider, NoDataCardKibanaProvider } from '@kbn/shared-ux-card-no-data'; import { + Services, KibanaNoDataPageServices, KibanaNoDataPageKibanaDependencies, } from '@kbn/shared-ux-page-kibana-no-data-types'; -import { LegacyServicesProvider, getLegacyServices } from './legacy_services'; - -const KibanaNoDataPageContext = React.createContext(null); +const KibanaNoDataPageContext = React.createContext(null); /** * A Context Provider that provides services to the component. @@ -29,15 +28,17 @@ const KibanaNoDataPageContext = React.createContext = ({ children, ...services -}) => ( - - - - {children} - - - -); +}) => { + const { hasESData, hasUserDataView } = services; + + return ( + + + {children} + + + ); +}; /** * Kibana-specific Provider that maps dependencies to services. @@ -46,27 +47,16 @@ export const KibanaNoDataPageKibanaProvider: FC { - const { coreStart, dataViewEditor, dataViews } = dependencies; - const value: KibanaNoDataPageServices = { - addBasePath: coreStart.http.basePath.prepend, - canAccessFleet: coreStart.application.capabilities.navLinks.integrations, - canCreateNewDataView: dataViewEditor.userPermissions.editDataView(), - currentAppId$: coreStart.application.currentAppId$, - dataViewsDocLink: coreStart.docLinks.links.indexPatterns?.introduction, - hasDataView: dataViews.hasData.hasDataView, + const { dataViews } = dependencies; + const value: Services = { hasESData: dataViews.hasData.hasESData, hasUserDataView: dataViews.hasData.hasUserDataView, - navigateToUrl: coreStart.application.navigateToUrl, - openDataViewEditor: dataViewEditor.openEditor, - setIsFullscreen: (isVisible: boolean) => coreStart.chrome.setIsVisible(isVisible), }; return ( - - {children} - + {children} ); diff --git a/packages/shared-ux/page/kibana_no_data/mocks/BUILD.bazel b/packages/shared-ux/page/kibana_no_data/mocks/BUILD.bazel index 2c195edb6de034..7f8c4c03fc92df 100644 --- a/packages/shared-ux/page/kibana_no_data/mocks/BUILD.bazel +++ b/packages/shared-ux/page/kibana_no_data/mocks/BUILD.bazel @@ -10,8 +10,17 @@ SOURCE_FILES = glob( "src/**/*.ts", ], exclude = [ + "**/*.config.js", + "**/*.mock.*", "**/*.test.*", "**/*.stories.*", + "**/__snapshots__", + "**/integration_tests", + "**/mocks", + "**/scripts", + "**/storybook", + "**/test_fixtures", + "**/test_helpers", ], ) @@ -37,8 +46,10 @@ NPM_MODULE_EXTRA_FILES = [ # "@npm//name-of-package" # eg. "@npm//lodash" RUNTIME_DEPS = [ - "//packages/shared-ux/prompt/no_data_views/mocks", + "@npm//react", "//packages/shared-ux/card/no_data/mocks", + "//packages/shared-ux/prompt/no_data_views/mocks", + "//packages/shared-ux/storybook/mock", ] # In this array place dependencies necessary to build the types, which will include the @@ -51,12 +62,14 @@ RUNTIME_DEPS = [ # # References to NPM packages work the same as RUNTIME_DEPS TYPES_DEPS = [ - "@npm//@types/node", "@npm//@types/jest", + "@npm//@types/node", + "@npm//@types/react", + "//packages/shared-ux/card/no_data/mocks:npm_module_types", "//packages/shared-ux/page/kibana_no_data/types:npm_module_types", - "//packages/kbn-shared-ux-components:npm_module_types", + "//packages/shared-ux/page/no_data/types", "//packages/shared-ux/prompt/no_data_views/mocks:npm_module_types", - "//packages/shared-ux/card/no_data/mocks:npm_module_types", + "//packages/shared-ux/storybook/mock:npm_module_types", ] jsts_transpiler( @@ -66,6 +79,14 @@ jsts_transpiler( root_input_dir = "src", ) +jsts_transpiler( + name = "target_web", + srcs = SRCS, + build_pkg_name = package_name(), + root_input_dir = "src", + web = True, +) + ts_config( name = "tsconfig", src = "tsconfig.json", @@ -91,7 +112,7 @@ ts_project( js_library( name = PKG_DIRNAME, srcs = NPM_MODULE_EXTRA_FILES, - deps = RUNTIME_DEPS + [":target_node"], + deps = RUNTIME_DEPS + [":target_node", ":target_web"], package_name = PKG_REQUIRE_NAME, visibility = ["//visibility:public"], ) diff --git a/packages/shared-ux/page/kibana_no_data/mocks/jest.config.js b/packages/shared-ux/page/kibana_no_data/mocks/jest.config.js deleted file mode 100644 index 4c71cbdc32e916..00000000000000 --- a/packages/shared-ux/page/kibana_no_data/mocks/jest.config.js +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -module.exports = { - preset: '@kbn/test/jest_node', - rootDir: '../../../../..', - roots: ['/packages/shared-ux/page/kibana_no_data/mocks'], -}; diff --git a/packages/shared-ux/page/kibana_no_data/mocks/package.json b/packages/shared-ux/page/kibana_no_data/mocks/package.json index 988bdc1d33acad..f134da02e430f8 100644 --- a/packages/shared-ux/page/kibana_no_data/mocks/package.json +++ b/packages/shared-ux/page/kibana_no_data/mocks/package.json @@ -3,5 +3,6 @@ "private": true, "version": "1.0.0", "main": "./target_node/index.js", + "browser": "./target_web/index.js", "license": "SSPL-1.0 OR Elastic License 2.0" -} +} \ No newline at end of file diff --git a/packages/shared-ux/page/kibana_no_data/mocks/src/jest.ts b/packages/shared-ux/page/kibana_no_data/mocks/src/jest.ts index 33f26bafbd33dc..5f2f6b309e56c2 100644 --- a/packages/shared-ux/page/kibana_no_data/mocks/src/jest.ts +++ b/packages/shared-ux/page/kibana_no_data/mocks/src/jest.ts @@ -9,33 +9,34 @@ import { getNoDataCardServicesMock } from '@kbn/shared-ux-card-no-data-mocks'; import { KibanaNoDataPageServices } from '@kbn/shared-ux-page-kibana-no-data-types'; import { getNoDataViewsPromptServicesMock } from '@kbn/shared-ux-prompt-no-data-views-mocks'; -import { mockServicesFactory, MockServicesFactoryParams } from '@kbn/shared-ux-services'; + +interface Params { + hasESData: boolean; + hasUserDataView: boolean; +} + +const defaultParams = { + hasESData: true, + hasUserDataView: true, +}; /** * Returns the Jest-compatible service abstractions for the `KibanaNoDataPage` Provider. */ -export const getServicesMock = (params?: MockServicesFactoryParams) => { - const { canCreateNewDataView, dataViewsDocLink, openDataViewEditor } = - getNoDataViewsPromptServicesMock(); - - const { addBasePath, canAccessFleet } = getNoDataCardServicesMock(); +export const getServicesMock = (params?: Partial) => { + const hasESData = + params && params.hasESData !== undefined ? params.hasESData : defaultParams.hasESData; - const { application, data, docLinks, editors, http, permissions, platform } = - mockServicesFactory(params); + const hasUserDataView = + params && params.hasUserDataView !== undefined + ? params.hasUserDataView + : defaultParams.hasUserDataView; const services: KibanaNoDataPageServices = { - ...application, - ...data, - ...docLinks, - ...editors, - ...http, - ...permissions, - ...platform, - canCreateNewDataView, - dataViewsDocLink, - openDataViewEditor, - addBasePath, - canAccessFleet, + ...getNoDataCardServicesMock(), + ...getNoDataViewsPromptServicesMock(), + hasESData: async () => hasESData, + hasUserDataView: async () => hasUserDataView, }; return services; diff --git a/packages/shared-ux/page/kibana_no_data/mocks/src/storybook.ts b/packages/shared-ux/page/kibana_no_data/mocks/src/storybook.ts index 32dcdfe4865801..1f4a7453e59b6b 100644 --- a/packages/shared-ux/page/kibana_no_data/mocks/src/storybook.ts +++ b/packages/shared-ux/page/kibana_no_data/mocks/src/storybook.ts @@ -6,13 +6,14 @@ * Side Public License, v 1. */ -import { servicesFactory } from '@kbn/shared-ux-storybook'; +import { action } from '@storybook/addon-actions'; + import { AbstractStorybookMock, ArgumentParams } from '@kbn/shared-ux-storybook-mock'; import type { KibanaNoDataPageServices, KibanaNoDataPageProps, } from '@kbn/shared-ux-page-kibana-no-data-types'; -import type { NoDataPageProps } from '@kbn/shared-ux-components'; +import type { NoDataPageProps } from '@kbn/shared-ux-page-no-data-types'; import { NoDataViewsPromptStorybookMock, @@ -23,7 +24,6 @@ import { NoDataCardStorybookMock, NoDataCardStorybookParams, } from '@kbn/shared-ux-card-no-data-mocks'; -import { action } from '@storybook/addon-actions'; type PropArguments = Pick; type ServiceArguments = Pick; @@ -83,22 +83,11 @@ export class StorybookMock extends AbstractStorybookMock< } getServices(params: Params): KibanaNoDataPageServices { - // Workaround to leverage the services package. - const { application, data, docLinks, editors, http, permissions, platform } = - servicesFactory(params); - return { - ...application, - ...data, - ...docLinks, - ...editors, - ...http, - ...permissions, - ...platform, - hasESData: () => params.hasESData, - hasUserDataView: () => params.hasUserDataView, ...noDataCardMock.getServices(params), ...noDataViewsMock.getServices(params), + hasESData: () => params.hasESData, + hasUserDataView: () => params.hasUserDataView, }; } } diff --git a/packages/shared-ux/page/kibana_no_data/mocks/tsconfig.json b/packages/shared-ux/page/kibana_no_data/mocks/tsconfig.json index 894f01d3220e91..dc96ec41f9035d 100644 --- a/packages/shared-ux/page/kibana_no_data/mocks/tsconfig.json +++ b/packages/shared-ux/page/kibana_no_data/mocks/tsconfig.json @@ -9,10 +9,12 @@ "stripInternal": false, "types": [ "jest", - "node" + "node", + "react" ] }, "include": [ - "src/**/*" + "**/*.ts", + "**/*.tsx", ] } diff --git a/packages/shared-ux/page/kibana_no_data/types/index.d.ts b/packages/shared-ux/page/kibana_no_data/types/index.d.ts index cfa1da12ccedfb..18fe5499e93c39 100644 --- a/packages/shared-ux/page/kibana_no_data/types/index.d.ts +++ b/packages/shared-ux/page/kibana_no_data/types/index.d.ts @@ -6,109 +6,44 @@ * Side Public License, v 1. */ -import { Observable } from 'rxjs'; -import { NoDataPageProps } from '@kbn/shared-ux-components'; +import { NoDataPageProps } from '@kbn/shared-ux-page-no-data-types'; -/** - * TODO: `DataView` is a class exported by `src/plugins/data_views/public`. Since this service - * is contained in this package-- and packages can only depend on other packages and never on - * plugins-- we have to set this to `unknown`. If and when `DataView` is exported from a - * stateless package, we can remove this. - * - * @see: https://github.com/elastic/kibana/issues/127695 - */ -type DataView = unknown; - -/** - * A subset of the `DataViewEditorOptions` interface relevant to this component. - * - * @see: src/plugins/data_view_editor/public/types.ts - */ -interface DataViewEditorOptions { - /** Handler to be invoked when the Data View Editor completes a save operation. */ - onSave: (dataView: DataView) => void; -} +import { + NoDataViewsPromptServices, + NoDataViewsPromptKibanaDependencies, +} from '@kbn/shared-ux-prompt-no-data-views-types'; +import { + NoDataCardServices, + NoDataCardKibanaDependencies, +} from '@kbn/shared-ux-card-no-data-types'; -/** - * A list of Services that are consumed by this component. - * - * This list is temporary, a stopgap as we migrate to a package-based architecture, where - * services are not collected in a single package. In order to make the transition, this - * interface is intentionally "flat". - * - * Expect this list to dwindle to zero as `@kbn/shared-ux-components` are migrated to their - * own packages, (and `@kbn/shared-ux-services` is removed). - */ -export interface KibanaNoDataPageServices { +export interface Services { /** True if the cluster contains data, false otherwise. */ hasESData: () => Promise; /** True if Kibana instance contains user-created data view, false otherwise. */ hasUserDataView: () => Promise; - - // Provided to Legacy Services, not relevant to this component. Will be removed. - /** Append the server base path to a relative URL. */ - addBasePath: (url: string) => string; - /** True if the user has permission to access Fleet, false otherwise. */ - canAccessFleet: boolean; - /** True if the user has permission to create a new Data View, false otherwise. */ - canCreateNewDataView: boolean; - /** Observable storing the active, current application ID. */ - currentAppId$: Observable; - /** A link to information about Data Views in Kibana */ - dataViewsDocLink: string; - /** True if Kibana instance contains any data view, including system-created ones. */ - hasDataView: () => Promise; - /** Use Kibana to navigate async to a different URL. */ - navigateToUrl: (url: string) => Promise | void; - /** A method to open the Data View Editor flow. */ - openDataViewEditor: (options: DataViewEditorOptions) => () => void; - /** Set the Kibana chrome and browser to full screen mode. */ - setIsFullscreen: (isFullscreen: boolean) => void; } /** - * An interface containing a collection of Kibana plugins and services required to - * render this component and its dependencies. + * A list of Services that are consumed by this component.. */ -export interface KibanaNoDataPageKibanaDependencies { - coreStart: { - application: { - capabilities: { - navLinks: Record; - }; - currentAppId$: Observable; - navigateToUrl: (url: string) => Promise; - }; - chrome: { - setIsVisible: (isVisible: boolean) => void; - }; - docLinks: { - links: { - indexPatterns: { - introduction: string; - }; - }; - }; - http: { - basePath: { - prepend: (url: string) => string; - }; - }; - }; +export type KibanaNoDataPageServices = Services & NoDataCardServices & NoDataViewsPromptServices; + +export interface KibanaDependencies { dataViews: { hasData: { - hasDataView: () => Promise; hasESData: () => Promise; hasUserDataView: () => Promise; }; }; - dataViewEditor: { - openEditor: (options: DataViewEditorOptions) => () => void; - userPermissions: { - editDataView: () => boolean; - }; - }; } +/** + * An interface containing a collection of Kibana plugins and services required to + * render this component and its dependencies. + */ +export type KibanaNoDataPageKibanaDependencies = KibanaDependencies & + NoDataViewsPromptKibanaDependencies & + NoDataCardKibanaDependencies; /** * Props for `KibanaNoDataPage`. diff --git a/packages/kbn-shared-ux-services/BUILD.bazel b/packages/shared-ux/page/kibana_template/impl/BUILD.bazel old mode 100755 new mode 100644 similarity index 86% rename from packages/kbn-shared-ux-services/BUILD.bazel rename to packages/shared-ux/page/kibana_template/impl/BUILD.bazel index 1ed65b979a3e39..8e27df56eadf2f --- a/packages/kbn-shared-ux-services/BUILD.bazel +++ b/packages/shared-ux/page/kibana_template/impl/BUILD.bazel @@ -2,16 +2,18 @@ load("@npm//@bazel/typescript:index.bzl", "ts_config") load("@build_bazel_rules_nodejs//:index.bzl", "js_library") load("//src/dev/bazel:index.bzl", "jsts_transpiler", "pkg_npm", "pkg_npm_types", "ts_project") -PKG_DIRNAME = "kbn-shared-ux-services" -PKG_REQUIRE_NAME = "@kbn/shared-ux-services" +PKG_DIRNAME = "impl" +PKG_REQUIRE_NAME = "@kbn/shared-ux-page-kibana-template" SOURCE_FILES = glob( [ "src/**/*.ts", "src/**/*.tsx", + "src/**/*.mdx", ], exclude = [ "**/*.test.*", + "**/*.stories.*", ], ) @@ -38,7 +40,7 @@ NPM_MODULE_EXTRA_FILES = [ # eg. "@npm//lodash" RUNTIME_DEPS = [ "@npm//react", - "@npm//rxjs", + "//packages/shared-ux/page/no_data_config/impl", ] # In this array place dependencies necessary to build the types, which will include the @@ -54,7 +56,9 @@ TYPES_DEPS = [ "@npm//@types/node", "@npm//@types/jest", "@npm//@types/react", - "@npm//rxjs", + "//packages/shared-ux/page/no_data_config/impl:npm_module_types", + "//packages/shared-ux/page/kibana_template/types", + "//packages/kbn-ambient-ui-types", ] jsts_transpiler( @@ -70,6 +74,10 @@ jsts_transpiler( build_pkg_name = package_name(), root_input_dir = "src", web = True, + additional_args = [ + "--copy-files", + "--quiet" + ], ) ts_config( diff --git a/packages/kbn-shared-ux-components/src/page_template/page_template.mdx b/packages/shared-ux/page/kibana_template/impl/README.mdx similarity index 97% rename from packages/kbn-shared-ux-components/src/page_template/page_template.mdx rename to packages/shared-ux/page/kibana_template/impl/README.mdx index fbaada158e2773..6d8151cbe882c2 100644 --- a/packages/kbn-shared-ux-components/src/page_template/page_template.mdx +++ b/packages/shared-ux/page/kibana_template/impl/README.mdx @@ -1,6 +1,6 @@ --- id: sharedUX/Components/PageTemplate -slug: /shared-ux-components/page_template/page_template +slug: /shared-ux/page_template title: Page Template description: A Kibana-specific wrapper around `EuiTemplate` tags: ['shared-ux', 'component'] @@ -124,7 +124,7 @@ Increases the consistency in messaging across all the solutions during the getti This is a built-in configuration that displays a very specific UI and requires very specific keys. It will also ignore all other configurations of the template including `pageHeader` and `children`, with the exception of continuing to show `solutionNav`. -The `noDataConfig` is of type [`NoDataPageProps`](https://github.com/elastic/kibana/blob/main/packages/kbn-shared-ux-components/src/page_template/no_data_page/types.ts#L14): +The `noDataConfig` is of type [`NoDataPageProps`](https://github.com/elastic/kibana/blob/main/packages/shared-ux/page/no_data/types/index.d.ts): 1. `solution: string`: Single name for the current solution, used to auto-generate the title, logo, and description *(required)* 2. `docsLink: string`: Required to set the docs link for the whole solution *(required)* diff --git a/packages/shared-ux/card/no_data/mocks/jest.config.js b/packages/shared-ux/page/kibana_template/impl/jest.config.js similarity index 81% rename from packages/shared-ux/card/no_data/mocks/jest.config.js rename to packages/shared-ux/page/kibana_template/impl/jest.config.js index 2c7697ab74eb80..103defe0f0ca61 100644 --- a/packages/shared-ux/card/no_data/mocks/jest.config.js +++ b/packages/shared-ux/page/kibana_template/impl/jest.config.js @@ -7,7 +7,7 @@ */ module.exports = { - preset: '@kbn/test/jest_node', + preset: '@kbn/test', rootDir: '../../../../..', - roots: ['/packages/shared-ux/card/no_data/mocks'], + roots: ['/packages/shared-ux/page/kibana_template/impl'], }; diff --git a/packages/shared-ux/page/kibana_template/impl/package.json b/packages/shared-ux/page/kibana_template/impl/package.json new file mode 100644 index 00000000000000..a0894810479993 --- /dev/null +++ b/packages/shared-ux/page/kibana_template/impl/package.json @@ -0,0 +1,7 @@ +{ + "name": "@kbn/shared-ux-page-kibana-template", + "private": true, + "version": "1.0.0", + "main": "./target_node/index.js", + "license": "SSPL-1.0 OR Elastic License 2.0" +} \ No newline at end of file diff --git a/packages/kbn-shared-ux-components/src/page_template/__snapshots__/page_template.test.tsx.snap b/packages/shared-ux/page/kibana_template/impl/src/__snapshots__/page_template.test.tsx.snap similarity index 100% rename from packages/kbn-shared-ux-components/src/page_template/__snapshots__/page_template.test.tsx.snap rename to packages/shared-ux/page/kibana_template/impl/src/__snapshots__/page_template.test.tsx.snap diff --git a/packages/kbn-shared-ux-components/src/page_template/__snapshots__/page_template_inner.test.tsx.snap b/packages/shared-ux/page/kibana_template/impl/src/__snapshots__/page_template_inner.test.tsx.snap similarity index 100% rename from packages/kbn-shared-ux-components/src/page_template/__snapshots__/page_template_inner.test.tsx.snap rename to packages/shared-ux/page/kibana_template/impl/src/__snapshots__/page_template_inner.test.tsx.snap diff --git a/packages/kbn-shared-ux-components/src/page_template/index.ts b/packages/shared-ux/page/kibana_template/impl/src/index.ts similarity index 60% rename from packages/kbn-shared-ux-components/src/page_template/index.ts rename to packages/shared-ux/page/kibana_template/impl/src/index.ts index cd7d6232d9a8b2..9a890cafe49aaf 100644 --- a/packages/kbn-shared-ux-components/src/page_template/index.ts +++ b/packages/shared-ux/page/kibana_template/impl/src/index.ts @@ -5,7 +5,12 @@ * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ -export { NoDataPage, NoDataConfigPage } from './no_data_page'; + export { KibanaPageTemplate } from './page_template'; -export type { KibanaPageTemplateProps } from './types'; -export type { NoDataPageProps } from './no_data_page'; +export { KibanaPageTemplateProvider, KibanaPageTemplateKibanaProvider } from './services'; +export type { + NoDataConfig, + KibanaPageTemplateProps, + KibanaPageTemplateServices, + KibanaPageTemplateKibanaDependencies, +} from '@kbn/shared-ux-page-kibana-template-types'; diff --git a/packages/shared-ux/page/kibana_template/impl/src/page_template.stories.tsx b/packages/shared-ux/page/kibana_template/impl/src/page_template.stories.tsx new file mode 100644 index 00000000000000..91f46f4f89faa0 --- /dev/null +++ b/packages/shared-ux/page/kibana_template/impl/src/page_template.stories.tsx @@ -0,0 +1,82 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import React from 'react'; +import { + KibanaPageTemplateStorybookMock, + NoDataConfigStorybookMock, + SolutionNavStorybookMock, + InnerPageTemplateStorybookMock, +} from '@kbn/shared-ux-page-kibana-template-mocks'; +import type { + KibanaPageTemplateStorybookParams, + NoDataConfigStorybookParams, + SolutionNavStorybookParams, + InnerPageTemplateStorybookParams, +} from '@kbn/shared-ux-page-kibana-template-mocks'; + +import { KibanaPageTemplateProvider } from './services'; + +import { KibanaPageTemplate as Component } from './page_template'; +import mdx from '../README.mdx'; + +export default { + title: 'Page/Page Template', + description: + 'A thin wrapper around `EuiTemplate`. Takes care of styling, empty state and no data config', + parameters: { + docs: { + page: mdx, + }, + }, +}; + +const templateMock = new KibanaPageTemplateStorybookMock(); +const solutionNavMock = new SolutionNavStorybookMock(); +const noDataConfigMock = new NoDataConfigStorybookMock(); +const innerMock = new InnerPageTemplateStorybookMock(); + +export const WithNoDataConfig = (params: NoDataConfigStorybookParams) => { + return ( + + + + ); +}; + +WithNoDataConfig.argTypes = noDataConfigMock.getArgumentTypes(); + +export const WithSolutionNav = (params: SolutionNavStorybookParams) => { + return ( + + + + ); +}; + +WithSolutionNav.argTypes = solutionNavMock.getArgumentTypes(); + +export const WithBoth = (params: KibanaPageTemplateStorybookParams) => { + return ( + + + + ); +}; + +WithBoth.argTypes = templateMock.getArgumentTypes(); + +export const WithNeither = (params: InnerPageTemplateStorybookParams) => { + return ( + + + + ); +}; + +WithNeither.argTypes = innerMock.getArgumentTypes(); diff --git a/packages/kbn-shared-ux-components/src/page_template/page_template.test.tsx b/packages/shared-ux/page/kibana_template/impl/src/page_template.test.tsx similarity index 97% rename from packages/kbn-shared-ux-components/src/page_template/page_template.test.tsx rename to packages/shared-ux/page/kibana_template/impl/src/page_template.test.tsx index 1324b60b928704..0e9df4b6c2394a 100644 --- a/packages/kbn-shared-ux-components/src/page_template/page_template.test.tsx +++ b/packages/shared-ux/page/kibana_template/impl/src/page_template.test.tsx @@ -9,9 +9,9 @@ import React from 'react'; import { shallow, render } from 'enzyme'; import { SolutionNavProps } from '@kbn/shared-ux-page-solution-nav'; +import type { NoDataPageProps } from '@kbn/shared-ux-page-no-data-types'; import { KibanaPageTemplate } from './page_template'; -import { NoDataPageProps } from './no_data_page'; const items: SolutionNavProps['items'] = [ { diff --git a/packages/kbn-shared-ux-components/src/page_template/page_template.tsx b/packages/shared-ux/page/kibana_template/impl/src/page_template.tsx similarity index 82% rename from packages/kbn-shared-ux-components/src/page_template/page_template.tsx rename to packages/shared-ux/page/kibana_template/impl/src/page_template.tsx index 467f02224b0de7..5a05315d395a77 100644 --- a/packages/kbn-shared-ux-components/src/page_template/page_template.tsx +++ b/packages/shared-ux/page/kibana_template/impl/src/page_template.tsx @@ -6,13 +6,17 @@ * Side Public License, v 1. */ -import React, { FunctionComponent } from 'react'; +import React, { FC } from 'react'; + +import { + NoDataConfigPage, + NoDataConfigPageWithSolutionNavBar, +} from '@kbn/shared-ux-page-no-data-config'; +import { KibanaPageTemplateProps } from '@kbn/shared-ux-page-kibana-template-types'; -import { NoDataConfigPage, NoDataConfigPageWithSolutionNavBar } from './no_data_page'; import { KibanaPageTemplateInner, KibanaPageTemplateWithSolutionNav } from './page_template_inner'; -import { KibanaPageTemplateProps } from './types'; -export const KibanaPageTemplate: FunctionComponent = ({ +export const KibanaPageTemplate: FC = ({ template, className, children, diff --git a/packages/kbn-shared-ux-components/src/page_template/page_template_inner.test.tsx b/packages/shared-ux/page/kibana_template/impl/src/page_template_inner.test.tsx similarity index 100% rename from packages/kbn-shared-ux-components/src/page_template/page_template_inner.test.tsx rename to packages/shared-ux/page/kibana_template/impl/src/page_template_inner.test.tsx diff --git a/packages/kbn-shared-ux-components/src/page_template/page_template_inner.tsx b/packages/shared-ux/page/kibana_template/impl/src/page_template_inner.tsx similarity index 81% rename from packages/kbn-shared-ux-components/src/page_template/page_template_inner.tsx rename to packages/shared-ux/page/kibana_template/impl/src/page_template_inner.tsx index 46424348f2ff3e..6d836a3c66d7f3 100644 --- a/packages/kbn-shared-ux-components/src/page_template/page_template_inner.tsx +++ b/packages/shared-ux/page/kibana_template/impl/src/page_template_inner.tsx @@ -6,20 +6,25 @@ * Side Public License, v 1. */ -import React, { FunctionComponent } from 'react'; - +import React, { FC } from 'react'; +import classNames from 'classnames'; import { EuiEmptyPrompt, EuiPageTemplate } from '@elastic/eui'; -import { withSolutionNav } from '@kbn/shared-ux-page-solution-nav'; -import { KibanaPageTemplateProps } from './types'; -import { getClasses } from './util'; +import { withSolutionNav } from '@kbn/shared-ux-page-solution-nav'; +import { KibanaPageTemplateProps as Props } from '@kbn/shared-ux-page-kibana-template-types'; -type Props = KibanaPageTemplateProps; +const getClasses = (template?: string, className?: string) => { + return classNames( + 'kbnPageTemplate', + template ? { [`kbnPageTemplate--${template}`]: template } : '', + className || '' + ); +}; /** * A thin wrapper around EuiPageTemplate with a few Kibana specific additions */ -export const KibanaPageTemplateInner: FunctionComponent = ({ +export const KibanaPageTemplateInner: FC = ({ template, className, pageHeader, diff --git a/packages/shared-ux/page/kibana_template/impl/src/services.tsx b/packages/shared-ux/page/kibana_template/impl/src/services.tsx new file mode 100644 index 00000000000000..328d3e8a6f9c8e --- /dev/null +++ b/packages/shared-ux/page/kibana_template/impl/src/services.tsx @@ -0,0 +1,41 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import React, { FC } from 'react'; + +import { + NoDataConfigPageProvider, + NoDataConfigPageKibanaProvider, +} from '@kbn/shared-ux-page-no-data-config'; + +import { + KibanaPageTemplateServices, + KibanaPageTemplateKibanaDependencies, +} from '@kbn/shared-ux-page-kibana-template-types'; + +/** + * A Context Provider that provides services to the component and its dependencies. + */ +export const KibanaPageTemplateProvider: FC = ({ + children, + ...services +}) => { + return {children}; +}; + +/** + * Kibana-specific Provider that maps dependencies to services. + */ +export const KibanaPageTemplateKibanaProvider: FC = ({ + children, + ...dependencies +}) => { + return ( + {children} + ); +}; diff --git a/packages/shared-ux/page/kibana_template/impl/tsconfig.json b/packages/shared-ux/page/kibana_template/impl/tsconfig.json new file mode 100644 index 00000000000000..6b965878dca791 --- /dev/null +++ b/packages/shared-ux/page/kibana_template/impl/tsconfig.json @@ -0,0 +1,19 @@ +{ + "extends": "../../../../../tsconfig.bazel.json", + "compilerOptions": { + "declaration": true, + "declarationMap": true, + "emitDeclarationOnly": true, + "outDir": "target_types", + "rootDir": ".", + "stripInternal": false, + "types": [ + "jest", + "node", + "@kbn/ambient-ui-types", + ] + }, + "include": [ + "src/**/*" + ] +} diff --git a/packages/shared-ux/page/kibana_template/mocks/BUILD.bazel b/packages/shared-ux/page/kibana_template/mocks/BUILD.bazel new file mode 100644 index 00000000000000..0680dd91e867f6 --- /dev/null +++ b/packages/shared-ux/page/kibana_template/mocks/BUILD.bazel @@ -0,0 +1,144 @@ +load("@npm//@bazel/typescript:index.bzl", "ts_config") +load("@build_bazel_rules_nodejs//:index.bzl", "js_library") +load("//src/dev/bazel:index.bzl", "jsts_transpiler", "pkg_npm", "pkg_npm_types", "ts_project") + +PKG_DIRNAME = "mocks" +PKG_REQUIRE_NAME = "@kbn/shared-ux-page-kibana-template-mocks" + +SOURCE_FILES = glob( + [ + "src/**/*.ts", + "src/**/*.tsx", + ], + exclude = [ + "**/*.config.js", + "**/*.mock.*", + "**/*.test.*", + "**/*.stories.*", + "**/__snapshots__", + "**/integration_tests", + "**/mocks", + "**/scripts", + "**/storybook", + "**/test_fixtures", + "**/test_helpers", + ], +) + +SRCS = SOURCE_FILES + +filegroup( + name = "srcs", + srcs = SRCS, +) + +NPM_MODULE_EXTRA_FILES = [ + "package.json", +] + +# In this array place runtime dependencies, including other packages and NPM packages +# which must be available for this code to run. +# +# To reference other packages use: +# "//repo/relative/path/to/package" +# eg. "//packages/kbn-utils" +# +# To reference a NPM package use: +# "@npm//name-of-package" +# eg. "@npm//lodash" +RUNTIME_DEPS = [ + "@npm//lodash", + "@npm//react", + "//packages/shared-ux/page/no_data_config/mocks", + "//packages/shared-ux/storybook/mock", +] + +# In this array place dependencies necessary to build the types, which will include the +# :npm_module_types target of other packages and packages from NPM, including @types/* +# packages. +# +# To reference the types for another package use: +# "//repo/relative/path/to/package:npm_module_types" +# eg. "//packages/kbn-utils:npm_module_types" +# +# References to NPM packages work the same as RUNTIME_DEPS +TYPES_DEPS = [ + "@npm//@types/jest", + "@npm//@types/lodash", + "@npm//@types/node", + "@npm//@types/react", + "//packages/shared-ux/page/kibana_template/types", + "//packages/shared-ux/page/no_data_config/mocks:npm_module_types", + "//packages/shared-ux/storybook/mock:npm_module_types", +] + +jsts_transpiler( + name = "target_node", + srcs = SRCS, + build_pkg_name = package_name(), + root_input_dir = "src", +) + +jsts_transpiler( + name = "target_web", + srcs = SRCS, + build_pkg_name = package_name(), + root_input_dir = "src", + web = True, +) + +ts_config( + name = "tsconfig", + src = "tsconfig.json", + deps = [ + "//:tsconfig.base.json", + "//:tsconfig.bazel.json", + ], +) + +ts_project( + name = "tsc_types", + args = ['--pretty'], + srcs = SRCS, + deps = TYPES_DEPS, + declaration = True, + declaration_map = True, + emit_declaration_only = True, + out_dir = "target_types", + root_dir = "src", + tsconfig = ":tsconfig", +) + +js_library( + name = PKG_DIRNAME, + srcs = NPM_MODULE_EXTRA_FILES, + deps = RUNTIME_DEPS + [":target_node", ":target_web"], + package_name = PKG_REQUIRE_NAME, + visibility = ["//visibility:public"], +) + +pkg_npm( + name = "npm_module", + deps = [":" + PKG_DIRNAME], +) + +filegroup( + name = "build", + srcs = [":npm_module"], + visibility = ["//visibility:public"], +) + +pkg_npm_types( + name = "npm_module_types", + srcs = SRCS, + deps = [":tsc_types"], + package_name = PKG_REQUIRE_NAME, + tsconfig = ":tsconfig", + visibility = ["//visibility:public"], +) + +filegroup( + name = "build_types", + srcs = [":npm_module_types"], + visibility = ["//visibility:public"], +) diff --git a/packages/shared-ux/page/kibana_template/mocks/README.mdx b/packages/shared-ux/page/kibana_template/mocks/README.mdx new file mode 100644 index 00000000000000..7515ff010ac90e --- /dev/null +++ b/packages/shared-ux/page/kibana_template/mocks/README.mdx @@ -0,0 +1,3 @@ +# @kbn/shared-ux-page-kibana-template-mocks + +Empty package generated by @kbn/generate diff --git a/packages/shared-ux/page/kibana_template/mocks/package.json b/packages/shared-ux/page/kibana_template/mocks/package.json new file mode 100644 index 00000000000000..c6dc7b5671d7ee --- /dev/null +++ b/packages/shared-ux/page/kibana_template/mocks/package.json @@ -0,0 +1,8 @@ +{ + "name": "@kbn/shared-ux-page-kibana-template-mocks", + "private": true, + "version": "1.0.0", + "main": "./target_node/index.js", + "browser": "./target_web/index.js", + "license": "SSPL-1.0 OR Elastic License 2.0" +} \ No newline at end of file diff --git a/packages/shared-ux/page/kibana_template/mocks/src/index.ts b/packages/shared-ux/page/kibana_template/mocks/src/index.ts new file mode 100644 index 00000000000000..c2193c9c89e618 --- /dev/null +++ b/packages/shared-ux/page/kibana_template/mocks/src/index.ts @@ -0,0 +1,26 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +export { + getServicesMock as getKibanaPageTemplateServicesMock, + getKibanaDependenciesMock as getKibanaPageTemplateKibanaDependenciesMock, +} from './jest'; + +export { + KibanaPageTemplateStorybookMock, + NoDataConfigStorybookMock, + SolutionNavStorybookMock, + InnerPageTemplateStorybookMock, +} from './storybook'; + +export type { + KibanaPageTemplateStorybookParams, + NoDataConfigStorybookParams, + SolutionNavStorybookParams, + InnerPageTemplateStorybookParams, +} from './storybook'; diff --git a/packages/shared-ux/page/kibana_template/mocks/src/jest.ts b/packages/shared-ux/page/kibana_template/mocks/src/jest.ts new file mode 100644 index 00000000000000..5f260e194f6d89 --- /dev/null +++ b/packages/shared-ux/page/kibana_template/mocks/src/jest.ts @@ -0,0 +1,30 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { getNoDataCardKibanaDependenciesMock } from '@kbn/shared-ux-card-no-data-mocks'; +import type { + KibanaPageTemplateServices, + KibanaPageTemplateKibanaDependencies, +} from '@kbn/shared-ux-page-kibana-template-types'; +import { getNoDataConfigPageServicesMock } from '@kbn/shared-ux-page-no-data-config-mocks'; + +export const getServicesMock = () => { + const services: KibanaPageTemplateServices = { + ...getNoDataConfigPageServicesMock(), + }; + + return services; +}; + +export const getKibanaDependenciesMock = () => { + const dependencies: KibanaPageTemplateKibanaDependencies = { + ...getNoDataCardKibanaDependenciesMock(), + }; + + return dependencies; +}; diff --git a/packages/shared-ux/page/kibana_template/mocks/src/storybook/all.ts b/packages/shared-ux/page/kibana_template/mocks/src/storybook/all.ts new file mode 100644 index 00000000000000..6a5754ba1862b4 --- /dev/null +++ b/packages/shared-ux/page/kibana_template/mocks/src/storybook/all.ts @@ -0,0 +1,72 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { AbstractStorybookMock } from '@kbn/shared-ux-storybook-mock'; +import type { ArgumentParams } from '@kbn/shared-ux-storybook-mock'; + +import { NoDataConfigPageStorybookMock } from '@kbn/shared-ux-page-no-data-config-mocks'; +import type { NoDataConfigPageStorybookParams } from '@kbn/shared-ux-page-no-data-config-mocks'; + +import type { + KibanaPageTemplateProps, + KibanaPageTemplateServices, +} from '@kbn/shared-ux-page-kibana-template-types'; + +import { noDataConfigArguments } from './no_data_config'; +import type { NoDataConfigArguments } from './no_data_config'; +import { solutionNavArguments, solutionNavProps } from './solution_nav'; +import type { SolutionNavArguments } from './solution_nav'; + +type PropArguments = NoDataConfigArguments & SolutionNavArguments; + +export type Params = ArgumentParams & NoDataConfigPageStorybookParams; + +const noDataConfigMock = new NoDataConfigPageStorybookMock(); + +export class StorybookMock extends AbstractStorybookMock< + KibanaPageTemplateProps, + KibanaPageTemplateServices, + PropArguments +> { + propArguments = { + ...noDataConfigArguments, + ...solutionNavArguments, + }; + + serviceArguments = {}; + + dependencies = [noDataConfigMock]; + + getProps(params?: Params): KibanaPageTemplateProps { + const result: KibanaPageTemplateProps = { + noDataConfig: { + action: { + elasticAgent: { + title: 'Add Integrations', + }, + }, + solution: this.getArgumentValue('solution', params), + logo: this.getArgumentValue('logo', params), + docsLink: this.getArgumentValue('docsLink', params), + pageTitle: this.getArgumentValue('pageTitle', params), + }, + solutionNav: { + name: this.getArgumentValue('name', params), + icon: this.getArgumentValue('icon', params), + canBeCollapsed: this.getArgumentValue('canBeCollapsed', params), + ...solutionNavProps, + }, + }; + + return result; + } + + getServices(params: Params): KibanaPageTemplateServices { + return { ...noDataConfigMock.getServices(params) }; + } +} diff --git a/packages/shared-ux/page/kibana_template/mocks/src/storybook/index.ts b/packages/shared-ux/page/kibana_template/mocks/src/storybook/index.ts new file mode 100644 index 00000000000000..ecbc26c20a095e --- /dev/null +++ b/packages/shared-ux/page/kibana_template/mocks/src/storybook/index.ts @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +export { StorybookMock as NoDataConfigStorybookMock } from './no_data_config'; +export type { Params as NoDataConfigStorybookParams } from './no_data_config'; + +export { StorybookMock as SolutionNavStorybookMock } from './solution_nav'; +export type { Params as SolutionNavStorybookParams } from './solution_nav'; + +export { StorybookMock as KibanaPageTemplateStorybookMock } from './all'; +export type { Params as KibanaPageTemplateStorybookParams } from './all'; + +export { StorybookMock as InnerPageTemplateStorybookMock } from './inner'; +export type { Params as InnerPageTemplateStorybookParams } from './inner'; diff --git a/packages/shared-ux/page/kibana_template/mocks/src/storybook/inner.tsx b/packages/shared-ux/page/kibana_template/mocks/src/storybook/inner.tsx new file mode 100644 index 00000000000000..7794aea021b893 --- /dev/null +++ b/packages/shared-ux/page/kibana_template/mocks/src/storybook/inner.tsx @@ -0,0 +1,94 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import React from 'react'; +import { AbstractStorybookMock } from '@kbn/shared-ux-storybook-mock'; +import type { ArgumentParams } from '@kbn/shared-ux-storybook-mock'; + +import { NoDataConfigPageStorybookMock } from '@kbn/shared-ux-page-no-data-config-mocks'; +import type { NoDataConfigPageStorybookParams } from '@kbn/shared-ux-page-no-data-config-mocks'; + +import type { + KibanaPageTemplateProps, + KibanaPageTemplateServices, +} from '@kbn/shared-ux-page-kibana-template-types'; + +type PageHeader = NonNullable; +export type PageHeaderArguments = Pick< + PageHeader, + 'iconType' | 'pageTitle' | 'description' | 'rightSideItems' +>; + +type PropArguments = Pick & PageHeaderArguments; + +export type Params = ArgumentParams & NoDataConfigPageStorybookParams; + +const noDataConfigMock = new NoDataConfigPageStorybookMock(); + +export const pageHeaderArguments: ArgumentParams = { + isEmptyState: { + control: 'boolean', + defaultValue: false, + }, + iconType: { + control: { type: 'radio' }, + options: ['logoElastic', 'logoKibana', 'logoCloud', undefined], + defaultValue: undefined, + }, + pageTitle: { + control: 'text', + defaultValue: 'Page title', + }, + description: { + control: 'text', + defaultValue: 'Page description', + }, + rightSideItems: { + control: 'boolean', + defaultValue: true, + }, +}; + +const rightSideItems: PageHeaderArguments['rightSideItems'] = [ + First Item, + Second Item, +]; + +export class StorybookMock extends AbstractStorybookMock< + KibanaPageTemplateProps, + KibanaPageTemplateServices, + PropArguments +> { + propArguments = { + ...pageHeaderArguments, + }; + + serviceArguments = {}; + + dependencies = []; + + getProps(params?: Params): KibanaPageTemplateProps { + const result: KibanaPageTemplateProps = { + isEmptyState: this.getArgumentValue('isEmptyState', params), + pageHeader: { + iconType: this.getArgumentValue('iconType', params), + pageTitle: this.getArgumentValue('pageTitle', params), + description: this.getArgumentValue('description', params), + rightSideItems: this.getArgumentValue('rightSideItems', params) + ? rightSideItems + : undefined, + }, + }; + + return result; + } + + getServices(params: Params): KibanaPageTemplateServices { + return { ...noDataConfigMock.getServices(params) }; + } +} diff --git a/packages/shared-ux/page/kibana_template/mocks/src/storybook/no_data_config.ts b/packages/shared-ux/page/kibana_template/mocks/src/storybook/no_data_config.ts new file mode 100644 index 00000000000000..92e7f0da52e620 --- /dev/null +++ b/packages/shared-ux/page/kibana_template/mocks/src/storybook/no_data_config.ts @@ -0,0 +1,86 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { AbstractStorybookMock } from '@kbn/shared-ux-storybook-mock'; +import type { ArgumentParams } from '@kbn/shared-ux-storybook-mock'; + +import { NoDataConfigPageStorybookMock } from '@kbn/shared-ux-page-no-data-config-mocks'; +import type { NoDataConfigPageStorybookParams } from '@kbn/shared-ux-page-no-data-config-mocks'; + +import type { + NoDataConfig, + KibanaPageTemplateProps, + KibanaPageTemplateServices, +} from '@kbn/shared-ux-page-kibana-template-types'; + +export type NoDataConfigArguments = Pick< + NoDataConfig, + 'solution' | 'logo' | 'docsLink' | 'pageTitle' +>; + +type PropArguments = NoDataConfigArguments; + +export type Params = ArgumentParams & NoDataConfigPageStorybookParams; + +const noDataConfigMock = new NoDataConfigPageStorybookMock(); + +export const noDataConfigArguments: ArgumentParams = { + solution: { + control: 'text', + defaultValue: 'Observability', + }, + logo: { + control: { type: 'radio' }, + options: ['logoElastic', 'logoKibana', 'logoCloud', undefined], + defaultValue: undefined, + }, + docsLink: { + control: 'text', + defaultValue: 'docs/link', + }, + pageTitle: { + control: 'text', + defaultValue: '', + }, +}; + +export class StorybookMock extends AbstractStorybookMock< + KibanaPageTemplateProps, + KibanaPageTemplateServices, + PropArguments +> { + propArguments = { + ...noDataConfigArguments, + }; + + serviceArguments = {}; + + dependencies = [noDataConfigMock]; + + getProps(params?: Params): KibanaPageTemplateProps { + const result: KibanaPageTemplateProps = { + noDataConfig: { + action: { + elasticAgent: { + title: 'Add Integrations', + }, + }, + solution: this.getArgumentValue('solution', params), + logo: this.getArgumentValue('logo', params), + docsLink: this.getArgumentValue('docsLink', params), + pageTitle: this.getArgumentValue('pageTitle', params), + }, + }; + + return result; + } + + getServices(params: Params): KibanaPageTemplateServices { + return { ...noDataConfigMock.getServices(params) }; + } +} diff --git a/packages/shared-ux/page/kibana_template/mocks/src/storybook/solution_nav.ts b/packages/shared-ux/page/kibana_template/mocks/src/storybook/solution_nav.ts new file mode 100644 index 00000000000000..3590a3e896a2e9 --- /dev/null +++ b/packages/shared-ux/page/kibana_template/mocks/src/storybook/solution_nav.ts @@ -0,0 +1,115 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { AbstractStorybookMock } from '@kbn/shared-ux-storybook-mock'; +import type { ArgumentParams } from '@kbn/shared-ux-storybook-mock'; + +import { NoDataConfigPageStorybookMock } from '@kbn/shared-ux-page-no-data-config-mocks'; +import type { NoDataConfigPageStorybookParams } from '@kbn/shared-ux-page-no-data-config-mocks'; + +import type { + KibanaPageTemplateProps, + KibanaPageTemplateServices, +} from '@kbn/shared-ux-page-kibana-template-types'; + +type SolutionNav = NonNullable; +export type SolutionNavArguments = Pick; + +type PropArguments = SolutionNavArguments; + +export type Params = ArgumentParams & NoDataConfigPageStorybookParams; + +const noDataConfigMock = new NoDataConfigPageStorybookMock(); + +export const solutionNavArguments: ArgumentParams = { + name: { + control: 'text', + defaultValue: 'Kibana', + }, + icon: { + control: { type: 'radio' }, + options: ['logoKibana', 'logoObservability', 'logoSecurity'], + defaultValue: 'logoKibana', + }, + canBeCollapsed: { + control: 'boolean', + defaultValue: true, + }, +}; + +export const solutionNavProps = { + items: [ + { + name: 'Ingest', + id: '1', + items: [ + { + name: 'Ingest Node Pipelines', + id: '1.1', + }, + { + name: 'Logstash Pipelines', + id: '1.2', + }, + { + name: 'Beats Central Management', + id: '1.3', + }, + ], + }, + { + name: 'Data', + id: '2', + items: [ + { + name: 'Index Management', + id: '2.1', + }, + { + name: 'Index Lifecycle Policies', + id: '2.2', + }, + { + name: 'Snapshot and Restore', + id: '2.3', + }, + ], + }, + ], +}; + +export class StorybookMock extends AbstractStorybookMock< + KibanaPageTemplateProps, + KibanaPageTemplateServices, + PropArguments +> { + propArguments = { + ...solutionNavArguments, + }; + + serviceArguments = {}; + + dependencies = [noDataConfigMock]; + + getProps(params?: Params): KibanaPageTemplateProps { + const result: KibanaPageTemplateProps = { + solutionNav: { + name: this.getArgumentValue('name', params), + icon: this.getArgumentValue('icon', params), + canBeCollapsed: this.getArgumentValue('canBeCollapsed', params), + ...solutionNavProps, + }, + }; + + return result; + } + + getServices(params: Params): KibanaPageTemplateServices { + return { ...noDataConfigMock.getServices(params) }; + } +} diff --git a/packages/shared-ux/page/kibana_template/mocks/tsconfig.json b/packages/shared-ux/page/kibana_template/mocks/tsconfig.json new file mode 100644 index 00000000000000..dc96ec41f9035d --- /dev/null +++ b/packages/shared-ux/page/kibana_template/mocks/tsconfig.json @@ -0,0 +1,20 @@ +{ + "extends": "../../../../../tsconfig.bazel.json", + "compilerOptions": { + "declaration": true, + "declarationMap": true, + "emitDeclarationOnly": true, + "outDir": "target_types", + "rootDir": "src", + "stripInternal": false, + "types": [ + "jest", + "node", + "react" + ] + }, + "include": [ + "**/*.ts", + "**/*.tsx", + ] +} diff --git a/packages/shared-ux/page/kibana_template/types/BUILD.bazel b/packages/shared-ux/page/kibana_template/types/BUILD.bazel new file mode 100644 index 00000000000000..45cbd0fd4cc422 --- /dev/null +++ b/packages/shared-ux/page/kibana_template/types/BUILD.bazel @@ -0,0 +1,59 @@ +load("@npm//@bazel/typescript:index.bzl", "ts_config") +load("@build_bazel_rules_nodejs//:index.bzl", "js_library") +load("//src/dev/bazel:index.bzl", "jsts_transpiler", "pkg_npm", "pkg_npm_types", "ts_project") + +PKG_DIRNAME = "types" +PKG_REQUIRE_NAME = "@kbn/shared-ux-page-kibana-template-types" + +SRCS = glob( + [ + "*.d.ts", + ] +) + +filegroup( + name = "srcs", + srcs = SRCS, +) + +NPM_MODULE_EXTRA_FILES = [ + "package.json", +] + +# In this array place runtime dependencies, including other packages and NPM packages +# which must be available for this code to run. +# +# To reference other packages use: +# "//repo/relative/path/to/package" +# eg. "//packages/kbn-utils" +# +# To reference a NPM package use: +# "@npm//name-of-package" +# eg. "@npm//lodash" +RUNTIME_DEPS = [ +] + +js_library( + name = PKG_DIRNAME, + srcs = SRCS + NPM_MODULE_EXTRA_FILES, + deps = RUNTIME_DEPS, + package_name = PKG_REQUIRE_NAME, + visibility = ["//visibility:public"], +) + +pkg_npm( + name = "npm_module", + deps = [":" + PKG_DIRNAME], +) + +filegroup( + name = "build", + srcs = [":npm_module"], + visibility = ["//visibility:public"], +) + +alias( + name = "npm_module_types", + actual = ":" + PKG_DIRNAME, + visibility = ["//visibility:public"], +) diff --git a/packages/shared-ux/page/kibana_template/types/README.mdx b/packages/shared-ux/page/kibana_template/types/README.mdx new file mode 100644 index 00000000000000..8245f7d8d8c21d --- /dev/null +++ b/packages/shared-ux/page/kibana_template/types/README.mdx @@ -0,0 +1,3 @@ +# @kbn/shared-ux-page-kibana-template-types + +Empty package generated by @kbn/generate diff --git a/packages/kbn-shared-ux-components/src/page_template/types.ts b/packages/shared-ux/page/kibana_template/types/index.d.ts similarity index 74% rename from packages/kbn-shared-ux-components/src/page_template/types.ts rename to packages/shared-ux/page/kibana_template/types/index.d.ts index 6a8b0d583ed18a..8f3129c31817d5 100644 --- a/packages/kbn-shared-ux-components/src/page_template/types.ts +++ b/packages/shared-ux/page/kibana_template/types/index.d.ts @@ -9,7 +9,15 @@ import { EuiPageTemplateProps } from '@elastic/eui'; import { SolutionNavProps } from '@kbn/shared-ux-page-solution-nav'; -import { NoDataPageProps } from './no_data_page'; +import { + NoDataConfig, + NoDataConfigPageServices, + NoDataConfigPageKibanaDependencies, +} from '@kbn/shared-ux-page-no-data-config-types'; + +export type KibanaPageTemplateKibanaDependencies = NoDataConfigPageKibanaDependencies; +export type KibanaPageTemplateServices = NoDataConfigPageServices; +export type { NoDataConfig } from '@kbn/shared-ux-page-no-data-config-types'; export type KibanaPageTemplateProps = EuiPageTemplateProps & { /** @@ -27,5 +35,5 @@ export type KibanaPageTemplateProps = EuiPageTemplateProps & { * Accepts a configuration object, that when provided, ignores pageHeader and children and instead * displays Agent, Beats, and custom cards to direct users to the right ingest location */ - noDataConfig?: NoDataPageProps; + noDataConfig?: NoDataConfig; }; diff --git a/packages/shared-ux/page/kibana_template/types/package.json b/packages/shared-ux/page/kibana_template/types/package.json new file mode 100644 index 00000000000000..4562e9a1becdd5 --- /dev/null +++ b/packages/shared-ux/page/kibana_template/types/package.json @@ -0,0 +1,7 @@ +{ + "name": "@kbn/shared-ux-page-kibana-template-types", + "private": true, + "version": "1.0.0", + "main": "./target_node/index.js", + "license": "SSPL-1.0 OR Elastic License 2.0" +} \ No newline at end of file diff --git a/packages/shared-ux/page/kibana_template/types/tsconfig.json b/packages/shared-ux/page/kibana_template/types/tsconfig.json new file mode 100644 index 00000000000000..7a4adfcdbecff6 --- /dev/null +++ b/packages/shared-ux/page/kibana_template/types/tsconfig.json @@ -0,0 +1,14 @@ +{ + "extends": "../../../../../tsconfig.bazel.json", + "compilerOptions": { + "declaration": true, + "declarationMap": true, + "emitDeclarationOnly": true, + "outDir": "target_types", + "stripInternal": false, + "types": [] + }, + "include": [ + "*.d.ts" + ] +} diff --git a/packages/kbn-shared-ux-components/BUILD.bazel b/packages/shared-ux/page/no_data/impl/BUILD.bazel similarity index 75% rename from packages/kbn-shared-ux-components/BUILD.bazel rename to packages/shared-ux/page/no_data/impl/BUILD.bazel index 74924f4c6519d7..13ffd0694bdd27 100644 --- a/packages/kbn-shared-ux-components/BUILD.bazel +++ b/packages/shared-ux/page/no_data/impl/BUILD.bazel @@ -2,19 +2,17 @@ load("@npm//@bazel/typescript:index.bzl", "ts_config") load("@build_bazel_rules_nodejs//:index.bzl", "js_library") load("//src/dev/bazel:index.bzl", "jsts_transpiler", "pkg_npm", "pkg_npm_types", "ts_project") -PKG_DIRNAME = "kbn-shared-ux-components" -PKG_REQUIRE_NAME = "@kbn/shared-ux-components" +PKG_DIRNAME = "impl" +PKG_REQUIRE_NAME = "@kbn/shared-ux-page-no-data" SOURCE_FILES = glob( [ "src/**/*.ts", "src/**/*.tsx", - "src/**/*.scss", - "src/**/*.mdx", - "src/**/*.svg", ], exclude = [ "**/*.test.*", + "**/*.stories.*", ], ) @@ -41,22 +39,10 @@ NPM_MODULE_EXTRA_FILES = [ # eg. "@npm//lodash" RUNTIME_DEPS = [ "@npm//@elastic/eui", - "@npm//@emotion/css", - "@npm//@emotion/react", "@npm//classnames", - "@npm//react-use", "@npm//react", - "@npm//rxjs", - "@npm//url-loader", - "//packages/kbn-i18n-react", - "//packages/kbn-i18n", - "//packages/kbn-shared-ux-services", - "//packages/kbn-shared-ux-storybook", - "//packages/kbn-shared-ux-utility", "//packages/shared-ux/avatar/solution", "//packages/shared-ux/card/no_data/impl", - "//packages/shared-ux/link/redirect_app/impl", - "//packages/shared-ux/page/solution_nav", "//packages/shared-ux/prompt/no_data_views/impl", ] @@ -71,24 +57,14 @@ RUNTIME_DEPS = [ # References to NPM packages work the same as RUNTIME_DEPS TYPES_DEPS = [ "@npm//@elastic/eui", - "@npm//@emotion/css", - "@npm//@emotion/react", "@npm//@types/classnames", "@npm//@types/jest", "@npm//@types/node", "@npm//@types/react", - "@npm//react-use", - "@npm//rxjs", "//packages/kbn-ambient-ui-types", - "//packages/kbn-i18n-react:npm_module_types", - "//packages/kbn-i18n:npm_module_types", - "//packages/kbn-shared-ux-services:npm_module_types", - "//packages/kbn-shared-ux-storybook:npm_module_types", - "//packages/kbn-shared-ux-utility:npm_module_types", "//packages/shared-ux/avatar/solution:npm_module_types", "//packages/shared-ux/card/no_data/impl:npm_module_types", - "//packages/shared-ux/link/redirect_app/impl:npm_module_types", - "//packages/shared-ux/page/solution_nav:npm_module_types", + "//packages/shared-ux/page/no_data/types:npm_module_types", "//packages/shared-ux/prompt/no_data_views/impl:npm_module_types", ] diff --git a/packages/shared-ux/page/no_data/impl/README.mdx b/packages/shared-ux/page/no_data/impl/README.mdx new file mode 100644 index 00000000000000..e5dd8c235c4ce4 --- /dev/null +++ b/packages/shared-ux/page/no_data/impl/README.mdx @@ -0,0 +1,3 @@ +# @kbn/shared-ux-page-no-data + +Empty package generated by @kbn/generate diff --git a/packages/kbn-shared-ux-components/jest.config.js b/packages/shared-ux/page/no_data/impl/jest.config.js similarity index 81% rename from packages/kbn-shared-ux-components/jest.config.js rename to packages/shared-ux/page/no_data/impl/jest.config.js index c2ac8c3a57106d..1b7ff2aafe7407 100644 --- a/packages/kbn-shared-ux-components/jest.config.js +++ b/packages/shared-ux/page/no_data/impl/jest.config.js @@ -8,6 +8,6 @@ module.exports = { preset: '@kbn/test', - rootDir: '../..', - roots: ['/packages/kbn-shared-ux-components'], + rootDir: '../../../../..', + roots: ['/packages/shared-ux/page/no_data/impl'], }; diff --git a/packages/kbn-shared-ux-services/package.json b/packages/shared-ux/page/no_data/impl/package.json old mode 100755 new mode 100644 similarity index 80% rename from packages/kbn-shared-ux-services/package.json rename to packages/shared-ux/page/no_data/impl/package.json index 7d7d999bf6961c..1f09f616a765f3 --- a/packages/kbn-shared-ux-services/package.json +++ b/packages/shared-ux/page/no_data/impl/package.json @@ -1,5 +1,5 @@ { - "name": "@kbn/shared-ux-services", + "name": "@kbn/shared-ux-page-no-data", "private": true, "version": "1.0.0", "main": "./target_node/index.js", diff --git a/packages/shared-ux/page/no_data/impl/src/action_card.tsx b/packages/shared-ux/page/no_data/impl/src/action_card.tsx new file mode 100644 index 00000000000000..0dec8c677b12cd --- /dev/null +++ b/packages/shared-ux/page/no_data/impl/src/action_card.tsx @@ -0,0 +1,30 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import React from 'react'; + +import { NoDataCard, NoDataCardProps } from '@kbn/shared-ux-card-no-data'; +import { ActionCardProps } from '@kbn/shared-ux-page-no-data-types'; + +export type NoDataPageActions = NoDataCardProps; + +export const KEY_ELASTIC_AGENT = 'elasticAgent'; + +export const ActionCard = ({ action }: ActionCardProps) => { + const actionKeys = Object.keys(action); + + if (actionKeys.length !== 1) { + return null; + } + + const actionKey = actionKeys[0]; + const key = + actionKey === KEY_ELASTIC_AGENT ? 'empty-page-agent-action' : `empty-page-${actionKey}-action`; + + return ; +}; diff --git a/packages/kbn-shared-ux-components/src/page_template/no_data_page/index.ts b/packages/shared-ux/page/no_data/impl/src/index.ts similarity index 65% rename from packages/kbn-shared-ux-components/src/page_template/no_data_page/index.ts rename to packages/shared-ux/page/no_data/impl/src/index.ts index a6f8c91f7614ce..5438612b541bd7 100644 --- a/packages/kbn-shared-ux-components/src/page_template/no_data_page/index.ts +++ b/packages/shared-ux/page/no_data/impl/src/index.ts @@ -7,5 +7,10 @@ */ export { NoDataPage } from './no_data_page'; -export type { NoDataPageProps } from './types'; -export { NoDataConfigPage, NoDataConfigPageWithSolutionNavBar } from './no_data_config_page'; +export type { + NoDataPageProps, + NoDataPageServices, + NoDataPageKibanaDependencies, +} from '@kbn/shared-ux-page-no-data-types'; + +export { NoDataPageKibanaProvider, NoDataPageProvider } from './services'; diff --git a/packages/shared-ux/page/no_data/impl/src/no_data_page.stories.tsx b/packages/shared-ux/page/no_data/impl/src/no_data_page.stories.tsx new file mode 100644 index 00000000000000..6b56a446383582 --- /dev/null +++ b/packages/shared-ux/page/no_data/impl/src/no_data_page.stories.tsx @@ -0,0 +1,39 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import React from 'react'; + +import { NoDataPageStorybookMock } from '@kbn/shared-ux-page-no-data-mocks'; +import type { NoDataPageStorybookParams } from '@kbn/shared-ux-page-no-data-mocks'; + +import { NoDataPage as Component } from './no_data_page'; + +import { NoDataPageProvider } from './services'; +import mdx from '../README.mdx'; + +const mock = new NoDataPageStorybookMock(); + +export default { + title: 'No Data/Page/No Data Page', + description: 'A component to display when there is no data available', + parameters: { + docs: { + page: mdx, + }, + }, +}; + +export const NoDataPage = (params: NoDataPageStorybookParams) => { + return ( + + + + ); +}; + +NoDataPage.argTypes = mock.getArgumentTypes(); diff --git a/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_page.test.tsx b/packages/shared-ux/page/no_data/impl/src/no_data_page.test.tsx similarity index 81% rename from packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_page.test.tsx rename to packages/shared-ux/page/no_data/impl/src/no_data_page.test.tsx index b9474285469e18..576cf4f3b72309 100644 --- a/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_page.test.tsx +++ b/packages/shared-ux/page/no_data/impl/src/no_data_page.test.tsx @@ -9,14 +9,15 @@ import React from 'react'; import { mountWithIntl } from '@kbn/test-jest-helpers'; import { NoDataCard } from '@kbn/shared-ux-card-no-data'; -import { SharedUxServicesProvider, mockServicesFactory } from '@kbn/shared-ux-services'; +import { getNoDataPageServicesMock } from '@kbn/shared-ux-page-no-data-mocks'; import { NoDataPage } from './no_data_page'; +import { NoDataPageProvider } from './services'; describe('NoDataPage', () => { test('render', () => { const component = mountWithIntl( - + { logo={'logoKibana'} docsLink="test" /> - + ); expect(component.find('h1').html()).toContain('Welcome to Elastic Analytics!'); expect(component.find(NoDataCard).length).toBe(1); diff --git a/packages/shared-ux/page/no_data/impl/src/no_data_page.tsx b/packages/shared-ux/page/no_data/impl/src/no_data_page.tsx new file mode 100644 index 00000000000000..1bc93123aea952 --- /dev/null +++ b/packages/shared-ux/page/no_data/impl/src/no_data_page.tsx @@ -0,0 +1,67 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import React from 'react'; +import classNames from 'classnames'; + +import { EuiLink, EuiSpacer, EuiText, EuiTextColor } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n-react'; + +import { KibanaSolutionAvatar } from '@kbn/shared-ux-avatar-solution'; +import type { NoDataPageProps } from '@kbn/shared-ux-page-no-data-types'; + +import { ActionCard } from './action_card'; + +export const NoDataPage = ({ + solution, + logo, + action, + docsLink, + pageTitle, + className, +}: NoDataPageProps) => { + const title = + pageTitle || + i18n.translate('sharedUXPackages.noDataPage.welcomeTitle', { + defaultMessage: 'Welcome to Elastic {solution}!', + values: { solution }, + }); + + const link = ( + + + + ); + + const message = ( + + ); + + return ( +
+ + + +

{title}

+ +

{message}

+
+
+ + +
+ ); +}; diff --git a/packages/shared-ux/page/no_data/impl/src/services.tsx b/packages/shared-ux/page/no_data/impl/src/services.tsx new file mode 100644 index 00000000000000..3d10cc5547c92d --- /dev/null +++ b/packages/shared-ux/page/no_data/impl/src/services.tsx @@ -0,0 +1,33 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import React, { FC } from 'react'; + +import { NoDataCardKibanaProvider, NoDataCardProvider } from '@kbn/shared-ux-card-no-data'; + +import type { + NoDataPageServices, + NoDataPageKibanaDependencies, +} from '@kbn/shared-ux-page-no-data-types'; + +/** + * A Context Provider that provides services to the component and its dependencies. + */ +export const NoDataPageProvider: FC = ({ children, ...services }) => { + return {children}; +}; + +/** + * Kibana-specific Provider that maps dependencies to services. + */ +export const NoDataPageKibanaProvider: FC = ({ + children, + ...dependencies +}) => { + return {children}; +}; diff --git a/packages/kbn-shared-ux-components/tsconfig.json b/packages/shared-ux/page/no_data/impl/tsconfig.json similarity index 79% rename from packages/kbn-shared-ux-components/tsconfig.json rename to packages/shared-ux/page/no_data/impl/tsconfig.json index dd55bdb28a6323..40ed24ecac4d23 100644 --- a/packages/kbn-shared-ux-components/tsconfig.json +++ b/packages/shared-ux/page/no_data/impl/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "../../tsconfig.bazel.json", + "extends": "../../../../../tsconfig.bazel.json", "compilerOptions": { "declaration": true, "declarationMap": true, @@ -10,7 +10,7 @@ "types": [ "jest", "node", - "@emotion/react/types/css-prop", + "react", "@kbn/ambient-ui-types", ] }, diff --git a/packages/shared-ux/page/no_data/mocks/BUILD.bazel b/packages/shared-ux/page/no_data/mocks/BUILD.bazel new file mode 100644 index 00000000000000..9296b28ed96f12 --- /dev/null +++ b/packages/shared-ux/page/no_data/mocks/BUILD.bazel @@ -0,0 +1,141 @@ +load("@npm//@bazel/typescript:index.bzl", "ts_config") +load("@build_bazel_rules_nodejs//:index.bzl", "js_library") +load("//src/dev/bazel:index.bzl", "jsts_transpiler", "pkg_npm", "pkg_npm_types", "ts_project") + +PKG_DIRNAME = "mocks" +PKG_REQUIRE_NAME = "@kbn/shared-ux-page-no-data-mocks" + +SOURCE_FILES = glob( + [ + "src/**/*.ts", + ], + exclude = [ + "**/*.config.js", + "**/*.mock.*", + "**/*.test.*", + "**/*.stories.*", + "**/__snapshots__", + "**/integration_tests", + "**/mocks", + "**/scripts", + "**/storybook", + "**/test_fixtures", + "**/test_helpers", + ], +) + +SRCS = SOURCE_FILES + +filegroup( + name = "srcs", + srcs = SRCS, +) + +NPM_MODULE_EXTRA_FILES = [ + "package.json", +] + +# In this array place runtime dependencies, including other packages and NPM packages +# which must be available for this code to run. +# +# To reference other packages use: +# "//repo/relative/path/to/package" +# eg. "//packages/kbn-utils" +# +# To reference a NPM package use: +# "@npm//name-of-package" +# eg. "@npm//lodash" +RUNTIME_DEPS = [ + "@npm//react", + "//packages/shared-ux/card/no_data/mocks", + "//packages/shared-ux/storybook/mock", +] + +# In this array place dependencies necessary to build the types, which will include the +# :npm_module_types target of other packages and packages from NPM, including @types/* +# packages. +# +# To reference the types for another package use: +# "//repo/relative/path/to/package:npm_module_types" +# eg. "//packages/kbn-utils:npm_module_types" +# +# References to NPM packages work the same as RUNTIME_DEPS +TYPES_DEPS = [ + "@npm//@types/node", + "@npm//@types/jest", + "@npm//@types/react", + "//packages/shared-ux/page/no_data/types", + "//packages/shared-ux/card/no_data/mocks:npm_module_types", + "//packages/shared-ux/storybook/mock:npm_module_types", +] + +jsts_transpiler( + name = "target_node", + srcs = SRCS, + build_pkg_name = package_name(), + root_input_dir = "src", +) + +jsts_transpiler( + name = "target_web", + srcs = SRCS, + build_pkg_name = package_name(), + root_input_dir = "src", + web = True, +) + +ts_config( + name = "tsconfig", + src = "tsconfig.json", + deps = [ + "//:tsconfig.base.json", + "//:tsconfig.bazel.json", + ], +) + +ts_project( + name = "tsc_types", + args = ['--pretty'], + srcs = SRCS, + deps = TYPES_DEPS, + declaration = True, + declaration_map = True, + emit_declaration_only = True, + out_dir = "target_types", + root_dir = "src", + tsconfig = ":tsconfig", +) + +js_library( + name = PKG_DIRNAME, + srcs = NPM_MODULE_EXTRA_FILES, + deps = RUNTIME_DEPS + [":target_node", ":target_web"], + package_name = PKG_REQUIRE_NAME, + visibility = ["//visibility:public"], +) + +pkg_npm( + name = "npm_module", + deps = [":" + PKG_DIRNAME], +) + +filegroup( + name = "build", + srcs = [":npm_module"], + visibility = ["//visibility:public"], +) + +pkg_npm_types( + name = "npm_module_types", + srcs = SRCS, + deps = [":tsc_types"], + package_name = PKG_REQUIRE_NAME, + tsconfig = ":tsconfig", + visibility = ["//visibility:public"], +) + +filegroup( + name = "build_types", + srcs = [":npm_module_types"], + visibility = ["//visibility:public"], +) diff --git a/packages/shared-ux/page/no_data/mocks/README.md b/packages/shared-ux/page/no_data/mocks/README.md new file mode 100644 index 00000000000000..5714e473d1f0c8 --- /dev/null +++ b/packages/shared-ux/page/no_data/mocks/README.md @@ -0,0 +1,3 @@ +# @kbn/shared-ux-page-no-data-mocks + +Empty package generated by @kbn/generate diff --git a/packages/shared-ux/page/no_data/mocks/package.json b/packages/shared-ux/page/no_data/mocks/package.json new file mode 100644 index 00000000000000..d6051a988cdc42 --- /dev/null +++ b/packages/shared-ux/page/no_data/mocks/package.json @@ -0,0 +1,8 @@ +{ + "name": "@kbn/shared-ux-page-no-data-mocks", + "private": true, + "version": "1.0.0", + "main": "./target_node/index.js", + "browser": "./target_web/index.js", + "license": "SSPL-1.0 OR Elastic License 2.0" +} \ No newline at end of file diff --git a/packages/shared-ux/page/no_data/mocks/src/index.ts b/packages/shared-ux/page/no_data/mocks/src/index.ts new file mode 100644 index 00000000000000..a17ff47a677752 --- /dev/null +++ b/packages/shared-ux/page/no_data/mocks/src/index.ts @@ -0,0 +1,15 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +export { + getServicesMock as getNoDataPageServicesMock, + getKibanaDependenciesMock as getNoDataPageKibanaDependenciesMock, +} from './jest'; + +export { NoDataPageStorybookMock } from './storybook'; +export type { Params as NoDataPageStorybookParams } from './storybook'; diff --git a/packages/shared-ux/page/no_data/mocks/src/jest.ts b/packages/shared-ux/page/no_data/mocks/src/jest.ts new file mode 100644 index 00000000000000..fd44142c2f5972 --- /dev/null +++ b/packages/shared-ux/page/no_data/mocks/src/jest.ts @@ -0,0 +1,64 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import deepmerge from 'deepmerge'; +import { isPlainObject } from 'lodash'; + +import type { + NoDataPageServices, + NoDataPageKibanaDependencies, +} from '@kbn/shared-ux-page-no-data-types'; + +import { + getNoDataCardServicesMock, + getNoDataCardKibanaDependenciesMock, +} from '@kbn/shared-ux-card-no-data-mocks'; + +const defaultParams = { + canAccessFleet: true, +}; + +export const getServicesMock = (params: Partial = defaultParams) => { + const canAccessFleet = + params.canAccessFleet !== undefined ? params.canAccessFleet : defaultParams.canAccessFleet; + + const services: NoDataPageServices = { + ...getNoDataCardServicesMock(), + canAccessFleet, + }; + + return services; +}; + +/** + * Return a Jest mock of the Kibana dependencies for the `NoDataPageKibanaProvider`. + */ +export const getKibanaDependenciesMock = ( + params: Partial = defaultParams +): NoDataPageKibanaDependencies => { + const integrations = + params.canAccessFleet !== undefined ? params.canAccessFleet : defaultParams.canAccessFleet; + + return deepmerge( + { + coreStart: { + application: { + capabilities: { + navLinks: { + integrations, + }, + }, + }, + }, + }, + getNoDataCardKibanaDependenciesMock(), + { + isMergeableObject: isPlainObject, + } + ); +}; diff --git a/packages/shared-ux/page/no_data/mocks/src/storybook.ts b/packages/shared-ux/page/no_data/mocks/src/storybook.ts new file mode 100644 index 00000000000000..899ddf819a7d62 --- /dev/null +++ b/packages/shared-ux/page/no_data/mocks/src/storybook.ts @@ -0,0 +1,67 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { AbstractStorybookMock } from '@kbn/shared-ux-storybook-mock'; +import type { ArgumentParams } from '@kbn/shared-ux-storybook-mock'; +import type { NoDataPageProps, NoDataPageServices } from '@kbn/shared-ux-page-no-data-types'; +import { NoDataCardStorybookMock } from '@kbn/shared-ux-card-no-data-mocks'; +import type { NoDataCardStorybookParams } from '@kbn/shared-ux-card-no-data-mocks'; + +type PropArguments = Pick; + +export type Params = ArgumentParams & NoDataCardStorybookParams; + +const dataCardMock = new NoDataCardStorybookMock(); + +export class NoDataPageStorybookMock extends AbstractStorybookMock< + NoDataPageProps, + NoDataPageServices, + PropArguments +> { + propArguments = { + solution: { + control: 'text', + defaultValue: 'Observability', + }, + logo: { + control: { type: 'radio' }, + options: ['logoElastic', 'logoKibana', 'logoCloud', undefined], + defaultValue: undefined, + }, + docsLink: { + control: 'text', + defaultValue: 'docs/link', + }, + pageTitle: { + control: 'text', + defaultValue: '', + }, + }; + + serviceArguments = {}; + + dependencies = [dataCardMock]; + + getProps(params?: Params): NoDataPageProps { + return { + action: { + elasticAgent: { + title: 'Add Integrations', + }, + }, + solution: this.getArgumentValue('solution', params), + logo: this.getArgumentValue('logo', params), + docsLink: this.getArgumentValue('docsLink', params), + pageTitle: this.getArgumentValue('pageTitle', params), + }; + } + + getServices(params: Params): NoDataPageServices { + return { ...dataCardMock.getServices(params) }; + } +} diff --git a/packages/shared-ux/page/no_data/mocks/tsconfig.json b/packages/shared-ux/page/no_data/mocks/tsconfig.json new file mode 100644 index 00000000000000..dc96ec41f9035d --- /dev/null +++ b/packages/shared-ux/page/no_data/mocks/tsconfig.json @@ -0,0 +1,20 @@ +{ + "extends": "../../../../../tsconfig.bazel.json", + "compilerOptions": { + "declaration": true, + "declarationMap": true, + "emitDeclarationOnly": true, + "outDir": "target_types", + "rootDir": "src", + "stripInternal": false, + "types": [ + "jest", + "node", + "react" + ] + }, + "include": [ + "**/*.ts", + "**/*.tsx", + ] +} diff --git a/packages/shared-ux/page/no_data/types/BUILD.bazel b/packages/shared-ux/page/no_data/types/BUILD.bazel new file mode 100644 index 00000000000000..618a82a8f6a980 --- /dev/null +++ b/packages/shared-ux/page/no_data/types/BUILD.bazel @@ -0,0 +1,59 @@ +load("@npm//@bazel/typescript:index.bzl", "ts_config") +load("@build_bazel_rules_nodejs//:index.bzl", "js_library") +load("//src/dev/bazel:index.bzl", "jsts_transpiler", "pkg_npm", "pkg_npm_types", "ts_project") + +PKG_DIRNAME = "types" +PKG_REQUIRE_NAME = "@kbn/shared-ux-page-no-data-types" + +SRCS = glob( + [ + "*.d.ts", + ] +) + +filegroup( + name = "srcs", + srcs = SRCS, +) + +NPM_MODULE_EXTRA_FILES = [ + "package.json", +] + +# In this array place runtime dependencies, including other packages and NPM packages +# which must be available for this code to run. +# +# To reference other packages use: +# "//repo/relative/path/to/package" +# eg. "//packages/kbn-utils" +# +# To reference a NPM package use: +# "@npm//name-of-package" +# eg. "@npm//lodash" +RUNTIME_DEPS = [ +] + +js_library( + name = PKG_DIRNAME, + srcs = SRCS + NPM_MODULE_EXTRA_FILES, + deps = RUNTIME_DEPS, + package_name = PKG_REQUIRE_NAME, + visibility = ["//visibility:public"], +) + +pkg_npm( + name = "npm_module", + deps = [":" + PKG_DIRNAME], +) + +filegroup( + name = "build", + srcs = [":npm_module"], + visibility = ["//visibility:public"], +) + +alias( + name = "npm_module_types", + actual = ":" + PKG_DIRNAME, + visibility = ["//visibility:public"], +) diff --git a/packages/shared-ux/page/no_data/types/README.mdx b/packages/shared-ux/page/no_data/types/README.mdx new file mode 100644 index 00000000000000..7890d0ef8a3c46 --- /dev/null +++ b/packages/shared-ux/page/no_data/types/README.mdx @@ -0,0 +1,3 @@ +# @kbn/shared-ux-page-no-data-types + +Empty package generated by @kbn/generate diff --git a/packages/kbn-shared-ux-components/src/page_template/no_data_page/types.ts b/packages/shared-ux/page/no_data/types/index.d.ts similarity index 66% rename from packages/kbn-shared-ux-components/src/page_template/no_data_page/types.ts rename to packages/shared-ux/page/no_data/types/index.d.ts index e22f7a7b81a77f..3db9e80c950c94 100644 --- a/packages/kbn-shared-ux-components/src/page_template/no_data_page/types.ts +++ b/packages/shared-ux/page/no_data/types/index.d.ts @@ -7,31 +7,50 @@ */ import { CommonProps } from '@elastic/eui'; -import { NoDataCardProps } from '@kbn/shared-ux-card-no-data'; +import { + NoDataCardProps, + NoDataCardServices, + NoDataCardKibanaDependencies, +} from '@kbn/shared-ux-card-no-data-types'; export type NoDataPageActions = NoDataCardProps; -export interface NoDataPageProps extends CommonProps { +export interface ActionCardProps { /** - * Single name for the current solution, used to auto-generate the title, logo, description, and button label + * An object of `NoDataPageActions`. + * + * Use `elasticAgent` as the primary key for pre-configured cards of this type. + * Otherwise use a custom key that contains `EuiCard` props. */ - solution: string; + action: Record; +} + +export interface NoDataPageProps extends CommonProps, ActionCardProps { /** - * Optionally replace the auto-generated logo + * Single name for the current solution, used to auto-generate the title, logo, description, and button label */ - logo?: string; + solution: string; /** * Required to set the docs link for the whole solution */ docsLink: string; /** - * Optionally replace the auto-generated page title (h1) + * Optionally replace the auto-generated logo */ - pageTitle?: string; + logo?: string; /** - * An object of `NoDataPageActions`. - * Use `elasticAgent` as the primary key for pre-configured cards of this type. - * Otherwise use a custom key that contains `EuiCard` props. + * Optionally replace the auto-generated page title (h1) */ - action: Record; + pageTitle?: string; } + +/** + * A list of services that are consumed by this component. + */ +export type NoDataPageServices = NoDataCardServices; + +/** + * An interface containing a collection of Kibana plugins and services required to + * render this component. + */ +export type NoDataPageKibanaDependencies = NoDataCardKibanaDependencies; diff --git a/packages/shared-ux/page/no_data/types/package.json b/packages/shared-ux/page/no_data/types/package.json new file mode 100644 index 00000000000000..8e9dce1b11f45b --- /dev/null +++ b/packages/shared-ux/page/no_data/types/package.json @@ -0,0 +1,7 @@ +{ + "name": "@kbn/shared-ux-page-no-data-types", + "private": true, + "version": "1.0.0", + "main": "./target_node/index.js", + "license": "SSPL-1.0 OR Elastic License 2.0" +} diff --git a/packages/shared-ux/page/no_data/types/tsconfig.json b/packages/shared-ux/page/no_data/types/tsconfig.json new file mode 100644 index 00000000000000..7a4adfcdbecff6 --- /dev/null +++ b/packages/shared-ux/page/no_data/types/tsconfig.json @@ -0,0 +1,14 @@ +{ + "extends": "../../../../../tsconfig.bazel.json", + "compilerOptions": { + "declaration": true, + "declarationMap": true, + "emitDeclarationOnly": true, + "outDir": "target_types", + "stripInternal": false, + "types": [] + }, + "include": [ + "*.d.ts" + ] +} diff --git a/packages/shared-ux/page/no_data_config/impl/BUILD.bazel b/packages/shared-ux/page/no_data_config/impl/BUILD.bazel new file mode 100644 index 00000000000000..73c069342a5a09 --- /dev/null +++ b/packages/shared-ux/page/no_data_config/impl/BUILD.bazel @@ -0,0 +1,138 @@ +load("@npm//@bazel/typescript:index.bzl", "ts_config") +load("@build_bazel_rules_nodejs//:index.bzl", "js_library") +load("//src/dev/bazel:index.bzl", "jsts_transpiler", "pkg_npm", "pkg_npm_types", "ts_project") + +PKG_DIRNAME = "impl" +PKG_REQUIRE_NAME = "@kbn/shared-ux-page-no-data-config" + +SOURCE_FILES = glob( + [ + "src/**/*.ts", + "src/**/*.tsx", + "src/**/*.mdx", + ], + exclude = [ + "**/*.test.*", + "**/*.stories.*", + ], +) + +SRCS = SOURCE_FILES + +filegroup( + name = "srcs", + srcs = SRCS, +) + +NPM_MODULE_EXTRA_FILES = [ + "package.json", +] + +# In this array place runtime dependencies, including other packages and NPM packages +# which must be available for this code to run. +# +# To reference other packages use: +# "//repo/relative/path/to/package" +# eg. "//packages/kbn-utils" +# +# To reference a NPM package use: +# "@npm//name-of-package" +# eg. "@npm//lodash" +RUNTIME_DEPS = [ + "@npm//react", + "@npm//classnames", + "@npm//@elastic/eui", + "//packages/shared-ux/page/solution_nav", + "//packages/shared-ux/page/no_data/impl", +] + +# In this array place dependencies necessary to build the types, which will include the +# :npm_module_types target of other packages and packages from NPM, including @types/* +# packages. +# +# To reference the types for another package use: +# "//repo/relative/path/to/package:npm_module_types" +# eg. "//packages/kbn-utils:npm_module_types" +# +# References to NPM packages work the same as RUNTIME_DEPS +TYPES_DEPS = [ + "@npm//@types/node", + "@npm//@types/jest", + "@npm//@types/react", + "@npm//classnames", + "@npm//@elastic/eui", + "//packages/shared-ux/page/solution_nav:npm_module_types", + "//packages/shared-ux/page/no_data/impl:npm_module_types", + "//packages/shared-ux/page/no_data_config/types", +] + +jsts_transpiler( + name = "target_node", + srcs = SRCS, + build_pkg_name = package_name(), + root_input_dir = "src", +) + +jsts_transpiler( + name = "target_web", + srcs = SRCS, + build_pkg_name = package_name(), + root_input_dir = "src", + web = True, +) + +ts_config( + name = "tsconfig", + src = "tsconfig.json", + deps = [ + "//:tsconfig.base.json", + "//:tsconfig.bazel.json", + ], +) + +ts_project( + name = "tsc_types", + args = ['--pretty'], + srcs = SRCS, + deps = TYPES_DEPS, + declaration = True, + declaration_map = True, + emit_declaration_only = True, + out_dir = "target_types", + root_dir = "src", + tsconfig = ":tsconfig", +) + +js_library( + name = PKG_DIRNAME, + srcs = NPM_MODULE_EXTRA_FILES, + deps = RUNTIME_DEPS + [":target_node", ":target_web"], + package_name = PKG_REQUIRE_NAME, + visibility = ["//visibility:public"], +) + +pkg_npm( + name = "npm_module", + deps = [":" + PKG_DIRNAME], +) + +filegroup( + name = "build", + srcs = [":npm_module"], + visibility = ["//visibility:public"], +) + +pkg_npm_types( + name = "npm_module_types", + srcs = SRCS, + deps = [":tsc_types"], + package_name = PKG_REQUIRE_NAME, + tsconfig = ":tsconfig", + visibility = ["//visibility:public"], +) + +filegroup( + name = "build_types", + srcs = [":npm_module_types"], + visibility = ["//visibility:public"], +) diff --git a/packages/shared-ux/page/no_data_config/impl/README.mdx b/packages/shared-ux/page/no_data_config/impl/README.mdx new file mode 100644 index 00000000000000..a7f73534bbd098 --- /dev/null +++ b/packages/shared-ux/page/no_data_config/impl/README.mdx @@ -0,0 +1,3 @@ +# @kbn/shared-ux-page-no-data-config + +Empty package generated by @kbn/generate diff --git a/packages/shared-ux/link/redirect_app/types/jest.config.js b/packages/shared-ux/page/no_data_config/impl/jest.config.js similarity index 80% rename from packages/shared-ux/link/redirect_app/types/jest.config.js rename to packages/shared-ux/page/no_data_config/impl/jest.config.js index 53269ab395d095..09a8f39000c1d5 100644 --- a/packages/shared-ux/link/redirect_app/types/jest.config.js +++ b/packages/shared-ux/page/no_data_config/impl/jest.config.js @@ -7,7 +7,7 @@ */ module.exports = { - preset: '@kbn/test/jest_node', + preset: '@kbn/test', rootDir: '../../../../..', - roots: ['/packages/shared-ux/link/redirect_app/types'], + roots: ['/packages/shared-ux/page/no_data_config/impl'], }; diff --git a/packages/kbn-shared-ux-storybook/package.json b/packages/shared-ux/page/no_data_config/impl/package.json similarity index 77% rename from packages/kbn-shared-ux-storybook/package.json rename to packages/shared-ux/page/no_data_config/impl/package.json index c5f22bb151431a..216bba70b5d50c 100644 --- a/packages/kbn-shared-ux-storybook/package.json +++ b/packages/shared-ux/page/no_data_config/impl/package.json @@ -1,5 +1,5 @@ { - "name": "@kbn/shared-ux-storybook", + "name": "@kbn/shared-ux-page-no-data-config", "private": true, "version": "1.0.0", "main": "./target_node/index.js", diff --git a/packages/kbn-shared-ux-components/src/page_template/util/constants.ts b/packages/shared-ux/page/no_data_config/impl/src/constants.ts similarity index 78% rename from packages/kbn-shared-ux-components/src/page_template/util/constants.ts rename to packages/shared-ux/page/no_data_config/impl/src/constants.ts index 92dbe1cb16279f..1c4c2685433d48 100644 --- a/packages/kbn-shared-ux-components/src/page_template/util/constants.ts +++ b/packages/shared-ux/page/no_data_config/impl/src/constants.ts @@ -6,11 +6,11 @@ * Side Public License, v 1. */ -import { KibanaPageTemplateProps } from '../types'; +import type { NoDataConfigPageProps } from '@kbn/shared-ux-page-no-data-config-types'; export const NO_DATA_PAGE_MAX_WIDTH = 950; -export const NO_DATA_PAGE_TEMPLATE_PROPS: KibanaPageTemplateProps = { +export const NO_DATA_PAGE_TEMPLATE_PROPS: NoDataConfigPageProps = { restrictWidth: NO_DATA_PAGE_MAX_WIDTH, template: 'centeredBody', pageContentProps: { diff --git a/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_config_page/index.ts b/packages/shared-ux/page/no_data_config/impl/src/index.ts similarity index 64% rename from packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_config_page/index.ts rename to packages/shared-ux/page/no_data_config/impl/src/index.ts index f8c272c8f98756..baf373726144d0 100644 --- a/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_config_page/index.ts +++ b/packages/shared-ux/page/no_data_config/impl/src/index.ts @@ -5,4 +5,11 @@ * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ + export { NoDataConfigPage, NoDataConfigPageWithSolutionNavBar } from './no_data_config_page'; +export { NoDataConfigPageKibanaProvider, NoDataConfigPageProvider } from './services'; +export type { + NoDataConfigPageProps, + NoDataConfigPageServices, + NoDataConfigPageKibanaDependencies, +} from '@kbn/shared-ux-page-no-data-config-types'; diff --git a/packages/shared-ux/page/no_data_config/impl/src/no_data_config_page.stories.tsx b/packages/shared-ux/page/no_data_config/impl/src/no_data_config_page.stories.tsx new file mode 100644 index 00000000000000..3106a5b41416d7 --- /dev/null +++ b/packages/shared-ux/page/no_data_config/impl/src/no_data_config_page.stories.tsx @@ -0,0 +1,39 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import React from 'react'; + +import { NoDataConfigPageStorybookMock } from '@kbn/shared-ux-page-no-data-config-mocks'; +import type { NoDataConfigPageStorybookParams } from '@kbn/shared-ux-page-no-data-config-mocks'; + +import { NoDataConfigPage as Component } from './no_data_config_page'; + +import { NoDataConfigPageProvider } from './services'; +import mdx from '../README.mdx'; + +const mock = new NoDataConfigPageStorybookMock(); + +export default { + title: 'No Data/Page/No Data Config Page', + description: 'A component to display when there is no data available', + parameters: { + docs: { + page: mdx, + }, + }, +}; + +export const NoDataConfigPage = (params: NoDataConfigPageStorybookParams) => { + return ( + + + + ); +}; + +NoDataConfigPage.argTypes = mock.getArgumentTypes(); diff --git a/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_config_page/no_data_config_page.test.tsx b/packages/shared-ux/page/no_data_config/impl/src/no_data_config_page.test.tsx similarity index 55% rename from packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_config_page/no_data_config_page.test.tsx rename to packages/shared-ux/page/no_data_config/impl/src/no_data_config_page.test.tsx index dc618a068e1203..fbd897314ecebd 100644 --- a/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_config_page/no_data_config_page.test.tsx +++ b/packages/shared-ux/page/no_data_config/impl/src/no_data_config_page.test.tsx @@ -6,13 +6,17 @@ * Side Public License, v 1. */ -import { shallow } from 'enzyme'; import React from 'react'; +import { mountWithIntl } from '@kbn/test-jest-helpers'; + +import { getNoDataConfigPageServicesMock } from '@kbn/shared-ux-page-no-data-config-mocks'; + import { NoDataConfigPage } from './no_data_config_page'; +import { NoDataConfigPageProvider } from './services'; describe('NoDataConfigPage', () => { const noDataConfig = { - solution: 'Kibana', + solution: 'Solution', logo: 'logoKibana', docsLink: 'test-link', action: { @@ -24,7 +28,12 @@ describe('NoDataConfigPage', () => { }, }; test('renders', () => { - const component = shallow(); - expect(component).toMatchSnapshot(); + const component = mountWithIntl( + + + + ); + expect(component.find('h1').html()).toContain('Welcome to Elastic Solution!'); + expect(component.find('button').html()).toContain('Click me'); }); }); diff --git a/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_config_page/no_data_config_page.tsx b/packages/shared-ux/page/no_data_config/impl/src/no_data_config_page.tsx similarity index 54% rename from packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_config_page/no_data_config_page.tsx rename to packages/shared-ux/page/no_data_config/impl/src/no_data_config_page.tsx index c21431a8107fe2..f5153aa25686ea 100644 --- a/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_config_page/no_data_config_page.tsx +++ b/packages/shared-ux/page/no_data_config/impl/src/no_data_config_page.tsx @@ -7,29 +7,36 @@ */ import React from 'react'; +import classNames from 'classnames'; import { EuiPageTemplate } from '@elastic/eui'; + import { withSolutionNav } from '@kbn/shared-ux-page-solution-nav'; +import { NoDataPage } from '@kbn/shared-ux-page-no-data'; +import type { NoDataConfigPageProps } from '@kbn/shared-ux-page-no-data-config-types'; + +import { NO_DATA_PAGE_TEMPLATE_PROPS } from './constants'; -import { NoDataPage } from '../no_data_page'; -import { KibanaPageTemplateProps } from '../../types'; -import { getClasses, NO_DATA_PAGE_TEMPLATE_PROPS } from '../../util'; +const getClasses = (template?: string, className?: string) => { + return classNames( + 'kbnPageTemplate', + template ? { [`kbnPageTemplate--${template}`]: template } : '', + className || '' + ); +}; -export const NoDataConfigPage = (props: KibanaPageTemplateProps) => { - const { className, noDataConfig, ...rest } = props; +export const NoDataConfigPage = (props: NoDataConfigPageProps) => { + const { className: classNameProp, noDataConfig, ...rest } = props; if (!noDataConfig) { return null; } - const template = NO_DATA_PAGE_TEMPLATE_PROPS.template; - const classes = getClasses(template, className); + const className = getClasses(NO_DATA_PAGE_TEMPLATE_PROPS.template, classNameProp); return ( diff --git a/packages/shared-ux/page/no_data_config/impl/src/services.tsx b/packages/shared-ux/page/no_data_config/impl/src/services.tsx new file mode 100644 index 00000000000000..a7d0d118c053db --- /dev/null +++ b/packages/shared-ux/page/no_data_config/impl/src/services.tsx @@ -0,0 +1,35 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import React, { FC } from 'react'; + +import { NoDataPageProvider, NoDataPageKibanaProvider } from '@kbn/shared-ux-page-no-data'; +import type { + NoDataConfigPageServices, + NoDataConfigPageKibanaDependencies, +} from '@kbn/shared-ux-page-no-data-config-types'; + +/** + * A Context Provider that provides services to the component and its dependencies. + */ +export const NoDataConfigPageProvider: FC = ({ + children, + ...services +}) => { + return {children}; +}; + +/** + * Kibana-specific Provider that maps dependencies to services. + */ +export const NoDataConfigPageKibanaProvider: FC = ({ + children, + ...dependencies +}) => { + return {children}; +}; diff --git a/packages/shared-ux/page/no_data_config/impl/tsconfig.json b/packages/shared-ux/page/no_data_config/impl/tsconfig.json new file mode 100644 index 00000000000000..40ed24ecac4d23 --- /dev/null +++ b/packages/shared-ux/page/no_data_config/impl/tsconfig.json @@ -0,0 +1,20 @@ +{ + "extends": "../../../../../tsconfig.bazel.json", + "compilerOptions": { + "declaration": true, + "declarationMap": true, + "emitDeclarationOnly": true, + "outDir": "target_types", + "rootDir": "src", + "stripInternal": false, + "types": [ + "jest", + "node", + "react", + "@kbn/ambient-ui-types", + ] + }, + "include": [ + "src/**/*" + ] +} diff --git a/packages/shared-ux/page/no_data_config/mocks/BUILD.bazel b/packages/shared-ux/page/no_data_config/mocks/BUILD.bazel new file mode 100644 index 00000000000000..0a797fd6de629d --- /dev/null +++ b/packages/shared-ux/page/no_data_config/mocks/BUILD.bazel @@ -0,0 +1,140 @@ +load("@npm//@bazel/typescript:index.bzl", "ts_config") +load("@build_bazel_rules_nodejs//:index.bzl", "js_library") +load("//src/dev/bazel:index.bzl", "jsts_transpiler", "pkg_npm", "pkg_npm_types", "ts_project") + +PKG_DIRNAME = "mocks" +PKG_REQUIRE_NAME = "@kbn/shared-ux-page-no-data-config-mocks" + +SOURCE_FILES = glob( + [ + "src/**/*.ts", + ], + exclude = [ + "**/*.config.js", + "**/*.mock.*", + "**/*.test.*", + "**/*.stories.*", + "**/__snapshots__", + "**/integration_tests", + "**/mocks", + "**/scripts", + "**/storybook", + "**/test_fixtures", + "**/test_helpers", + ], +) + +SRCS = SOURCE_FILES + +filegroup( + name = "srcs", + srcs = SRCS, +) + +NPM_MODULE_EXTRA_FILES = [ + "package.json", +] + +# In this array place runtime dependencies, including other packages and NPM packages +# which must be available for this code to run. +# +# To reference other packages use: +# "//repo/relative/path/to/package" +# eg. "//packages/kbn-utils" +# +# To reference a NPM package use: +# "@npm//name-of-package" +# eg. "@npm//lodash" +RUNTIME_DEPS = [ + "@npm//react", + "//packages/shared-ux/page/no_data/mocks", +] + +# In this array place dependencies necessary to build the types, which will include the +# :npm_module_types target of other packages and packages from NPM, including @types/* +# packages. +# +# To reference the types for another package use: +# "//repo/relative/path/to/package:npm_module_types" +# eg. "//packages/kbn-utils:npm_module_types" +# +# References to NPM packages work the same as RUNTIME_DEPS +TYPES_DEPS = [ + "@npm//@types/jest", + "@npm//@types/node", + "@npm//@types/react", + "//packages/shared-ux/page/no_data_config/types", + "//packages/shared-ux/page/no_data/mocks:npm_module_types", + "//packages/shared-ux/storybook/mock:npm_module_types", +] + +jsts_transpiler( + name = "target_node", + srcs = SRCS, + build_pkg_name = package_name(), + root_input_dir = "src", +) + +jsts_transpiler( + name = "target_web", + srcs = SRCS, + build_pkg_name = package_name(), + root_input_dir = "src", + web = True, +) + +ts_config( + name = "tsconfig", + src = "tsconfig.json", + deps = [ + "//:tsconfig.base.json", + "//:tsconfig.bazel.json", + ], +) + +ts_project( + name = "tsc_types", + args = ['--pretty'], + srcs = SRCS, + deps = TYPES_DEPS, + declaration = True, + declaration_map = True, + emit_declaration_only = True, + out_dir = "target_types", + root_dir = "src", + tsconfig = ":tsconfig", +) + +js_library( + name = PKG_DIRNAME, + srcs = NPM_MODULE_EXTRA_FILES, + deps = RUNTIME_DEPS + [":target_node", ":target_web"], + package_name = PKG_REQUIRE_NAME, + visibility = ["//visibility:public"], +) + +pkg_npm( + name = "npm_module", + deps = [":" + PKG_DIRNAME], +) + +filegroup( + name = "build", + srcs = [":npm_module"], + visibility = ["//visibility:public"], +) + +pkg_npm_types( + name = "npm_module_types", + srcs = SRCS, + deps = [":tsc_types"], + package_name = PKG_REQUIRE_NAME, + tsconfig = ":tsconfig", + visibility = ["//visibility:public"], +) + +filegroup( + name = "build_types", + srcs = [":npm_module_types"], + visibility = ["//visibility:public"], +) diff --git a/packages/shared-ux/page/no_data_config/mocks/README.md b/packages/shared-ux/page/no_data_config/mocks/README.md new file mode 100644 index 00000000000000..bcf739e2d96584 --- /dev/null +++ b/packages/shared-ux/page/no_data_config/mocks/README.md @@ -0,0 +1,3 @@ +# @kbn/shared-ux-page-no-data-config-mocks + +Empty package generated by @kbn/generate diff --git a/packages/shared-ux/page/no_data_config/mocks/package.json b/packages/shared-ux/page/no_data_config/mocks/package.json new file mode 100644 index 00000000000000..32245715f2b1ba --- /dev/null +++ b/packages/shared-ux/page/no_data_config/mocks/package.json @@ -0,0 +1,8 @@ +{ + "name": "@kbn/shared-ux-page-no-data-config-mocks", + "private": true, + "version": "1.0.0", + "main": "./target_node/index.js", + "browser": "./target_web/index.js", + "license": "SSPL-1.0 OR Elastic License 2.0" +} \ No newline at end of file diff --git a/src/plugins/shared_ux/common/index.ts b/packages/shared-ux/page/no_data_config/mocks/src/index.ts old mode 100755 new mode 100644 similarity index 62% rename from src/plugins/shared_ux/common/index.ts rename to packages/shared-ux/page/no_data_config/mocks/src/index.ts index 92dee001d90120..4e6911f89e37b2 --- a/src/plugins/shared_ux/common/index.ts +++ b/packages/shared-ux/page/no_data_config/mocks/src/index.ts @@ -6,8 +6,7 @@ * Side Public License, v 1. */ -/** The ID of the Shared UX plugin. */ -export const PLUGIN_ID = 'sharedUX'; +export { getServicesMock as getNoDataConfigPageServicesMock } from './jest'; -/** The name of the Shared UX plugin. */ -export const PLUGIN_NAME = 'sharedUX'; +export { NoDataConfigPageStorybookMock } from './storybook'; +export type { Params as NoDataConfigPageStorybookParams } from './storybook'; diff --git a/packages/shared-ux/page/no_data_config/mocks/src/jest.ts b/packages/shared-ux/page/no_data_config/mocks/src/jest.ts new file mode 100644 index 00000000000000..f4f2c48e4ce035 --- /dev/null +++ b/packages/shared-ux/page/no_data_config/mocks/src/jest.ts @@ -0,0 +1,33 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import type { + NoDataConfigPageServices, + NoDataConfigPageKibanaDependencies, +} from '@kbn/shared-ux-page-no-data-config-types'; + +import { + getNoDataPageServicesMock, + getNoDataPageKibanaDependenciesMock, +} from '@kbn/shared-ux-page-no-data-mocks'; + +export const getServicesMock = () => { + const services: NoDataConfigPageServices = { + ...getNoDataPageServicesMock(), + }; + + return services; +}; + +export const getKibanaDependenciesMock = () => { + const dependencies: NoDataConfigPageKibanaDependencies = { + ...getNoDataPageKibanaDependenciesMock(), + }; + + return dependencies; +}; diff --git a/packages/shared-ux/page/no_data_config/mocks/src/storybook.ts b/packages/shared-ux/page/no_data_config/mocks/src/storybook.ts new file mode 100644 index 00000000000000..5c36fc79f90a78 --- /dev/null +++ b/packages/shared-ux/page/no_data_config/mocks/src/storybook.ts @@ -0,0 +1,74 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { AbstractStorybookMock } from '@kbn/shared-ux-storybook-mock'; +import type { ArgumentParams } from '@kbn/shared-ux-storybook-mock'; + +import type { + NoDataConfig, + NoDataConfigPageProps, + NoDataConfigPageServices, +} from '@kbn/shared-ux-page-no-data-config-types'; +import { NoDataPageStorybookMock } from '@kbn/shared-ux-page-no-data-mocks'; +import type { NoDataPageStorybookParams } from '@kbn/shared-ux-page-no-data-mocks'; + +type PropArguments = Pick; + +export type Params = ArgumentParams & NoDataPageStorybookParams; + +const dataPageMock = new NoDataPageStorybookMock(); + +export class NoDataConfigPageStorybookMock extends AbstractStorybookMock< + NoDataConfigPageProps, + NoDataConfigPageServices, + PropArguments +> { + propArguments = { + solution: { + control: 'text', + defaultValue: 'Observability', + }, + logo: { + control: { type: 'radio' }, + options: ['logoElastic', 'logoKibana', 'logoCloud', undefined], + defaultValue: undefined, + }, + docsLink: { + control: 'text', + defaultValue: 'docs/link', + }, + pageTitle: { + control: 'text', + defaultValue: '', + }, + }; + + serviceArguments = {}; + + dependencies = [dataPageMock]; + + getProps(params?: Params): NoDataConfigPageProps { + return { + noDataConfig: { + action: { + elasticAgent: { + title: 'Add Integrations', + }, + }, + solution: this.getArgumentValue('solution', params), + logo: this.getArgumentValue('logo', params), + docsLink: this.getArgumentValue('docsLink', params), + pageTitle: this.getArgumentValue('pageTitle', params), + }, + }; + } + + getServices(params: Params): NoDataConfigPageServices { + return { ...dataPageMock.getServices(params) }; + } +} diff --git a/packages/shared-ux/page/no_data_config/mocks/tsconfig.json b/packages/shared-ux/page/no_data_config/mocks/tsconfig.json new file mode 100644 index 00000000000000..dc96ec41f9035d --- /dev/null +++ b/packages/shared-ux/page/no_data_config/mocks/tsconfig.json @@ -0,0 +1,20 @@ +{ + "extends": "../../../../../tsconfig.bazel.json", + "compilerOptions": { + "declaration": true, + "declarationMap": true, + "emitDeclarationOnly": true, + "outDir": "target_types", + "rootDir": "src", + "stripInternal": false, + "types": [ + "jest", + "node", + "react" + ] + }, + "include": [ + "**/*.ts", + "**/*.tsx", + ] +} diff --git a/packages/shared-ux/page/no_data_config/types/BUILD.bazel b/packages/shared-ux/page/no_data_config/types/BUILD.bazel new file mode 100644 index 00000000000000..6fa1669fcc1763 --- /dev/null +++ b/packages/shared-ux/page/no_data_config/types/BUILD.bazel @@ -0,0 +1,59 @@ +load("@npm//@bazel/typescript:index.bzl", "ts_config") +load("@build_bazel_rules_nodejs//:index.bzl", "js_library") +load("//src/dev/bazel:index.bzl", "jsts_transpiler", "pkg_npm", "pkg_npm_types", "ts_project") + +PKG_DIRNAME = "types" +PKG_REQUIRE_NAME = "@kbn/shared-ux-page-no-data-config-types" + +SRCS = glob( + [ + "*.d.ts", + ] +) + +filegroup( + name = "srcs", + srcs = SRCS, +) + +NPM_MODULE_EXTRA_FILES = [ + "package.json", +] + +# In this array place runtime dependencies, including other packages and NPM packages +# which must be available for this code to run. +# +# To reference other packages use: +# "//repo/relative/path/to/package" +# eg. "//packages/kbn-utils" +# +# To reference a NPM package use: +# "@npm//name-of-package" +# eg. "@npm//lodash" +RUNTIME_DEPS = [ +] + +js_library( + name = PKG_DIRNAME, + srcs = SRCS + NPM_MODULE_EXTRA_FILES, + deps = RUNTIME_DEPS, + package_name = PKG_REQUIRE_NAME, + visibility = ["//visibility:public"], +) + +pkg_npm( + name = "npm_module", + deps = [":" + PKG_DIRNAME], +) + +filegroup( + name = "build", + srcs = [":npm_module"], + visibility = ["//visibility:public"], +) + +alias( + name = "npm_module_types", + actual = ":" + PKG_DIRNAME, + visibility = ["//visibility:public"], +) diff --git a/packages/shared-ux/page/no_data_config/types/README.md b/packages/shared-ux/page/no_data_config/types/README.md new file mode 100644 index 00000000000000..dd146f60dcf4bb --- /dev/null +++ b/packages/shared-ux/page/no_data_config/types/README.md @@ -0,0 +1,3 @@ +# @kbn/shared-ux-page-no-data-config-types + +Empty package generated by @kbn/generate diff --git a/packages/shared-ux/page/no_data_config/types/index.d.ts b/packages/shared-ux/page/no_data_config/types/index.d.ts new file mode 100644 index 00000000000000..10950bcf296c8c --- /dev/null +++ b/packages/shared-ux/page/no_data_config/types/index.d.ts @@ -0,0 +1,27 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { EuiPageTemplateProps } from '@elastic/eui'; + +import type { + NoDataPageProps, + NoDataPageServices, + NoDataPageKibanaDependencies, +} from '@kbn/shared-ux-page-no-data-types'; + +export type NoDataConfigPageKibanaDependencies = NoDataPageKibanaDependencies; +export type NoDataConfigPageServices = NoDataPageServices; +export type NoDataConfig = NoDataPageProps; + +export type NoDataConfigPageProps = EuiPageTemplateProps & { + /** + * Accepts a configuration object, that when provided, ignores pageHeader and children and instead + * displays Agent, Beats, and custom cards to direct users to the right ingest location + */ + noDataConfig?: NoDataConfig; +}; diff --git a/packages/shared-ux/page/no_data_config/types/package.json b/packages/shared-ux/page/no_data_config/types/package.json new file mode 100644 index 00000000000000..1af47fb4c50285 --- /dev/null +++ b/packages/shared-ux/page/no_data_config/types/package.json @@ -0,0 +1,7 @@ +{ + "name": "@kbn/shared-ux-page-no-data-config-types", + "private": true, + "version": "1.0.0", + "main": "./target_node/index.js", + "license": "SSPL-1.0 OR Elastic License 2.0" +} diff --git a/packages/shared-ux/page/no_data_config/types/tsconfig.json b/packages/shared-ux/page/no_data_config/types/tsconfig.json new file mode 100644 index 00000000000000..7a4adfcdbecff6 --- /dev/null +++ b/packages/shared-ux/page/no_data_config/types/tsconfig.json @@ -0,0 +1,14 @@ +{ + "extends": "../../../../../tsconfig.bazel.json", + "compilerOptions": { + "declaration": true, + "declarationMap": true, + "emitDeclarationOnly": true, + "outDir": "target_types", + "stripInternal": false, + "types": [] + }, + "include": [ + "*.d.ts" + ] +} diff --git a/packages/shared-ux/page/solution_nav/src/solution_nav.stories.tsx b/packages/shared-ux/page/solution_nav/src/solution_nav.stories.tsx index 9613fbac42f6e0..2f22aad1737714 100644 --- a/packages/shared-ux/page/solution_nav/src/solution_nav.stories.tsx +++ b/packages/shared-ux/page/solution_nav/src/solution_nav.stories.tsx @@ -11,7 +11,7 @@ import { action } from '@storybook/addon-actions'; import { SolutionNav as Component, SolutionNavProps } from './solution_nav'; export default { - title: 'Page Template', + title: 'Page/Solution Nav', description: 'Solution-specific navigation for the sidebar', }; diff --git a/packages/shared-ux/prompt/no_data_views/impl/src/index.ts b/packages/shared-ux/prompt/no_data_views/impl/src/index.ts index 9483e5406da4c2..48afcb79369974 100644 --- a/packages/shared-ux/prompt/no_data_views/impl/src/index.ts +++ b/packages/shared-ux/prompt/no_data_views/impl/src/index.ts @@ -8,7 +8,7 @@ export type { NoDataViewsPromptComponentProps, - NoDataViewsPromptKibanaServices, + NoDataViewsPromptKibanaDependencies, NoDataViewsPromptProps, NoDataViewsPromptServices, } from '@kbn/shared-ux-prompt-no-data-views-types'; diff --git a/packages/shared-ux/prompt/no_data_views/impl/src/no_data_views.stories.tsx b/packages/shared-ux/prompt/no_data_views/impl/src/no_data_views.stories.tsx index 56d4ec63d2eaa5..748687fbda5e83 100644 --- a/packages/shared-ux/prompt/no_data_views/impl/src/no_data_views.stories.tsx +++ b/packages/shared-ux/prompt/no_data_views/impl/src/no_data_views.stories.tsx @@ -29,7 +29,7 @@ export default { const mock = new NoDataViewsPromptStorybookMock(); -export const NoDataViews = (params: NoDataViewsPromptStorybookParams) => { +export const Prompt = (params: NoDataViewsPromptStorybookParams) => { return ( @@ -37,4 +37,4 @@ export const NoDataViews = (params: NoDataViewsPromptStorybookParams) => { ); }; -NoDataViews.argTypes = mock.getArgumentTypes(); +Prompt.argTypes = mock.getArgumentTypes(); diff --git a/packages/shared-ux/prompt/no_data_views/impl/src/services.tsx b/packages/shared-ux/prompt/no_data_views/impl/src/services.tsx index cf6236429441fb..b8fe90e1ef135d 100644 --- a/packages/shared-ux/prompt/no_data_views/impl/src/services.tsx +++ b/packages/shared-ux/prompt/no_data_views/impl/src/services.tsx @@ -9,7 +9,7 @@ import React, { FC, useContext } from 'react'; import type { NoDataViewsPromptServices, - NoDataViewsPromptKibanaServices, + NoDataViewsPromptKibanaDependencies, } from '@kbn/shared-ux-prompt-no-data-views-types'; const NoDataViewsPromptContext = React.createContext(null); @@ -37,7 +37,7 @@ export const NoDataViewsPromptProvider: FC = ({ /** * Kibana-specific Provider that maps to known dependency types. */ -export const NoDataViewsPromptKibanaProvider: FC = ({ +export const NoDataViewsPromptKibanaProvider: FC = ({ children, ...services }) => { diff --git a/packages/shared-ux/prompt/no_data_views/mocks/BUILD.bazel b/packages/shared-ux/prompt/no_data_views/mocks/BUILD.bazel index 21099840dc91e5..6f725e99b61475 100644 --- a/packages/shared-ux/prompt/no_data_views/mocks/BUILD.bazel +++ b/packages/shared-ux/prompt/no_data_views/mocks/BUILD.bazel @@ -10,8 +10,17 @@ SOURCE_FILES = glob( "src/**/*.ts", ], exclude = [ + "**/*.config.js", + "**/*.mock.*", "**/*.test.*", "**/*.stories.*", + "**/__snapshots__", + "**/integration_tests", + "**/mocks", + "**/scripts", + "**/storybook", + "**/test_fixtures", + "**/test_helpers", ], ) @@ -38,6 +47,7 @@ NPM_MODULE_EXTRA_FILES = [ # eg. "@npm//lodash" RUNTIME_DEPS = [ "@npm//@storybook/addon-actions", + "@npm//react", "//packages/shared-ux/storybook/mock", ] @@ -51,9 +61,10 @@ RUNTIME_DEPS = [ # # References to NPM packages work the same as RUNTIME_DEPS TYPES_DEPS = [ - "@npm//@types/node", - "@npm//@types/jest", "@npm//@storybook/addon-actions", + "@npm//@types/jest", + "@npm//@types/node", + "@npm//@types/react", "//packages/shared-ux/prompt/no_data_views/types:npm_module_types", "//packages/shared-ux/storybook/mock:npm_module_types", ] @@ -65,6 +76,14 @@ jsts_transpiler( root_input_dir = "src", ) +jsts_transpiler( + name = "target_web", + srcs = SRCS, + build_pkg_name = package_name(), + root_input_dir = "src", + web = True, +) + ts_config( name = "tsconfig", src = "tsconfig.json", @@ -90,7 +109,7 @@ ts_project( js_library( name = PKG_DIRNAME, srcs = NPM_MODULE_EXTRA_FILES, - deps = RUNTIME_DEPS + [":target_node"], + deps = RUNTIME_DEPS + [":target_node", ":target_web"], package_name = PKG_REQUIRE_NAME, visibility = ["//visibility:public"], ) diff --git a/packages/shared-ux/prompt/no_data_views/mocks/jest.config.js b/packages/shared-ux/prompt/no_data_views/mocks/jest.config.js deleted file mode 100644 index 1efd78b09a8b14..00000000000000 --- a/packages/shared-ux/prompt/no_data_views/mocks/jest.config.js +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -module.exports = { - preset: '@kbn/test/jest_node', - rootDir: '../../../../..', - roots: ['/packages/shared-ux/prompt/no_data_views/mocks'], -}; diff --git a/packages/shared-ux/prompt/no_data_views/mocks/package.json b/packages/shared-ux/prompt/no_data_views/mocks/package.json index b00c829ace8e52..2478bd3e76dd4a 100644 --- a/packages/shared-ux/prompt/no_data_views/mocks/package.json +++ b/packages/shared-ux/prompt/no_data_views/mocks/package.json @@ -3,5 +3,6 @@ "private": true, "version": "1.0.0", "main": "./target_node/index.js", + "browser": "./target_web/index.js", "license": "SSPL-1.0 OR Elastic License 2.0" } \ No newline at end of file diff --git a/packages/shared-ux/prompt/no_data_views/mocks/tsconfig.json b/packages/shared-ux/prompt/no_data_views/mocks/tsconfig.json index 894f01d3220e91..dc96ec41f9035d 100644 --- a/packages/shared-ux/prompt/no_data_views/mocks/tsconfig.json +++ b/packages/shared-ux/prompt/no_data_views/mocks/tsconfig.json @@ -9,10 +9,12 @@ "stripInternal": false, "types": [ "jest", - "node" + "node", + "react" ] }, "include": [ - "src/**/*" + "**/*.ts", + "**/*.tsx", ] } diff --git a/packages/shared-ux/prompt/no_data_views/types/index.d.ts b/packages/shared-ux/prompt/no_data_views/types/index.d.ts index e143e4e6d035c9..4b428cc64ad3d1 100644 --- a/packages/shared-ux/prompt/no_data_views/types/index.d.ts +++ b/packages/shared-ux/prompt/no_data_views/types/index.d.ts @@ -42,7 +42,7 @@ export interface NoDataViewsPromptServices { /** * Kibana-specific service types. */ -export interface NoDataViewsPromptKibanaServices { +export interface NoDataViewsPromptKibanaDependencies { coreStart: { docLinks: { links: { diff --git a/packages/kbn-shared-ux-storybook/BUILD.bazel b/packages/shared-ux/storybook/config/BUILD.bazel similarity index 88% rename from packages/kbn-shared-ux-storybook/BUILD.bazel rename to packages/shared-ux/storybook/config/BUILD.bazel index 4f710f2dbe120d..1f35734bb21472 100644 --- a/packages/kbn-shared-ux-storybook/BUILD.bazel +++ b/packages/shared-ux/storybook/config/BUILD.bazel @@ -2,16 +2,25 @@ load("@npm//@bazel/typescript:index.bzl", "ts_config") load("@build_bazel_rules_nodejs//:index.bzl", "js_library") load("//src/dev/bazel:index.bzl", "jsts_transpiler", "pkg_npm", "pkg_npm_types", "ts_project") -PKG_DIRNAME = "kbn-shared-ux-storybook" -PKG_REQUIRE_NAME = "@kbn/shared-ux-storybook" +PKG_DIRNAME = "config" +PKG_REQUIRE_NAME = "@kbn/shared-ux-storybook-config" SOURCE_FILES = glob( [ - "src/**/*.ts", - "src/**/*.tsx", + "**/*.ts", ], exclude = [ + "**/*.config.js", + "**/*.mock.*", "**/*.test.*", + "**/*.stories.*", + "**/__snapshots__", + "**/integration_tests", + "**/mocks", + "**/scripts", + "**/storybook", + "**/test_fixtures", + "**/test_helpers", ], ) @@ -37,10 +46,10 @@ NPM_MODULE_EXTRA_FILES = [ # "@npm//name-of-package" # eg. "@npm//lodash" RUNTIME_DEPS = [ - "//packages/kbn-shared-ux-services", "//packages/kbn-storybook", "@npm//@storybook/react", "@npm//@storybook/addon-actions", + "@npm//jest-mock", ] # In this array place dependencies necessary to build the types, which will include the @@ -53,7 +62,7 @@ RUNTIME_DEPS = [ # # References to NPM packages work the same as RUNTIME_DEPS TYPES_DEPS = [ - "//packages/kbn-shared-ux-services:npm_module_types", + "@npm//jest-mock", "//packages/kbn-storybook:npm_module_types", "//packages/kbn-ambient-ui-types:npm_module_types", "//packages/kbn-ambient-storybook-types:npm_module_types", @@ -67,14 +76,12 @@ jsts_transpiler( name = "target_node", srcs = SRCS, build_pkg_name = package_name(), - root_input_dir = "src", ) jsts_transpiler( name = "target_web", srcs = SRCS, build_pkg_name = package_name(), - root_input_dir = "src", web = True, ) @@ -96,7 +103,7 @@ ts_project( declaration_map = True, emit_declaration_only = True, out_dir = "target_types", - root_dir = "src", + root_dir = ".", tsconfig = ":tsconfig", ) diff --git a/packages/shared-ux/storybook/config/README.mdx b/packages/shared-ux/storybook/config/README.mdx new file mode 100644 index 00000000000000..eeab8f1f4c987c --- /dev/null +++ b/packages/shared-ux/storybook/config/README.mdx @@ -0,0 +1,3 @@ +# @kbn/shared-ux-storybook-config + +Storybook configuration used by `yarn storybook`. Refer to `@kbn/storybook` for more information. diff --git a/packages/kbn-shared-ux-components/src/page_template/util/presentation.ts b/packages/shared-ux/storybook/config/constants.ts similarity index 58% rename from packages/kbn-shared-ux-components/src/page_template/util/presentation.ts rename to packages/shared-ux/storybook/config/constants.ts index ab7144ee37b579..8efe045ad57a1e 100644 --- a/packages/kbn-shared-ux-components/src/page_template/util/presentation.ts +++ b/packages/shared-ux/storybook/config/constants.ts @@ -6,8 +6,8 @@ * Side Public License, v 1. */ -import classNames from 'classnames'; +/** The title of the Storybook. */ +export const TITLE = 'Shared UX Storybook'; -export const getClasses = (template: string | undefined, className: string | undefined) => { - return classNames('kbnPageTemplate', { [`kbnPageTemplate--${template}`]: template }, className); -}; +/** The remote URL of the root from which Storybook loads stories for Shared UX. */ +export const URL = 'https://github.com/elastic/kibana/tree/main/packages/shared_ux'; diff --git a/src/plugins/charts/public/static/utils/index.ts b/packages/shared-ux/storybook/config/index.ts similarity index 89% rename from src/plugins/charts/public/static/utils/index.ts rename to packages/shared-ux/storybook/config/index.ts index efb6e72823d735..5a73da614bf279 100644 --- a/src/plugins/charts/public/static/utils/index.ts +++ b/packages/shared-ux/storybook/config/index.ts @@ -6,4 +6,4 @@ * Side Public License, v 1. */ -export * from './transform_click_event'; +export { TITLE, URL } from './constants'; diff --git a/packages/kbn-shared-ux-storybook/src/config/main.ts b/packages/shared-ux/storybook/config/main.ts similarity index 72% rename from packages/kbn-shared-ux-storybook/src/config/main.ts rename to packages/shared-ux/storybook/config/main.ts index 6e57ca8ad5e72a..47a47a5a802b3b 100644 --- a/packages/kbn-shared-ux-storybook/src/config/main.ts +++ b/packages/shared-ux/storybook/config/main.ts @@ -10,11 +10,7 @@ import { defaultConfig } from '@kbn/storybook'; module.exports = { ...defaultConfig, - stories: [ - '../../../shared-ux/**/*.stories.+(tsx|mdx)', - '../../../kbn-shared-ux*/**/*.stories.+(tsx|mdx)', - '../../../../src/plugins/shared_ux/**/*.stories.+(tsx|mdx)', - ], + stories: ['../../**/*.stories.+(tsx|mdx)'], reactOptions: { strictMode: true, }, diff --git a/packages/kbn-shared-ux-storybook/src/config/manager.ts b/packages/shared-ux/storybook/config/manager.ts similarity index 72% rename from packages/kbn-shared-ux-storybook/src/config/manager.ts rename to packages/shared-ux/storybook/config/manager.ts index 64284fb46f36f6..fb973258b9053f 100644 --- a/packages/kbn-shared-ux-storybook/src/config/manager.ts +++ b/packages/shared-ux/storybook/config/manager.ts @@ -8,14 +8,16 @@ import { addons } from '@storybook/addons'; import { create } from '@storybook/theming'; -import { PANEL_ID } from '@storybook/addon-actions'; +import { PANEL_ID as selectedPanel } from '@storybook/addon-actions'; + +import { TITLE as brandTitle, URL as brandUrl } from './constants'; addons.setConfig({ theme: create({ base: 'light', - brandTitle: 'Shared UX Storybook', - brandUrl: 'https://github.com/elastic/kibana/tree/main/src/plugins/shared_ux', + brandTitle, + brandUrl, }), + selectedPanel, showPanel: true.valueOf, - selectedPanel: PANEL_ID, }); diff --git a/packages/kbn-shared-ux-components/package.json b/packages/shared-ux/storybook/config/package.json similarity index 78% rename from packages/kbn-shared-ux-components/package.json rename to packages/shared-ux/storybook/config/package.json index 948df7fadd7127..ee7206b2d87dfb 100644 --- a/packages/kbn-shared-ux-components/package.json +++ b/packages/shared-ux/storybook/config/package.json @@ -1,8 +1,8 @@ { - "name": "@kbn/shared-ux-components", + "name": "@kbn/shared-ux-storybook-config", "private": true, "version": "1.0.0", "main": "./target_node/index.js", "browser": "./target_web/index.js", "license": "SSPL-1.0 OR Elastic License 2.0" -} +} \ No newline at end of file diff --git a/packages/shared-ux/storybook/config/preview.ts b/packages/shared-ux/storybook/config/preview.ts new file mode 100644 index 00000000000000..5a53e48a916d8c --- /dev/null +++ b/packages/shared-ux/storybook/config/preview.ts @@ -0,0 +1,21 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +/* eslint-disable @typescript-eslint/no-namespace,@typescript-eslint/no-empty-interface */ +declare global { + namespace NodeJS { + interface Global {} + interface InspectOptions {} + type ConsoleConstructor = console.ConsoleConstructor; + } +} +/* eslint-enable */ + +import jest from 'jest-mock'; +/* @ts-expect-error TS doesn't see jest as a property of window, and I don't want to edit our global config. */ +window.jest = jest; diff --git a/packages/kbn-shared-ux-storybook/tsconfig.json b/packages/shared-ux/storybook/config/tsconfig.json similarity index 78% rename from packages/kbn-shared-ux-storybook/tsconfig.json rename to packages/shared-ux/storybook/config/tsconfig.json index b26c95a01dfd83..835b78a44758da 100644 --- a/packages/kbn-shared-ux-storybook/tsconfig.json +++ b/packages/shared-ux/storybook/config/tsconfig.json @@ -1,11 +1,11 @@ { - "extends": "../../tsconfig.bazel.json", + "extends": "../../../../tsconfig.bazel.json", "compilerOptions": { "declaration": true, "declarationMap": true, "emitDeclarationOnly": true, "outDir": "target_types", - "rootDir": "src", + "rootDir": ".", "stripInternal": false, "types": [ "jest", @@ -14,6 +14,6 @@ ] }, "include": [ - "src/**/*" + "*.ts" ] } diff --git a/packages/shared-ux/storybook/mock/BUILD.bazel b/packages/shared-ux/storybook/mock/BUILD.bazel index 71b1a263ea0afb..c77d05261bc1de 100644 --- a/packages/shared-ux/storybook/mock/BUILD.bazel +++ b/packages/shared-ux/storybook/mock/BUILD.bazel @@ -10,8 +10,17 @@ SOURCE_FILES = glob( "src/**/*.ts", ], exclude = [ + "**/*.config.js", + "**/*.mock.*", "**/*.test.*", "**/*.stories.*", + "**/__snapshots__", + "**/integration_tests", + "**/mocks", + "**/scripts", + "**/storybook", + "**/test_fixtures", + "**/test_helpers", ], ) @@ -37,6 +46,8 @@ NPM_MODULE_EXTRA_FILES = [ # "@npm//name-of-package" # eg. "@npm//lodash" RUNTIME_DEPS = [ + "@npm//@storybook/react", + "@npm//react", ] # In this array place dependencies necessary to build the types, which will include the @@ -49,9 +60,10 @@ RUNTIME_DEPS = [ # # References to NPM packages work the same as RUNTIME_DEPS TYPES_DEPS = [ - "@npm//@types/node", - "@npm//@types/jest", "@npm//@storybook/react", + "@npm//@types/jest", + "@npm//@types/node", + "@npm//@types/react", ] jsts_transpiler( @@ -61,6 +73,14 @@ jsts_transpiler( root_input_dir = "src", ) +jsts_transpiler( + name = "target_web", + srcs = SRCS, + build_pkg_name = package_name(), + root_input_dir = "src", + web = True, +) + ts_config( name = "tsconfig", src = "tsconfig.json", @@ -86,7 +106,7 @@ ts_project( js_library( name = PKG_DIRNAME, srcs = NPM_MODULE_EXTRA_FILES, - deps = RUNTIME_DEPS + [":target_node"], + deps = RUNTIME_DEPS + [":target_node", ":target_web"], package_name = PKG_REQUIRE_NAME, visibility = ["//visibility:public"], ) diff --git a/packages/shared-ux/storybook/mock/package.json b/packages/shared-ux/storybook/mock/package.json index 18761aab4c92c2..0baee9437cac06 100644 --- a/packages/shared-ux/storybook/mock/package.json +++ b/packages/shared-ux/storybook/mock/package.json @@ -3,5 +3,6 @@ "private": true, "version": "1.0.0", "main": "./target_node/index.js", + "browser": "./target_web/index.js", "license": "SSPL-1.0 OR Elastic License 2.0" } \ No newline at end of file diff --git a/packages/shared-ux/storybook/mock/tsconfig.json b/packages/shared-ux/storybook/mock/tsconfig.json index 39d3c7097814ac..7b7386979c9a8e 100644 --- a/packages/shared-ux/storybook/mock/tsconfig.json +++ b/packages/shared-ux/storybook/mock/tsconfig.json @@ -9,10 +9,12 @@ "stripInternal": false, "types": [ "jest", - "node" + "node", + "react" ] }, "include": [ - "src/**/*" + "**/*.ts", + "**/*.tsx", ] } diff --git a/renovate.json b/renovate.json index 49337a00d7246d..7f60faf4a0a62f 100644 --- a/renovate.json +++ b/renovate.json @@ -168,7 +168,7 @@ }, { "groupName": "react-query", - "packageNames": ["react-query"], + "packageNames": ["@tanstack/react-query", "@tanstack/react-query-devtools"], "reviewers": [ "team:response-ops", "team:kibana-cloud-security-posture", @@ -180,6 +180,17 @@ "matchBaseBranches": ["main"], "labels": ["release_note:skip", "backport:skip", "ci:all-cypress-suites"], "enabled": true + }, + { + "groupName": "react-hook-form", + "packageNames": ["react-hook-form"], + "reviewers": [ + "team:security-asset-management", + "team:uptime" + ], + "matchBaseBranches": ["main"], + "labels": ["release_note:skip", "backport:skip", "ci:all-cypress-suites"], + "enabled": true } ] } diff --git a/scripts/synthtrace.js b/scripts/synthtrace.js index 5e551acf847698..bffa55065a17fe 100644 --- a/scripts/synthtrace.js +++ b/scripts/synthtrace.js @@ -9,8 +9,8 @@ require('../src/setup_node_env'); // We have to import directly from package since scenarios and worker.js are imported dynamically, -// If we import the package (require('@elastic/apm-synthtrace')) the program will be executed on the compiled files, and thus we need to +// If we import the package (require('@kbn/apm-synthtrace')) the program will be executed on the compiled files, and thus we need to // compile scenarios with `yarn kbn bootstrap` every time scenario changes. // eslint-disable-next-line @kbn/imports/uniform_imports -require('../packages/elastic-apm-synthtrace/src/cli').runSynthtrace(); +require('../packages/kbn-apm-synthtrace/src/cli').runSynthtrace(); diff --git a/src/cli/command.js b/src/cli/command.js index 6174cab85dec3f..b85037330027b8 100644 --- a/src/cli/command.js +++ b/src/cli/command.js @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import { set } from '@elastic/safer-lodash-set'; +import { set } from '@kbn/safer-lodash-set'; import _ from 'lodash'; import Chalk from 'chalk'; diff --git a/src/cli/keystore/read_keystore.js b/src/cli/keystore/read_keystore.js index d3629c32671f74..a4f007690a661d 100644 --- a/src/cli/keystore/read_keystore.js +++ b/src/cli/keystore/read_keystore.js @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import { set } from '@elastic/safer-lodash-set'; +import { set } from '@kbn/safer-lodash-set'; import { Keystore } from '.'; import { getKeystore } from '../../cli_keystore/get_keystore'; diff --git a/src/cli/serve/serve.js b/src/cli/serve/serve.js index 6425b0d6c80050..d5c1f844c4d1c9 100644 --- a/src/cli/serve/serve.js +++ b/src/cli/serve/serve.js @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import { set as lodashSet } from '@elastic/safer-lodash-set'; +import { set as lodashSet } from '@kbn/safer-lodash-set'; import _ from 'lodash'; import { statSync } from 'fs'; import { resolve } from 'path'; diff --git a/src/core/server/core_usage_data/core_usage_data_service.test.ts b/src/core/server/core_usage_data/core_usage_data_service.test.ts index c45b3fdb0a1250..5ac2863745ee7a 100644 --- a/src/core/server/core_usage_data/core_usage_data_service.test.ts +++ b/src/core/server/core_usage_data/core_usage_data_service.test.ts @@ -18,14 +18,14 @@ import { mockCoreContext } from '@kbn/core-base-server-mocks'; import { config as RawLoggingConfig } from '@kbn/core-logging-server-internal'; import { config as RawElasticsearchConfig } from '@kbn/core-elasticsearch-server-internal'; import { config as RawHttpConfig } from '@kbn/core-http-server-internal'; -import { savedObjectsConfig as RawSavedObjectsConfig } from '../saved_objects/saved_objects_config'; +import { savedObjectsConfig as RawSavedObjectsConfig } from '@kbn/core-saved-objects-base-server-internal'; import { httpServiceMock } from '@kbn/core-http-server-mocks'; import { metricsServiceMock } from '@kbn/core-metrics-server-mocks'; import { savedObjectsServiceMock } from '../saved_objects/saved_objects_service.mock'; import { CoreUsageDataService } from './core_usage_data_service'; import { elasticsearchServiceMock } from '@kbn/core-elasticsearch-server-mocks'; -import { typeRegistryMock } from '../saved_objects/saved_objects_type_registry.mock'; +import { typeRegistryMock } from '@kbn/core-saved-objects-base-server-mocks'; import { CORE_USAGE_STATS_TYPE } from './constants'; import { CoreUsageStatsClient } from './core_usage_stats_client'; diff --git a/src/core/server/core_usage_data/core_usage_data_service.ts b/src/core/server/core_usage_data/core_usage_data_service.ts index f1e51a7e5f5aa1..c5f2335e333e47 100644 --- a/src/core/server/core_usage_data/core_usage_data_service.ts +++ b/src/core/server/core_usage_data/core_usage_data_service.ts @@ -23,9 +23,12 @@ import type { HttpConfigType, InternalHttpServiceSetup } from '@kbn/core-http-se import type { ElasticsearchServiceStart } from '@kbn/core-elasticsearch-server'; import type { ElasticsearchConfigType } from '@kbn/core-elasticsearch-server-internal'; import type { MetricsServiceSetup, OpsMetrics } from '@kbn/core-metrics-server'; -import { SavedObjectsServiceStart, SavedObjectTypeRegistry } from '..'; +import { + LEGACY_URL_ALIAS_TYPE, + type SavedObjectsConfigType, +} from '@kbn/core-saved-objects-base-server-internal'; -import { SavedObjectsConfigType } from '../saved_objects/saved_objects_config'; +import { SavedObjectsServiceStart, SavedObjectTypeRegistry } from '..'; import type { CoreServicesUsageData, CoreUsageData, @@ -36,7 +39,6 @@ import type { } from './types'; import { isConfigured } from './is_configured'; import { coreUsageStatsType } from './core_usage_stats'; -import { LEGACY_URL_ALIAS_TYPE } from '../saved_objects/object_types'; import { CORE_USAGE_STATS_TYPE } from './constants'; import { CoreUsageStatsClient } from './core_usage_stats_client'; import { CoreIncrementUsageCounter } from './types'; diff --git a/src/core/server/core_usage_data/core_usage_stats_client.test.ts b/src/core/server/core_usage_data/core_usage_stats_client.test.ts index 6bcaa38bd00620..9a6984f6b57855 100644 --- a/src/core/server/core_usage_data/core_usage_stats_client.test.ts +++ b/src/core/server/core_usage_data/core_usage_stats_client.test.ts @@ -29,8 +29,8 @@ import { LEGACY_DASHBOARDS_EXPORT_STATS_PREFIX, BULK_RESOLVE_STATS_PREFIX, } from './core_usage_stats_client'; +import { DEFAULT_NAMESPACE_STRING } from '@kbn/core-saved-objects-utils-server'; import { CoreUsageStatsClient } from '.'; -import { DEFAULT_NAMESPACE_STRING } from '../saved_objects/service/lib/utils'; describe('CoreUsageStatsClient', () => { const setup = (namespace?: string) => { diff --git a/src/core/server/core_usage_data/core_usage_stats_client.ts b/src/core/server/core_usage_data/core_usage_stats_client.ts index 2dd8c77fd18762..c14776ff7ed81e 100644 --- a/src/core/server/core_usage_data/core_usage_stats_client.ts +++ b/src/core/server/core_usage_data/core_usage_stats_client.ts @@ -6,9 +6,9 @@ * Side Public License, v 1. */ +import { DEFAULT_NAMESPACE_STRING } from '@kbn/core-saved-objects-utils-server'; import { CORE_USAGE_STATS_TYPE, CORE_USAGE_STATS_ID } from './constants'; import { CoreUsageStats } from './types'; -import { DEFAULT_NAMESPACE_STRING } from '../saved_objects/service/lib/utils'; import { ISavedObjectsRepository, SavedObjectsImportOptions, diff --git a/src/core/server/index.ts b/src/core/server/index.ts index 0f365366206d29..3327340c91a8cd 100644 --- a/src/core/server/index.ts +++ b/src/core/server/index.ts @@ -388,6 +388,12 @@ export type { ISavedObjectsSerializer, SavedObjectsRequestHandlerContext, } from '@kbn/core-saved-objects-server'; +export { + SavedObjectsErrorHelpers, + SavedObjectsUtils, + mergeSavedObjectMigrationMaps, +} from '@kbn/core-saved-objects-utils-server'; +export { SavedObjectTypeRegistry } from '@kbn/core-saved-objects-base-server-internal'; export type { SavedObjectsRepository, @@ -396,14 +402,7 @@ export type { SavedObjectsImporter, SavedObjectsImportError, } from './saved_objects'; -export { - SavedObjectsClient, - SavedObjectsErrorHelpers, - SavedObjectsSerializer, - SavedObjectTypeRegistry, - SavedObjectsUtils, - mergeSavedObjectMigrationMaps, -} from './saved_objects'; +export { SavedObjectsClient } from './saved_objects'; export type { IUiSettingsClient, diff --git a/src/core/server/integration_tests/saved_objects/routes/delete_unknown_types.test.ts b/src/core/server/integration_tests/saved_objects/routes/delete_unknown_types.test.ts index 4a13921750d1f0..b4a215169a3764 100644 --- a/src/core/server/integration_tests/saved_objects/routes/delete_unknown_types.test.ts +++ b/src/core/server/integration_tests/saved_objects/routes/delete_unknown_types.test.ts @@ -8,8 +8,8 @@ import supertest from 'supertest'; import { elasticsearchServiceMock } from '@kbn/core-elasticsearch-server-mocks'; +import { typeRegistryMock } from '@kbn/core-saved-objects-base-server-mocks'; import { registerDeleteUnknownTypesRoute } from '../../../saved_objects/routes/deprecations'; -import { typeRegistryMock } from '../../../saved_objects/saved_objects_type_registry.mock'; import { setupServer } from '../../../saved_objects/routes/test_utils'; import { SavedObjectsType } from '../../..'; import type { InternalSavedObjectsRequestHandlerContext } from '../../../saved_objects/internal_types'; diff --git a/src/core/server/integration_tests/saved_objects/routes/export.test.ts b/src/core/server/integration_tests/saved_objects/routes/export.test.ts index 358a23902d5e1a..b107d1266fe3ce 100644 --- a/src/core/server/integration_tests/saved_objects/routes/export.test.ts +++ b/src/core/server/integration_tests/saved_objects/routes/export.test.ts @@ -16,7 +16,7 @@ import { CoreUsageStatsClient } from '../../../core_usage_data'; import { coreUsageStatsClientMock } from '../../../core_usage_data/core_usage_stats_client.mock'; import { coreUsageDataServiceMock } from '../../../core_usage_data/core_usage_data_service.mock'; import { savedObjectsExporterMock } from '../../../saved_objects/export/saved_objects_exporter.mock'; -import { SavedObjectConfig } from '../../../saved_objects/saved_objects_config'; +import type { SavedObjectConfig } from '@kbn/core-saved-objects-base-server-internal'; import { registerExportRoute } from '../../../saved_objects/routes/export'; import { setupServer, createExportableType } from '../../../saved_objects/routes/test_utils'; import type { InternalSavedObjectsRequestHandlerContext } from '../../../saved_objects/internal_types'; diff --git a/src/core/server/integration_tests/saved_objects/routes/import.test.ts b/src/core/server/integration_tests/saved_objects/routes/import.test.ts index a9062b8d07919f..ec6a483e8ae1f0 100644 --- a/src/core/server/integration_tests/saved_objects/routes/import.test.ts +++ b/src/core/server/integration_tests/saved_objects/routes/import.test.ts @@ -9,14 +9,15 @@ jest.mock('uuid'); import supertest from 'supertest'; +import { SavedObjectsErrorHelpers } from '@kbn/core-saved-objects-utils-server'; import { registerImportRoute } from '../../../saved_objects/routes/import'; import { savedObjectsClientMock } from '../../../mocks'; import { CoreUsageStatsClient } from '../../../core_usage_data'; import { coreUsageStatsClientMock } from '../../../core_usage_data/core_usage_stats_client.mock'; import { coreUsageDataServiceMock } from '../../../core_usage_data/core_usage_data_service.mock'; -import { SavedObjectConfig } from '../../../saved_objects/saved_objects_config'; +import { SavedObjectConfig } from '@kbn/core-saved-objects-base-server-internal'; import { setupServer, createExportableType } from '../../../saved_objects/routes/test_utils'; -import { SavedObjectsErrorHelpers, SavedObjectsImporter } from '../../../saved_objects'; +import { SavedObjectsImporter } from '../../../saved_objects'; import type { InternalSavedObjectsRequestHandlerContext } from '../../../saved_objects/internal_types'; type SetupServerReturn = Awaited>; diff --git a/src/core/server/integration_tests/saved_objects/routes/resolve_import_errors.test.ts b/src/core/server/integration_tests/saved_objects/routes/resolve_import_errors.test.ts index defdbc5cfc1d61..5d26fde36fae48 100644 --- a/src/core/server/integration_tests/saved_objects/routes/resolve_import_errors.test.ts +++ b/src/core/server/integration_tests/saved_objects/routes/resolve_import_errors.test.ts @@ -15,7 +15,7 @@ import { CoreUsageStatsClient } from '../../../core_usage_data'; import { coreUsageStatsClientMock } from '../../../core_usage_data/core_usage_stats_client.mock'; import { coreUsageDataServiceMock } from '../../../core_usage_data/core_usage_data_service.mock'; import { setupServer, createExportableType } from '../../../saved_objects/routes/test_utils'; -import { SavedObjectConfig } from '../../../saved_objects/saved_objects_config'; +import { SavedObjectConfig } from '@kbn/core-saved-objects-base-server-internal'; import { SavedObjectsImporter } from '../../../saved_objects/import'; import type { InternalSavedObjectsRequestHandlerContext } from '../../../saved_objects/internal_types'; diff --git a/src/core/server/mocks.ts b/src/core/server/mocks.ts index a98eaf50554f2b..e2ae9a96b716d7 100644 --- a/src/core/server/mocks.ts +++ b/src/core/server/mocks.ts @@ -23,6 +23,7 @@ import { httpServiceMock } from '@kbn/core-http-server-mocks'; import { elasticsearchServiceMock } from '@kbn/core-elasticsearch-server-mocks'; import { metricsServiceMock } from '@kbn/core-metrics-server-mocks'; import { capabilitiesServiceMock } from '@kbn/core-capabilities-server-mocks'; +import { typeRegistryMock as savedObjectsTypeRegistryMock } from '@kbn/core-saved-objects-base-server-mocks'; import type { PluginInitializerContext, CoreSetup, @@ -34,7 +35,6 @@ import type { import { httpResourcesMock } from './http_resources/http_resources_service.mock'; import { savedObjectsServiceMock } from './saved_objects/saved_objects_service.mock'; import { savedObjectsClientMock } from './saved_objects/service/saved_objects_client.mock'; -import { typeRegistryMock as savedObjectsTypeRegistryMock } from './saved_objects/saved_objects_type_registry.mock'; import { renderingMock } from './rendering/rendering_service.mock'; import { uiSettingsServiceMock } from './ui_settings/ui_settings_service.mock'; import { SharedGlobalConfig } from './plugins'; @@ -47,12 +47,12 @@ export { configServiceMock, configDeprecationsMock } from '@kbn/config-mocks'; export { loggingSystemMock } from '@kbn/core-logging-server-mocks'; export { httpServerMock, sessionStorageMock, httpServiceMock } from '@kbn/core-http-server-mocks'; export { elasticsearchServiceMock } from '@kbn/core-elasticsearch-server-mocks'; +export { typeRegistryMock as savedObjectsTypeRegistryMock } from '@kbn/core-saved-objects-base-server-mocks'; export { httpResourcesMock } from './http_resources/http_resources_service.mock'; export { savedObjectsRepositoryMock } from './saved_objects/service/lib/repository.mock'; export { savedObjectsServiceMock } from './saved_objects/saved_objects_service.mock'; export { savedObjectsClientMock } from './saved_objects/service/saved_objects_client.mock'; export { migrationMocks } from './saved_objects/migrations/mocks'; -export { typeRegistryMock as savedObjectsTypeRegistryMock } from './saved_objects/saved_objects_type_registry.mock'; export { uiSettingsServiceMock } from './ui_settings/ui_settings_service.mock'; export { metricsServiceMock } from '@kbn/core-metrics-server-mocks'; export { renderingMock } from './rendering/rendering_service.mock'; diff --git a/src/core/server/plugins/legacy_config.ts b/src/core/server/plugins/legacy_config.ts index 4bee00d6157487..de86345c5b7ba3 100644 --- a/src/core/server/plugins/legacy_config.ts +++ b/src/core/server/plugins/legacy_config.ts @@ -16,8 +16,11 @@ import { ElasticsearchConfigType, config as elasticsearchConfig, } from '@kbn/core-elasticsearch-server-internal'; +import { + type SavedObjectsConfigType, + savedObjectsConfig, +} from '@kbn/core-saved-objects-base-server-internal'; import { SharedGlobalConfig, SharedGlobalConfigKeys } from './types'; -import { SavedObjectsConfigType, savedObjectsConfig } from '../saved_objects/saved_objects_config'; const createGlobalConfig = ({ elasticsearch, diff --git a/src/core/server/plugins/types.ts b/src/core/server/plugins/types.ts index d41be740018a7b..f8b20b66f50691 100644 --- a/src/core/server/plugins/types.ts +++ b/src/core/server/plugins/types.ts @@ -20,8 +20,7 @@ import type { import type { PluginName, PluginOpaqueId, PluginType } from '@kbn/core-base-common'; import type { NodeInfo } from '@kbn/core-node-server'; import type { ElasticsearchConfigType } from '@kbn/core-elasticsearch-server-internal'; - -import { SavedObjectsConfigType } from '../saved_objects/saved_objects_config'; +import type { SavedObjectsConfigType } from '@kbn/core-saved-objects-base-server-internal'; import { CorePreboot, CoreSetup, CoreStart } from '..'; type Maybe = T | undefined; diff --git a/src/core/server/saved_objects/deprecations/deprecation_factory.ts b/src/core/server/saved_objects/deprecations/deprecation_factory.ts index dea29cb7690ec8..d330577151a522 100644 --- a/src/core/server/saved_objects/deprecations/deprecation_factory.ts +++ b/src/core/server/saved_objects/deprecations/deprecation_factory.ts @@ -7,8 +7,8 @@ */ import type { ISavedObjectTypeRegistry } from '@kbn/core-saved-objects-server'; +import type { SavedObjectConfig } from '@kbn/core-saved-objects-base-server-internal'; import type { RegisterDeprecationsConfig } from '../../deprecations'; -import type { SavedObjectConfig } from '../saved_objects_config'; import { getUnknownTypesDeprecations } from './unknown_object_types'; interface GetDeprecationProviderOptions { diff --git a/src/core/server/saved_objects/deprecations/unknown_object_types.test.ts b/src/core/server/saved_objects/deprecations/unknown_object_types.test.ts index 51f228f46438b8..7e02f3343050df 100644 --- a/src/core/server/saved_objects/deprecations/unknown_object_types.test.ts +++ b/src/core/server/saved_objects/deprecations/unknown_object_types.test.ts @@ -9,7 +9,7 @@ import { getIndexForTypeMock } from './unknown_object_types.test.mocks'; import { deleteUnknownTypeObjects, getUnknownTypesDeprecations } from './unknown_object_types'; -import { typeRegistryMock } from '../saved_objects_type_registry.mock'; +import { typeRegistryMock } from '@kbn/core-saved-objects-base-server-mocks'; import { elasticsearchClientMock } from '@kbn/core-elasticsearch-client-server-mocks'; import { SavedObjectsType } from '../..'; import { createAggregateTypesSearchResponse } from '../migrations/actions/check_for_unknown_docs.mocks'; diff --git a/src/core/server/saved_objects/export/collect_exported_objects.test.ts b/src/core/server/saved_objects/export/collect_exported_objects.test.ts index 8aedffdd3745bd..480a80e23cc977 100644 --- a/src/core/server/saved_objects/export/collect_exported_objects.test.ts +++ b/src/core/server/saved_objects/export/collect_exported_objects.test.ts @@ -15,7 +15,7 @@ import type { import { applyExportTransformsMock } from './collect_exported_objects.test.mocks'; import { savedObjectsClientMock } from '../../mocks'; import { loggerMock } from '@kbn/logging-mocks'; -import { SavedObjectTypeRegistry } from '../saved_objects_type_registry'; +import { SavedObjectTypeRegistry } from '@kbn/core-saved-objects-base-server-internal'; import { collectExportedObjects, ExclusionReason } from './collect_exported_objects'; const createObject = (parts: Partial): SavedObject => ({ diff --git a/src/core/server/saved_objects/export/saved_objects_exporter.test.ts b/src/core/server/saved_objects/export/saved_objects_exporter.test.ts index 8b4604087141cf..55ee7642388ba2 100644 --- a/src/core/server/saved_objects/export/saved_objects_exporter.test.ts +++ b/src/core/server/saved_objects/export/saved_objects_exporter.test.ts @@ -8,9 +8,9 @@ import { httpServerMock } from '@kbn/core-http-server-mocks'; import type { SavedObject } from '@kbn/core-saved-objects-common'; +import { SavedObjectTypeRegistry } from '@kbn/core-saved-objects-base-server-internal'; import { SavedObjectsExporter } from './saved_objects_exporter'; import { savedObjectsClientMock } from '../service/saved_objects_client.mock'; -import { SavedObjectTypeRegistry } from '../saved_objects_type_registry'; import { loggerMock, MockedLogger } from '@kbn/logging-mocks'; import { Readable } from 'stream'; import { createPromiseFromStreams, createConcatStream } from '@kbn/utils'; diff --git a/src/core/server/saved_objects/import/import_saved_objects.test.ts b/src/core/server/saved_objects/import/import_saved_objects.test.ts index 71990a8438ef38..9a086537c4761c 100644 --- a/src/core/server/saved_objects/import/import_saved_objects.test.ts +++ b/src/core/server/saved_objects/import/import_saved_objects.test.ts @@ -30,8 +30,8 @@ import type { ISavedObjectTypeRegistry, SavedObjectsImportHook, } from '@kbn/core-saved-objects-server'; +import { typeRegistryMock } from '@kbn/core-saved-objects-base-server-mocks'; import { savedObjectsClientMock } from '../../mocks'; -import { typeRegistryMock } from '../saved_objects_type_registry.mock'; import { importSavedObjectsFromStream, ImportSavedObjectsOptions } from './import_saved_objects'; import type { ImportStateMap } from './lib'; diff --git a/src/core/server/saved_objects/import/lib/check_conflicts.test.ts b/src/core/server/saved_objects/import/lib/check_conflicts.test.ts index 3dcbeacae1a2d9..35be4e245086ce 100644 --- a/src/core/server/saved_objects/import/lib/check_conflicts.test.ts +++ b/src/core/server/saved_objects/import/lib/check_conflicts.test.ts @@ -13,7 +13,7 @@ import type { SavedObjectsImportRetry, } from '@kbn/core-saved-objects-common'; import type { SavedObjectsClientContract } from '@kbn/core-saved-objects-api-server'; -import { SavedObjectsErrorHelpers } from '../../service'; +import { SavedObjectsErrorHelpers } from '@kbn/core-saved-objects-utils-server'; import { checkConflicts } from './check_conflicts'; jest.mock('uuid', () => ({ diff --git a/src/core/server/saved_objects/import/lib/check_origin_conflicts.test.ts b/src/core/server/saved_objects/import/lib/check_origin_conflicts.test.ts index ed80c7cdf07510..756214e2ddc030 100644 --- a/src/core/server/saved_objects/import/lib/check_origin_conflicts.test.ts +++ b/src/core/server/saved_objects/import/lib/check_origin_conflicts.test.ts @@ -16,9 +16,9 @@ import type { } from '@kbn/core-saved-objects-common'; import type { SavedObjectsClientContract } from '@kbn/core-saved-objects-api-server'; import type { ISavedObjectTypeRegistry } from '@kbn/core-saved-objects-server'; +import { typeRegistryMock } from '@kbn/core-saved-objects-base-server-mocks'; import { checkOriginConflicts } from './check_origin_conflicts'; import { savedObjectsClientMock } from '../../../mocks'; -import { typeRegistryMock } from '../../saved_objects_type_registry.mock'; import type { ImportStateMap } from './types'; jest.mock('uuid', () => ({ diff --git a/src/core/server/saved_objects/import/lib/check_reference_origins.test.ts b/src/core/server/saved_objects/import/lib/check_reference_origins.test.ts index cff3a4d5540a0e..fce677ec6ea46f 100644 --- a/src/core/server/saved_objects/import/lib/check_reference_origins.test.ts +++ b/src/core/server/saved_objects/import/lib/check_reference_origins.test.ts @@ -15,7 +15,7 @@ import type { import type { ISavedObjectTypeRegistry } from '@kbn/core-saved-objects-server'; import { checkReferenceOrigins, CheckReferenceOriginsParams } from './check_reference_origins'; import { savedObjectsClientMock } from '../../../mocks'; -import { typeRegistryMock } from '../../saved_objects_type_registry.mock'; +import { typeRegistryMock } from '@kbn/core-saved-objects-base-server-mocks'; import type { ImportStateMap } from './types'; const MULTI_NS_TYPE = 'multi'; diff --git a/src/core/server/saved_objects/import/lib/create_saved_objects.test.ts b/src/core/server/saved_objects/import/lib/create_saved_objects.test.ts index a29765849c3649..363d2bee5899e6 100644 --- a/src/core/server/saved_objects/import/lib/create_saved_objects.test.ts +++ b/src/core/server/saved_objects/import/lib/create_saved_objects.test.ts @@ -9,8 +9,8 @@ import { savedObjectsClientMock } from '../../../mocks'; import type { SavedObject, SavedObjectsImportFailure } from '@kbn/core-saved-objects-common'; import { SavedObjectsClientContract } from '@kbn/core-saved-objects-api-server'; +import { SavedObjectsErrorHelpers } from '@kbn/core-saved-objects-utils-server'; import { createSavedObjects } from './create_saved_objects'; -import { SavedObjectsErrorHelpers } from '../../service'; import { extractErrors } from './extract_errors'; type CreateSavedObjectsParams = Parameters[0]; diff --git a/src/core/server/saved_objects/import/lib/extract_errors.test.ts b/src/core/server/saved_objects/import/lib/extract_errors.test.ts index 20a8d40b62a708..c4d3d0e4c27220 100644 --- a/src/core/server/saved_objects/import/lib/extract_errors.test.ts +++ b/src/core/server/saved_objects/import/lib/extract_errors.test.ts @@ -8,8 +8,8 @@ import type { SavedObject } from '@kbn/core-saved-objects-common'; import type { CreatedObject } from '@kbn/core-saved-objects-server'; +import { SavedObjectsErrorHelpers } from '@kbn/core-saved-objects-utils-server'; import { extractErrors } from './extract_errors'; -import { SavedObjectsErrorHelpers } from '../../service'; describe('extractErrors()', () => { test('returns empty array when no errors exist', () => { diff --git a/src/core/server/saved_objects/import/lib/validate_references.test.ts b/src/core/server/saved_objects/import/lib/validate_references.test.ts index 2e6f1a5e0a9a27..2a8095ef78ce88 100644 --- a/src/core/server/saved_objects/import/lib/validate_references.test.ts +++ b/src/core/server/saved_objects/import/lib/validate_references.test.ts @@ -6,10 +6,10 @@ * Side Public License, v 1. */ +import { SavedObjectsErrorHelpers } from '@kbn/core-saved-objects-utils-server'; import type { ValidateReferencesParams } from './validate_references'; import { validateReferences } from './validate_references'; import { savedObjectsClientMock } from '../../../mocks'; -import { SavedObjectsErrorHelpers } from '../../service'; function setup({ objects = [], diff --git a/src/core/server/saved_objects/import/resolve_import_errors.test.ts b/src/core/server/saved_objects/import/resolve_import_errors.test.ts index bc297182b281d6..288e58aabb4c2f 100644 --- a/src/core/server/saved_objects/import/resolve_import_errors.test.ts +++ b/src/core/server/saved_objects/import/resolve_import_errors.test.ts @@ -36,8 +36,8 @@ import type { ISavedObjectTypeRegistry, SavedObjectsImportHook, } from '@kbn/core-saved-objects-server'; +import { typeRegistryMock } from '@kbn/core-saved-objects-base-server-mocks'; import { savedObjectsClientMock } from '../../mocks'; -import { typeRegistryMock } from '../saved_objects_type_registry.mock'; import { resolveSavedObjectsImportErrors, ResolveSavedObjectsImportErrorsOptions, diff --git a/src/core/server/saved_objects/index.ts b/src/core/server/saved_objects/index.ts index 4a7a14b45b6654..4ccc4f1bcdb304 100644 --- a/src/core/server/saved_objects/index.ts +++ b/src/core/server/saved_objects/index.ts @@ -14,8 +14,6 @@ export type { SavedObjectsImportError } from './import'; export type { SavedObjectsExporter, SavedObjectsExportError } from './export'; -export { SavedObjectsSerializer } from './serialization'; - export { SavedObjectsService } from './saved_objects_service'; export type { @@ -23,10 +21,4 @@ export type { InternalSavedObjectsServiceSetup, } from './saved_objects_service'; -export type { SavedObjectsTypeMappingDefinitions } from './mappings'; - -export { mergeSavedObjectMigrationMaps } from './migrations'; - -export { savedObjectsConfig, savedObjectsMigrationConfig } from './saved_objects_config'; -export { SavedObjectTypeRegistry } from './saved_objects_type_registry'; export { CoreSavedObjectsRouteHandlerContext } from './saved_objects_route_handler_context'; diff --git a/src/core/server/saved_objects/migrations/actions/create_index.ts b/src/core/server/saved_objects/migrations/actions/create_index.ts index 0f6b062a421633..f48918d679624e 100644 --- a/src/core/server/saved_objects/migrations/actions/create_index.ts +++ b/src/core/server/saved_objects/migrations/actions/create_index.ts @@ -11,8 +11,8 @@ import * as TaskEither from 'fp-ts/lib/TaskEither'; import { pipe } from 'fp-ts/lib/pipeable'; import * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import type { ElasticsearchClient } from '@kbn/core-elasticsearch-server'; +import type { IndexMapping } from '@kbn/core-saved-objects-base-server-internal'; import { AcknowledgeResponse } from '.'; -import { IndexMapping } from '../../mappings'; import { catchRetryableEsClientErrors, RetryableEsClientError, diff --git a/src/core/server/saved_objects/migrations/actions/fetch_indices.ts b/src/core/server/saved_objects/migrations/actions/fetch_indices.ts index 922797f2ba2681..0eb43380a6990e 100644 --- a/src/core/server/saved_objects/migrations/actions/fetch_indices.ts +++ b/src/core/server/saved_objects/migrations/actions/fetch_indices.ts @@ -5,10 +5,11 @@ * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ + import * as TaskEither from 'fp-ts/lib/TaskEither'; import * as Either from 'fp-ts/lib/Either'; import type { ElasticsearchClient } from '@kbn/core-elasticsearch-server'; -import { IndexMapping } from '../../mappings'; +import type { IndexMapping } from '@kbn/core-saved-objects-base-server-internal'; import { catchRetryableEsClientErrors, RetryableEsClientError, diff --git a/src/core/server/saved_objects/migrations/actions/update_and_pickup_mappings.ts b/src/core/server/saved_objects/migrations/actions/update_and_pickup_mappings.ts index bd1c2d6ff76148..a5fe33e9bbcf5f 100644 --- a/src/core/server/saved_objects/migrations/actions/update_and_pickup_mappings.ts +++ b/src/core/server/saved_objects/migrations/actions/update_and_pickup_mappings.ts @@ -10,7 +10,7 @@ import * as Either from 'fp-ts/lib/Either'; import * as TaskEither from 'fp-ts/lib/TaskEither'; import { pipe } from 'fp-ts/lib/pipeable'; import type { ElasticsearchClient } from '@kbn/core-elasticsearch-server'; -import { IndexMapping } from '../../mappings'; +import type { IndexMapping } from '@kbn/core-saved-objects-base-server-internal'; import { catchRetryableEsClientErrors, RetryableEsClientError, diff --git a/src/core/server/saved_objects/migrations/core/build_active_mappings.test.ts b/src/core/server/saved_objects/migrations/core/build_active_mappings.test.ts index 7a57a7a8a08d39..7f1542ffc6008a 100644 --- a/src/core/server/saved_objects/migrations/core/build_active_mappings.test.ts +++ b/src/core/server/saved_objects/migrations/core/build_active_mappings.test.ts @@ -6,7 +6,10 @@ * Side Public License, v 1. */ -import { IndexMapping, SavedObjectsTypeMappingDefinitions } from '../../mappings'; +import type { + IndexMapping, + SavedObjectsTypeMappingDefinitions, +} from '@kbn/core-saved-objects-base-server-internal'; import { buildActiveMappings, diffMappings } from './build_active_mappings'; describe('buildActiveMappings', () => { diff --git a/src/core/server/saved_objects/migrations/core/build_active_mappings.ts b/src/core/server/saved_objects/migrations/core/build_active_mappings.ts index 62f5bd1454419f..1a0a502f655bdf 100644 --- a/src/core/server/saved_objects/migrations/core/build_active_mappings.ts +++ b/src/core/server/saved_objects/migrations/core/build_active_mappings.ts @@ -13,7 +13,10 @@ import crypto from 'crypto'; import { cloneDeep, mapValues } from 'lodash'; import type { SavedObjectsMappingProperties } from '@kbn/core-saved-objects-server'; -import { IndexMapping, SavedObjectsTypeMappingDefinitions } from '../../mappings'; +import type { + IndexMapping, + SavedObjectsTypeMappingDefinitions, +} from '@kbn/core-saved-objects-base-server-internal'; /** * Creates an index mapping with the core properties required by saved object diff --git a/src/core/server/saved_objects/migrations/core/build_index_map.test.ts b/src/core/server/saved_objects/migrations/core/build_index_map.test.ts index 5f5d587eec3591..ec82b0ac2c92f8 100644 --- a/src/core/server/saved_objects/migrations/core/build_index_map.test.ts +++ b/src/core/server/saved_objects/migrations/core/build_index_map.test.ts @@ -7,8 +7,8 @@ */ import type { SavedObjectsType } from '@kbn/core-saved-objects-server'; +import { SavedObjectTypeRegistry } from '@kbn/core-saved-objects-base-server-internal'; import { createIndexMap } from './build_index_map'; -import { SavedObjectTypeRegistry } from '../../saved_objects_type_registry'; const createRegistry = (...types: Array>) => { const registry = new SavedObjectTypeRegistry(); diff --git a/src/core/server/saved_objects/migrations/core/build_index_map.ts b/src/core/server/saved_objects/migrations/core/build_index_map.ts index 1e1adcf0dcbc86..225b3bb422925a 100644 --- a/src/core/server/saved_objects/migrations/core/build_index_map.ts +++ b/src/core/server/saved_objects/migrations/core/build_index_map.ts @@ -7,7 +7,7 @@ */ import type { ISavedObjectTypeRegistry } from '@kbn/core-saved-objects-server'; -import type { SavedObjectsTypeMappingDefinitions } from '../../mappings'; +import type { SavedObjectsTypeMappingDefinitions } from '@kbn/core-saved-objects-base-server-internal'; export interface CreateIndexMapOptions { kibanaIndexName: string; diff --git a/src/core/server/saved_objects/migrations/core/disable_unknown_type_mapping_fields.ts b/src/core/server/saved_objects/migrations/core/disable_unknown_type_mapping_fields.ts index b1e25e6e024fb5..8b1eccbe09d783 100644 --- a/src/core/server/saved_objects/migrations/core/disable_unknown_type_mapping_fields.ts +++ b/src/core/server/saved_objects/migrations/core/disable_unknown_type_mapping_fields.ts @@ -7,7 +7,7 @@ */ import type { SavedObjectsMappingProperties } from '@kbn/core-saved-objects-server'; -import { IndexMapping } from '../../mappings'; +import type { IndexMapping } from '@kbn/core-saved-objects-base-server-internal'; /** * Merges the active mappings and the source mappings while disabling the diff --git a/src/core/server/saved_objects/migrations/core/document_migrator.test.mock.ts b/src/core/server/saved_objects/migrations/core/document_migrator.test.mock.ts index ee0b18af5ac0dc..df7914a55876fd 100644 --- a/src/core/server/saved_objects/migrations/core/document_migrator.test.mock.ts +++ b/src/core/server/saved_objects/migrations/core/document_migrator.test.mock.ts @@ -7,8 +7,9 @@ */ const mockGetConvertedObjectId = jest.fn().mockReturnValue('uuidv5'); -jest.mock('../../service/lib/utils', () => { - const actual = jest.requireActual('../../service/lib/utils'); + +jest.mock('@kbn/core-saved-objects-utils-server', () => { + const actual = jest.requireActual('@kbn/core-saved-objects-utils-server'); return { ...actual, SavedObjectsUtils: { diff --git a/src/core/server/saved_objects/migrations/core/document_migrator.test.ts b/src/core/server/saved_objects/migrations/core/document_migrator.test.ts index d126cdce882537..a0dd1cfddc3a48 100644 --- a/src/core/server/saved_objects/migrations/core/document_migrator.test.ts +++ b/src/core/server/saved_objects/migrations/core/document_migrator.test.ts @@ -7,14 +7,16 @@ */ import { mockGetConvertedObjectId } from './document_migrator.test.mock'; -import { set } from '@elastic/safer-lodash-set'; +import { set } from '@kbn/safer-lodash-set'; import _ from 'lodash'; import type { SavedObjectUnsanitizedDoc, SavedObjectsType } from '@kbn/core-saved-objects-server'; +import { + SavedObjectTypeRegistry, + LEGACY_URL_ALIAS_TYPE, +} from '@kbn/core-saved-objects-base-server-internal'; import { DocumentMigrator } from './document_migrator'; import { TransformSavedObjectDocumentError } from './transform_saved_object_document_error'; import { loggingSystemMock } from '@kbn/core-logging-server-mocks'; -import { SavedObjectTypeRegistry } from '../../saved_objects_type_registry'; -import { LEGACY_URL_ALIAS_TYPE } from '../../object_types'; const mockLoggerFactory = loggingSystemMock.create(); const mockLogger = mockLoggerFactory.get('mock logger'); diff --git a/src/core/server/saved_objects/migrations/core/document_migrator.ts b/src/core/server/saved_objects/migrations/core/document_migrator.ts index 3782a74936b6e6..1040699a99e9df 100644 --- a/src/core/server/saved_objects/migrations/core/document_migrator.ts +++ b/src/core/server/saved_objects/migrations/core/document_migrator.ts @@ -43,7 +43,7 @@ import Boom from '@hapi/boom'; import uuidv5 from 'uuid/v5'; -import { set } from '@elastic/safer-lodash-set'; +import { set } from '@kbn/safer-lodash-set'; import _ from 'lodash'; import Semver from 'semver'; import type { Logger } from '@kbn/logging'; @@ -58,10 +58,13 @@ import type { SavedObjectMigrationFn, SavedObjectMigrationMap, } from '@kbn/core-saved-objects-server'; +import { DEFAULT_NAMESPACE_STRING, SavedObjectsUtils } from '@kbn/core-saved-objects-utils-server'; +import { + type LegacyUrlAlias, + LEGACY_URL_ALIAS_TYPE, +} from '@kbn/core-saved-objects-base-server-internal'; import { MigrationLogger } from './migration_logger'; import { TransformSavedObjectDocumentError } from '.'; -import { DEFAULT_NAMESPACE_STRING, SavedObjectsUtils } from '../../service/lib/utils'; -import { LegacyUrlAlias, LEGACY_URL_ALIAS_TYPE } from '../../object_types'; const DEFAULT_MINIMUM_CONVERT_VERSION = '8.0.0'; diff --git a/src/core/server/saved_objects/migrations/core/migrate_raw_docs.test.ts b/src/core/server/saved_objects/migrations/core/migrate_raw_docs.test.ts index 03124f6e7fde7f..c9d7b78953e281 100644 --- a/src/core/server/saved_objects/migrations/core/migrate_raw_docs.test.ts +++ b/src/core/server/saved_objects/migrations/core/migrate_raw_docs.test.ts @@ -6,11 +6,13 @@ * Side Public License, v 1. */ -import { set } from '@elastic/safer-lodash-set'; +import { set } from '@kbn/safer-lodash-set'; import * as Either from 'fp-ts/lib/Either'; import _ from 'lodash'; -import { SavedObjectTypeRegistry } from '../../saved_objects_type_registry'; -import { SavedObjectsSerializer } from '../../serialization'; +import { + SavedObjectTypeRegistry, + SavedObjectsSerializer, +} from '@kbn/core-saved-objects-base-server-internal'; import { DocumentsTransformFailed, DocumentsTransformSuccess, diff --git a/src/core/server/saved_objects/migrations/core/migrate_raw_docs.ts b/src/core/server/saved_objects/migrations/core/migrate_raw_docs.ts index 8534d7e497be07..d1ca65f1dd1034 100644 --- a/src/core/server/saved_objects/migrations/core/migrate_raw_docs.ts +++ b/src/core/server/saved_objects/migrations/core/migrate_raw_docs.ts @@ -16,7 +16,7 @@ import type { SavedObjectsRawDoc, SavedObjectUnsanitizedDoc, } from '@kbn/core-saved-objects-server'; -import { SavedObjectsSerializer } from '../../serialization'; +import { SavedObjectsSerializer } from '@kbn/core-saved-objects-base-server-internal'; import { MigrateAndConvertFn } from './document_migrator'; import { TransformSavedObjectDocumentError } from '.'; diff --git a/src/core/server/saved_objects/migrations/index.ts b/src/core/server/saved_objects/migrations/index.ts index 54416f423a79a6..707b777330ec32 100644 --- a/src/core/server/saved_objects/migrations/index.ts +++ b/src/core/server/saved_objects/migrations/index.ts @@ -9,4 +9,3 @@ export type { MigrationResult } from './core'; export { KibanaMigrator } from './kibana_migrator'; export type { IKibanaMigrator, KibanaMigratorStatus } from './kibana_migrator'; -export { mergeSavedObjectMigrationMaps } from './utils'; diff --git a/src/core/server/saved_objects/migrations/initial_state.test.ts b/src/core/server/saved_objects/migrations/initial_state.test.ts index 32e3b9f50f4a33..6d49b17d4fa800 100644 --- a/src/core/server/saved_objects/migrations/initial_state.test.ts +++ b/src/core/server/saved_objects/migrations/initial_state.test.ts @@ -10,9 +10,11 @@ import { ByteSizeValue } from '@kbn/config-schema'; import * as Option from 'fp-ts/Option'; import type { DocLinksServiceSetup } from '@kbn/core-doc-links-server'; import { docLinksServiceMock } from '@kbn/core-doc-links-server-mocks'; +import { + type SavedObjectsMigrationConfigType, + SavedObjectTypeRegistry, +} from '@kbn/core-saved-objects-base-server-internal'; import { loggingSystemMock } from '../../mocks'; -import { SavedObjectsMigrationConfigType } from '../saved_objects_config'; -import { SavedObjectTypeRegistry } from '../saved_objects_type_registry'; import { createInitialState } from './initial_state'; const mockLogger = loggingSystemMock.create(); diff --git a/src/core/server/saved_objects/migrations/initial_state.ts b/src/core/server/saved_objects/migrations/initial_state.ts index 861ec75e2d8759..1843227934bcd0 100644 --- a/src/core/server/saved_objects/migrations/initial_state.ts +++ b/src/core/server/saved_objects/migrations/initial_state.ts @@ -11,8 +11,10 @@ import type { DocLinksServiceStart } from '@kbn/core-doc-links-server'; import type { Logger } from '@kbn/logging'; import type { SavedObjectsMigrationVersion } from '@kbn/core-saved-objects-common'; import type { ISavedObjectTypeRegistry } from '@kbn/core-saved-objects-server'; -import type { IndexMapping } from '../mappings'; -import type { SavedObjectsMigrationConfigType } from '../saved_objects_config'; +import type { + IndexMapping, + SavedObjectsMigrationConfigType, +} from '@kbn/core-saved-objects-base-server-internal'; import type { InitState } from './state'; import { excludeUnusedTypesQuery } from './core'; diff --git a/src/core/server/saved_objects/migrations/kibana_migrator.test.ts b/src/core/server/saved_objects/migrations/kibana_migrator.test.ts index 6806e5a9c80a16..5d1cb32eca6d22 100644 --- a/src/core/server/saved_objects/migrations/kibana_migrator.test.ts +++ b/src/core/server/saved_objects/migrations/kibana_migrator.test.ts @@ -12,8 +12,8 @@ import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import { loggingSystemMock } from '@kbn/core-logging-server-mocks'; import { elasticsearchClientMock } from '@kbn/core-elasticsearch-client-server-mocks'; import type { SavedObjectsType } from '@kbn/core-saved-objects-server'; +import { SavedObjectTypeRegistry } from '@kbn/core-saved-objects-base-server-internal'; import { KibanaMigratorOptions, KibanaMigrator } from './kibana_migrator'; -import { SavedObjectTypeRegistry } from '../saved_objects_type_registry'; import { DocumentMigrator } from './core/document_migrator'; import { ByteSizeValue } from '@kbn/config-schema'; import { docLinksServiceMock } from '@kbn/core-doc-links-server-mocks'; diff --git a/src/core/server/saved_objects/migrations/kibana_migrator.ts b/src/core/server/saved_objects/migrations/kibana_migrator.ts index 146dd600ab4d01..2a8f9a9c3ee0f8 100644 --- a/src/core/server/saved_objects/migrations/kibana_migrator.ts +++ b/src/core/server/saved_objects/migrations/kibana_migrator.ts @@ -22,12 +22,15 @@ import type { SavedObjectsRawDoc, ISavedObjectTypeRegistry, } from '@kbn/core-saved-objects-server'; -import { IndexMapping, SavedObjectsTypeMappingDefinitions } from '../mappings'; -import { SavedObjectsSerializer } from '../serialization'; +import { + SavedObjectsSerializer, + type IndexMapping, + type SavedObjectsTypeMappingDefinitions, + type SavedObjectsMigrationConfigType, +} from '@kbn/core-saved-objects-base-server-internal'; import { buildActiveMappings, MigrationResult, MigrationStatus } from './core'; import { DocumentMigrator, VersionedTransformer } from './core/document_migrator'; import { createIndexMap } from './core/build_index_map'; -import { SavedObjectsMigrationConfigType } from '../saved_objects_config'; import { runResilientMigrator } from './run_resilient_migrator'; import { migrateRawDocsSafely } from './core/migrate_raw_docs'; diff --git a/src/core/server/saved_objects/migrations/migrations_state_action_machine.test.ts b/src/core/server/saved_objects/migrations/migrations_state_action_machine.test.ts index db319c63e216ff..1c4644fb433259 100644 --- a/src/core/server/saved_objects/migrations/migrations_state_action_machine.test.ts +++ b/src/core/server/saved_objects/migrations/migrations_state_action_machine.test.ts @@ -11,8 +11,8 @@ import { migrationStateActionMachine } from './migrations_state_action_machine'; import { docLinksServiceMock } from '@kbn/core-doc-links-server-mocks'; import { loggingSystemMock } from '@kbn/core-logging-server-mocks'; import { LoggerAdapter } from '@kbn/core-logging-server-internal'; +import { typeRegistryMock } from '@kbn/core-saved-objects-base-server-mocks'; import { elasticsearchServiceMock } from '../../mocks'; -import { typeRegistryMock } from '../saved_objects_type_registry.mock'; import * as Either from 'fp-ts/lib/Either'; import * as Option from 'fp-ts/lib/Option'; import { errors } from '@elastic/elasticsearch'; diff --git a/src/core/server/saved_objects/migrations/model/helpers.ts b/src/core/server/saved_objects/migrations/model/helpers.ts index ea28c14f9a5f05..5f84dc01af008b 100644 --- a/src/core/server/saved_objects/migrations/model/helpers.ts +++ b/src/core/server/saved_objects/migrations/model/helpers.ts @@ -12,8 +12,8 @@ import type { QueryDslQueryContainer, } from '@elastic/elasticsearch/lib/api/types'; import * as Either from 'fp-ts/lib/Either'; +import type { IndexMapping } from '@kbn/core-saved-objects-base-server-internal'; import type { State } from '../state'; -import type { IndexMapping } from '../../mappings'; import type { FetchIndexResponse } from '../actions'; /** diff --git a/src/core/server/saved_objects/migrations/run_resilient_migrator.ts b/src/core/server/saved_objects/migrations/run_resilient_migrator.ts index 9ca3d3dbaaa600..6a6153b9971463 100644 --- a/src/core/server/saved_objects/migrations/run_resilient_migrator.ts +++ b/src/core/server/saved_objects/migrations/run_resilient_migrator.ts @@ -11,14 +11,16 @@ import type { DocLinksServiceStart } from '@kbn/core-doc-links-server'; import type { ElasticsearchClient } from '@kbn/core-elasticsearch-server'; import type { SavedObjectsMigrationVersion } from '@kbn/core-saved-objects-common'; import type { ISavedObjectTypeRegistry } from '@kbn/core-saved-objects-server'; -import { IndexMapping } from '../mappings'; +import type { + IndexMapping, + SavedObjectsMigrationConfigType, +} from '@kbn/core-saved-objects-base-server-internal'; import type { TransformRawDocs } from './types'; import { MigrationResult } from './core'; import { next } from './next'; import { model } from './model'; import { createInitialState } from './initial_state'; import { migrationStateActionMachine } from './migrations_state_action_machine'; -import { SavedObjectsMigrationConfigType } from '../saved_objects_config'; /** * To avoid the Elasticsearch-js client aborting our requests before we diff --git a/src/core/server/saved_objects/migrations/state.ts b/src/core/server/saved_objects/migrations/state.ts index d94d49ecec7aa2..eb8d2e2fbb05b2 100644 --- a/src/core/server/saved_objects/migrations/state.ts +++ b/src/core/server/saved_objects/migrations/state.ts @@ -13,9 +13,9 @@ import type { SavedObjectsRawDoc, SavedObjectTypeExcludeFromUpgradeFilterHook, } from '@kbn/core-saved-objects-server'; +import type { IndexMapping } from '@kbn/core-saved-objects-base-server-internal'; import type { ControlState } from './state_action_machine'; import type { AliasAction } from './actions'; -import type { IndexMapping } from '../mappings'; import type { TransformErrorObjects } from './core'; import type { MigrationLog, Progress } from './types'; diff --git a/src/core/server/saved_objects/object_types/index.ts b/src/core/server/saved_objects/object_types/index.ts index 11a2c1973b09aa..55c0db7ffcdbc0 100644 --- a/src/core/server/saved_objects/object_types/index.ts +++ b/src/core/server/saved_objects/object_types/index.ts @@ -6,6 +6,4 @@ * Side Public License, v 1. */ -export { LEGACY_URL_ALIAS_TYPE } from './constants'; -export type { LegacyUrlAlias } from './types'; export { registerCoreObjectTypes } from './registration'; diff --git a/src/core/server/saved_objects/object_types/registration.test.ts b/src/core/server/saved_objects/object_types/registration.test.ts index 724b9baababef0..2c8a467e32842d 100644 --- a/src/core/server/saved_objects/object_types/registration.test.ts +++ b/src/core/server/saved_objects/object_types/registration.test.ts @@ -6,8 +6,8 @@ * Side Public License, v 1. */ -import { typeRegistryMock } from '../saved_objects_type_registry.mock'; -import { LEGACY_URL_ALIAS_TYPE } from './constants'; +import { typeRegistryMock } from '@kbn/core-saved-objects-base-server-mocks'; +import { LEGACY_URL_ALIAS_TYPE } from '@kbn/core-saved-objects-base-server-internal'; import { registerCoreObjectTypes } from './registration'; describe('Core saved object types registration', () => { diff --git a/src/core/server/saved_objects/object_types/registration.ts b/src/core/server/saved_objects/object_types/registration.ts index d93b1cc2e2a239..5d31cb1e030771 100644 --- a/src/core/server/saved_objects/object_types/registration.ts +++ b/src/core/server/saved_objects/object_types/registration.ts @@ -7,9 +7,11 @@ */ import type { ISavedObjectTypeRegistry, SavedObjectsType } from '@kbn/core-saved-objects-server'; -import { LEGACY_URL_ALIAS_TYPE } from './constants'; -import { SavedObjectTypeRegistry } from '..'; -import type { LegacyUrlAlias } from './types'; +import { + SavedObjectTypeRegistry, + LEGACY_URL_ALIAS_TYPE, + type LegacyUrlAlias, +} from '@kbn/core-saved-objects-base-server-internal'; const legacyUrlAliasType: SavedObjectsType = { name: LEGACY_URL_ALIAS_TYPE, diff --git a/src/core/server/saved_objects/routes/export.ts b/src/core/server/saved_objects/routes/export.ts index bd89a2845626a4..0ab75a3c7101d0 100644 --- a/src/core/server/saved_objects/routes/export.ts +++ b/src/core/server/saved_objects/routes/export.ts @@ -15,8 +15,8 @@ import type { SavedObjectsExportByTypeOptions, SavedObjectsExportByObjectOptions, } from '@kbn/core-saved-objects-server'; +import type { SavedObjectConfig } from '@kbn/core-saved-objects-base-server-internal'; import { InternalCoreUsageDataSetup } from '../../core_usage_data'; -import { SavedObjectConfig } from '../saved_objects_config'; import { SavedObjectsExportError } from '../export'; import type { InternalSavedObjectRouter } from '../internal_types'; import { validateTypes, validateObjects, catchAndReturnBoomErrors } from './utils'; diff --git a/src/core/server/saved_objects/routes/import.ts b/src/core/server/saved_objects/routes/import.ts index 0c56acf9e2d68b..717cc50a13e605 100644 --- a/src/core/server/saved_objects/routes/import.ts +++ b/src/core/server/saved_objects/routes/import.ts @@ -9,8 +9,8 @@ import { Readable } from 'stream'; import { extname } from 'path'; import { schema } from '@kbn/config-schema'; +import type { SavedObjectConfig } from '@kbn/core-saved-objects-base-server-internal'; import { InternalCoreUsageDataSetup } from '../../core_usage_data'; -import { SavedObjectConfig } from '../saved_objects_config'; import { SavedObjectsImportError } from '../import'; import type { InternalSavedObjectRouter } from '../internal_types'; import { catchAndReturnBoomErrors, createSavedObjectsStreamFromNdJson } from './utils'; diff --git a/src/core/server/saved_objects/routes/index.ts b/src/core/server/saved_objects/routes/index.ts index edc52efdeaef87..f49c604a37c0c7 100644 --- a/src/core/server/saved_objects/routes/index.ts +++ b/src/core/server/saved_objects/routes/index.ts @@ -8,8 +8,8 @@ import type { Logger } from '@kbn/logging'; import type { InternalHttpServiceSetup } from '@kbn/core-http-server-internal'; +import type { SavedObjectConfig } from '@kbn/core-saved-objects-base-server-internal'; import { InternalCoreUsageDataSetup } from '../../core_usage_data'; -import { SavedObjectConfig } from '../saved_objects_config'; import { IKibanaMigrator } from '../migrations'; import type { InternalSavedObjectsRequestHandlerContext } from '../internal_types'; import { registerGetRoute } from './get'; diff --git a/src/core/server/saved_objects/routes/resolve_import_errors.ts b/src/core/server/saved_objects/routes/resolve_import_errors.ts index 4bedec1715a4fb..ed919693e1b86f 100644 --- a/src/core/server/saved_objects/routes/resolve_import_errors.ts +++ b/src/core/server/saved_objects/routes/resolve_import_errors.ts @@ -8,10 +8,10 @@ import { extname } from 'path'; import { Readable } from 'stream'; -import { schema } from '@kbn/config-schema'; import { chain } from 'lodash'; +import { schema } from '@kbn/config-schema'; +import type { SavedObjectConfig } from '@kbn/core-saved-objects-base-server-internal'; import { InternalCoreUsageDataSetup } from '../../core_usage_data'; -import { SavedObjectConfig } from '../saved_objects_config'; import { SavedObjectsImportError } from '../import'; import type { InternalSavedObjectRouter } from '../internal_types'; import { catchAndReturnBoomErrors, createSavedObjectsStreamFromNdJson } from './utils'; diff --git a/src/core/server/saved_objects/saved_objects_service.mock.ts b/src/core/server/saved_objects/saved_objects_service.mock.ts index 292e39b0c199dd..f1a1ce6c091b65 100644 --- a/src/core/server/saved_objects/saved_objects_service.mock.ts +++ b/src/core/server/saved_objects/saved_objects_service.mock.ts @@ -21,7 +21,7 @@ import type { import { savedObjectsRepositoryMock } from './service/lib/repository.mock'; import { savedObjectsClientMock } from './service/saved_objects_client.mock'; -import { typeRegistryMock } from './saved_objects_type_registry.mock'; +import { typeRegistryMock, serializerMock } from '@kbn/core-saved-objects-base-server-mocks'; import { savedObjectsExporterMock } from './export/saved_objects_exporter.mock'; import { savedObjectsImporterMock } from './import/saved_objects_importer.mock'; import { migrationMocks } from './migrations/mocks'; @@ -105,4 +105,5 @@ export const savedObjectsServiceMock = { createTypeRegistryMock: typeRegistryMock.create, createExporter: savedObjectsExporterMock.create, createImporter: savedObjectsImporterMock.create, + createSerializer: serializerMock.create, }; diff --git a/src/core/server/saved_objects/saved_objects_service.test.mocks.ts b/src/core/server/saved_objects/saved_objects_service.test.mocks.ts index f4b58fd12d8ba4..4b66f5865def58 100644 --- a/src/core/server/saved_objects/saved_objects_service.test.mocks.ts +++ b/src/core/server/saved_objects/saved_objects_service.test.mocks.ts @@ -8,7 +8,7 @@ import { mockKibanaMigrator } from './migrations/kibana_migrator.mock'; import { savedObjectsClientProviderMock } from './service/lib/scoped_client_provider.mock'; -import { typeRegistryMock } from './saved_objects_type_registry.mock'; +import { typeRegistryMock } from '@kbn/core-saved-objects-base-server-mocks'; export const migratorInstanceMock = mockKibanaMigrator.create(); export const KibanaMigratorMock = jest.fn().mockImplementation(() => migratorInstanceMock); @@ -22,15 +22,15 @@ jest.doMock('./service/lib/scoped_client_provider', () => ({ })); export const typeRegistryInstanceMock = typeRegistryMock.create(); -jest.doMock('./saved_objects_type_registry', () => ({ - SavedObjectTypeRegistry: jest.fn().mockImplementation(() => typeRegistryInstanceMock), -})); +jest.doMock('@kbn/core-saved-objects-base-server-internal', () => { + const actual = jest.requireActual('@kbn/core-saved-objects-base-server-internal'); + return { + ...actual, + SavedObjectTypeRegistry: jest.fn().mockImplementation(() => typeRegistryInstanceMock), + }; +}); export const registerRoutesMock = jest.fn(); jest.doMock('./routes', () => ({ registerRoutes: registerRoutesMock, })); - -// The SavedObjectsSerializer imports SavedObjectUtils from the '../service' module, and that somehow breaks unit tests for the -// SavedObjectsService. To avoid this, we mock the entire './serialization' module, since we don't need it for these tests. -jest.mock('./serialization'); diff --git a/src/core/server/saved_objects/saved_objects_service.ts b/src/core/server/saved_objects/saved_objects_service.ts index 53eb376cc37b7e..542a13e3a4cc04 100644 --- a/src/core/server/saved_objects/saved_objects_service.ts +++ b/src/core/server/saved_objects/saved_objects_service.ts @@ -27,18 +27,18 @@ import type { SavedObjectsClientWrapperFactory, ISavedObjectTypeRegistry, } from '@kbn/core-saved-objects-server'; +import { + SavedObjectConfig, + SavedObjectsSerializer, + SavedObjectTypeRegistry, + type SavedObjectsConfigType, + type SavedObjectsMigrationConfigType, +} from '@kbn/core-saved-objects-base-server-internal'; import { SavedObjectsClient, SavedObjectsClientProvider } from './service'; import { KibanaMigrator, IKibanaMigrator } from './migrations'; import { InternalCoreUsageDataSetup } from '../core_usage_data'; import { InternalDeprecationsServiceSetup } from '../deprecations'; -import { - SavedObjectsConfigType, - SavedObjectsMigrationConfigType, - SavedObjectConfig, -} from './saved_objects_config'; import { SavedObjectsRepository } from './service/lib/repository'; -import { SavedObjectTypeRegistry } from './saved_objects_type_registry'; -import { SavedObjectsSerializer } from './serialization'; import { SavedObjectsExporter } from './export'; import { SavedObjectsImporter } from './import'; import { registerRoutes } from './routes'; diff --git a/src/core/server/saved_objects/service/index.ts b/src/core/server/saved_objects/service/index.ts index 1ce638c4c01889..0737fc725d1a4f 100644 --- a/src/core/server/saved_objects/service/index.ts +++ b/src/core/server/saved_objects/service/index.ts @@ -5,6 +5,7 @@ * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ -export { SavedObjectsErrorHelpers, SavedObjectsClientProvider, SavedObjectsUtils } from './lib'; + +export { SavedObjectsClientProvider } from './lib'; export type { SavedObjectsRepository, ISavedObjectsClientProvider } from './lib'; export { SavedObjectsClient } from './saved_objects_client'; diff --git a/src/core/server/saved_objects/service/lib/aggregations/validation.ts b/src/core/server/saved_objects/service/lib/aggregations/validation.ts index 76098d73306af7..b3a6bbae5e9561 100644 --- a/src/core/server/saved_objects/service/lib/aggregations/validation.ts +++ b/src/core/server/saved_objects/service/lib/aggregations/validation.ts @@ -10,7 +10,7 @@ import * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import { ObjectType } from '@kbn/config-schema'; import { isPlainObject, isArray } from 'lodash'; -import { IndexMapping } from '../../../mappings'; +import type { IndexMapping } from '@kbn/core-saved-objects-base-server-internal'; import { isObjectTypeAttribute, rewriteObjectTypeAttribute, diff --git a/src/core/server/saved_objects/service/lib/aggregations/validation_utils.ts b/src/core/server/saved_objects/service/lib/aggregations/validation_utils.ts index 0b2cc8e235c9cb..5548ad4d57a5dd 100644 --- a/src/core/server/saved_objects/service/lib/aggregations/validation_utils.ts +++ b/src/core/server/saved_objects/service/lib/aggregations/validation_utils.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import { IndexMapping } from '../../../mappings'; +import type { IndexMapping } from '@kbn/core-saved-objects-base-server-internal'; import { fieldDefined, hasFilterKeyError } from '../filter_utils'; /** diff --git a/src/core/server/saved_objects/service/lib/collect_multi_namespace_references.test.ts b/src/core/server/saved_objects/service/lib/collect_multi_namespace_references.test.ts index d3cf76716e5985..86e1e82d12a6fb 100644 --- a/src/core/server/saved_objects/service/lib/collect_multi_namespace_references.test.ts +++ b/src/core/server/saved_objects/service/lib/collect_multi_namespace_references.test.ts @@ -17,15 +17,15 @@ import type { SavedObjectsCollectMultiNamespaceReferencesObject, SavedObjectsCollectMultiNamespaceReferencesOptions, } from '@kbn/core-saved-objects-api-server'; -import { typeRegistryMock } from '../../saved_objects_type_registry.mock'; -import { SavedObjectsSerializer } from '../../serialization'; +import { SavedObjectsErrorHelpers } from '@kbn/core-saved-objects-utils-server'; +import { SavedObjectsSerializer } from '@kbn/core-saved-objects-base-server-internal'; +import { typeRegistryMock } from '@kbn/core-saved-objects-base-server-mocks'; import { ALIAS_OR_SHARED_ORIGIN_SEARCH_PER_PAGE, CollectMultiNamespaceReferencesParams, } from './collect_multi_namespace_references'; import { collectMultiNamespaceReferences } from './collect_multi_namespace_references'; import type { CreatePointInTimeFinderFn } from './point_in_time_finder'; -import { SavedObjectsErrorHelpers } from './errors'; const SPACES = ['default', 'another-space']; const VERSION_PROPS = { _seq_no: 1, _primary_term: 1 }; diff --git a/src/core/server/saved_objects/service/lib/collect_multi_namespace_references.ts b/src/core/server/saved_objects/service/lib/collect_multi_namespace_references.ts index b31f817e4c4d26..222b58d3a03e07 100644 --- a/src/core/server/saved_objects/service/lib/collect_multi_namespace_references.ts +++ b/src/core/server/saved_objects/service/lib/collect_multi_namespace_references.ts @@ -15,8 +15,8 @@ import type { SavedObjectReferenceWithContext, } from '@kbn/core-saved-objects-api-server'; import type { ISavedObjectTypeRegistry } from '@kbn/core-saved-objects-server'; -import type { SavedObjectsSerializer } from '../../serialization'; -import { SavedObjectsErrorHelpers } from './errors'; +import { SavedObjectsErrorHelpers } from '@kbn/core-saved-objects-utils-server'; +import type { SavedObjectsSerializer } from '@kbn/core-saved-objects-base-server-internal'; import { findLegacyUrlAliases } from './legacy_url_aliases'; import { getRootFields } from './included_fields'; import { diff --git a/src/core/server/saved_objects/service/lib/decorate_es_error.test.ts b/src/core/server/saved_objects/service/lib/decorate_es_error.test.ts index a7aa52f7a0f5a3..8290f7345190d4 100644 --- a/src/core/server/saved_objects/service/lib/decorate_es_error.test.ts +++ b/src/core/server/saved_objects/service/lib/decorate_es_error.test.ts @@ -8,8 +8,8 @@ import { errors as esErrors } from '@elastic/elasticsearch'; import { elasticsearchClientMock } from '@kbn/core-elasticsearch-client-server-mocks'; +import { SavedObjectsErrorHelpers } from '@kbn/core-saved-objects-utils-server'; import { decorateEsError } from './decorate_es_error'; -import { SavedObjectsErrorHelpers } from './errors'; describe('savedObjectsClient/decorateEsError', () => { it('always returns the same error it receives', () => { diff --git a/src/core/server/saved_objects/service/lib/decorate_es_error.ts b/src/core/server/saved_objects/service/lib/decorate_es_error.ts index 40eda7a854a25c..9cfdffc13a5ddc 100644 --- a/src/core/server/saved_objects/service/lib/decorate_es_error.ts +++ b/src/core/server/saved_objects/service/lib/decorate_es_error.ts @@ -10,6 +10,7 @@ import { get } from 'lodash'; import { errors as esErrors } from '@elastic/elasticsearch'; import type { ElasticsearchErrorDetails } from '@kbn/es-errors'; import { isSupportedEsServer } from '@kbn/core-elasticsearch-server-internal'; +import { SavedObjectsErrorHelpers } from '@kbn/core-saved-objects-utils-server'; const responseErrors = { isServiceUnavailable: (statusCode?: number) => statusCode === 503, @@ -25,8 +26,6 @@ const { ConnectionError, NoLivingConnectionsError, TimeoutError } = esErrors; const SCRIPT_CONTEXT_DISABLED_REGEX = /(?:cannot execute scripts using \[)([a-z]*)(?:\] context)/; const INLINE_SCRIPTS_DISABLED_MESSAGE = 'cannot execute [inline] scripts'; -import { SavedObjectsErrorHelpers } from './errors'; - type EsErrors = | esErrors.ConnectionError | esErrors.NoLivingConnectionsError diff --git a/src/core/server/saved_objects/service/lib/filter_utils.ts b/src/core/server/saved_objects/service/lib/filter_utils.ts index 27ff1c201cbddc..ae7bb08039850c 100644 --- a/src/core/server/saved_objects/service/lib/filter_utils.ts +++ b/src/core/server/saved_objects/service/lib/filter_utils.ts @@ -6,11 +6,11 @@ * Side Public License, v 1. */ -import { set } from '@elastic/safer-lodash-set'; +import { set } from '@kbn/safer-lodash-set'; import { get, cloneDeep } from 'lodash'; import * as esKuery from '@kbn/es-query'; -import { SavedObjectsErrorHelpers } from './errors'; -import { IndexMapping } from '../../mappings'; +import { SavedObjectsErrorHelpers } from '@kbn/core-saved-objects-utils-server'; +import type { IndexMapping } from '@kbn/core-saved-objects-base-server-internal'; type KueryNode = any; diff --git a/src/core/server/saved_objects/service/lib/find_shared_origin_objects.ts b/src/core/server/saved_objects/service/lib/find_shared_origin_objects.ts index 229e0c6f90a664..34aff0b11d6d04 100644 --- a/src/core/server/saved_objects/service/lib/find_shared_origin_objects.ts +++ b/src/core/server/saved_objects/service/lib/find_shared_origin_objects.ts @@ -7,9 +7,9 @@ */ import * as esKuery from '@kbn/es-query'; +import { ALL_NAMESPACES_STRING } from '@kbn/core-saved-objects-utils-server'; import { getObjectKey } from './internal_utils'; import type { CreatePointInTimeFinderFn } from './point_in_time_finder'; -import { ALL_NAMESPACES_STRING } from './utils'; interface ObjectOrigin { /** The object's type. */ diff --git a/src/core/server/saved_objects/service/lib/get_index_for_type.test.ts b/src/core/server/saved_objects/service/lib/get_index_for_type.test.ts index 16e3ba9495f045..01bb3174cc56bb 100644 --- a/src/core/server/saved_objects/service/lib/get_index_for_type.test.ts +++ b/src/core/server/saved_objects/service/lib/get_index_for_type.test.ts @@ -6,8 +6,8 @@ * Side Public License, v 1. */ +import { typeRegistryMock } from '@kbn/core-saved-objects-base-server-mocks'; import { getIndexForType } from './get_index_for_type'; -import { typeRegistryMock } from '../../saved_objects_type_registry.mock'; describe('getIndexForType', () => { const kibanaVersion = '8.0.0'; diff --git a/src/core/server/saved_objects/service/lib/index.ts b/src/core/server/saved_objects/service/lib/index.ts index 8fdb8301ce1017..a43750608bf95d 100644 --- a/src/core/server/saved_objects/service/lib/index.ts +++ b/src/core/server/saved_objects/service/lib/index.ts @@ -11,8 +11,4 @@ export { SavedObjectsClientProvider } from './scoped_client_provider'; export type { ISavedObjectsClientProvider } from './scoped_client_provider'; -export { SavedObjectsErrorHelpers } from './errors'; - -export { SavedObjectsUtils } from './utils'; - export { getIndexForType } from './get_index_for_type'; diff --git a/src/core/server/saved_objects/service/lib/internal_bulk_resolve.test.ts b/src/core/server/saved_objects/service/lib/internal_bulk_resolve.test.ts index ec55ea77257188..119b3ac85b6986 100644 --- a/src/core/server/saved_objects/service/lib/internal_bulk_resolve.test.ts +++ b/src/core/server/saved_objects/service/lib/internal_bulk_resolve.test.ts @@ -18,12 +18,13 @@ import type { SavedObjectsBulkResolveObject, SavedObjectsBaseOptions, } from '@kbn/core-saved-objects-api-server'; -import { LEGACY_URL_ALIAS_TYPE } from '../../object_types'; -import { typeRegistryMock } from '../../saved_objects_type_registry.mock'; -import { SavedObjectsSerializer } from '../../serialization'; -import { SavedObjectsErrorHelpers } from './errors'; +import { SavedObjectsErrorHelpers, SavedObjectsUtils } from '@kbn/core-saved-objects-utils-server'; +import { + SavedObjectsSerializer, + LEGACY_URL_ALIAS_TYPE, +} from '@kbn/core-saved-objects-base-server-internal'; +import { typeRegistryMock } from '@kbn/core-saved-objects-base-server-mocks'; import { internalBulkResolve, InternalBulkResolveParams } from './internal_bulk_resolve'; -import { SavedObjectsUtils } from './utils'; import { normalizeNamespace } from './internal_utils'; const VERSION_PROPS = { _seq_no: 1, _primary_term: 1 }; diff --git a/src/core/server/saved_objects/service/lib/internal_bulk_resolve.ts b/src/core/server/saved_objects/service/lib/internal_bulk_resolve.ts index ebe94e4e95b4de..b15fc56e2f3c01 100644 --- a/src/core/server/saved_objects/service/lib/internal_bulk_resolve.ts +++ b/src/core/server/saved_objects/service/lib/internal_bulk_resolve.ts @@ -21,14 +21,20 @@ import type { ISavedObjectTypeRegistry, SavedObjectsRawDocSource, } from '@kbn/core-saved-objects-server'; +import { + SavedObjectsErrorHelpers, + type DecoratedError, +} from '@kbn/core-saved-objects-utils-server'; +import { + LEGACY_URL_ALIAS_TYPE, + type LegacyUrlAlias, + type SavedObjectsSerializer, +} from '@kbn/core-saved-objects-base-server-internal'; import { CORE_USAGE_STATS_ID, CORE_USAGE_STATS_TYPE, REPOSITORY_RESOLVE_OUTCOME_STATS, } from '../../../core_usage_data'; -import { LegacyUrlAlias, LEGACY_URL_ALIAS_TYPE } from '../../object_types'; -import type { SavedObjectsSerializer } from '../../serialization'; -import { DecoratedError, SavedObjectsErrorHelpers } from './errors'; import { getCurrentTime, getSavedObjectFromSource, diff --git a/src/core/server/saved_objects/service/lib/internal_utils.test.ts b/src/core/server/saved_objects/service/lib/internal_utils.test.ts index 65cb83d3e8a774..96ca3949a4775e 100644 --- a/src/core/server/saved_objects/service/lib/internal_utils.test.ts +++ b/src/core/server/saved_objects/service/lib/internal_utils.test.ts @@ -7,8 +7,9 @@ */ import type { SavedObjectsRawDoc } from '@kbn/core-saved-objects-server'; -import { typeRegistryMock } from '../../saved_objects_type_registry.mock'; -import { encodeHitVersion } from '../../version'; +import { ALL_NAMESPACES_STRING } from '@kbn/core-saved-objects-utils-server'; +import { encodeHitVersion } from '@kbn/core-saved-objects-base-server-internal'; +import { typeRegistryMock } from '@kbn/core-saved-objects-base-server-mocks'; import { getBulkOperationError, getCurrentTime, @@ -19,7 +20,6 @@ import { rawDocExistsInNamespace, rawDocExistsInNamespaces, } from './internal_utils'; -import { ALL_NAMESPACES_STRING } from './utils'; describe('#getBulkOperationError', () => { const type = 'obj-type'; diff --git a/src/core/server/saved_objects/service/lib/internal_utils.ts b/src/core/server/saved_objects/service/lib/internal_utils.ts index 5f20a2bc3c842e..84539510504a2c 100644 --- a/src/core/server/saved_objects/service/lib/internal_utils.ts +++ b/src/core/server/saved_objects/service/lib/internal_utils.ts @@ -13,9 +13,15 @@ import type { SavedObjectsRawDoc, SavedObjectsRawDocSource, } from '@kbn/core-saved-objects-server'; -import { decodeRequestVersion, encodeHitVersion } from '../../version'; -import { SavedObjectsErrorHelpers } from './errors'; -import { ALL_NAMESPACES_STRING, SavedObjectsUtils } from './utils'; +import { + SavedObjectsErrorHelpers, + SavedObjectsUtils, + ALL_NAMESPACES_STRING, +} from '@kbn/core-saved-objects-utils-server'; +import { + decodeRequestVersion, + encodeHitVersion, +} from '@kbn/core-saved-objects-base-server-internal'; /** * Discriminated union (TypeScript approximation of an algebraic data type); this design pattern is used for internal repository operations. diff --git a/src/core/server/saved_objects/service/lib/legacy_url_aliases/delete_legacy_url_aliases.test.ts b/src/core/server/saved_objects/service/lib/legacy_url_aliases/delete_legacy_url_aliases.test.ts index dc261ee23aafb8..77a538672ff198 100644 --- a/src/core/server/saved_objects/service/lib/legacy_url_aliases/delete_legacy_url_aliases.test.ts +++ b/src/core/server/saved_objects/service/lib/legacy_url_aliases/delete_legacy_url_aliases.test.ts @@ -11,8 +11,8 @@ import { mockGetEsErrorMessage } from './delete_legacy_url_aliases.test.mock'; / import { errors as EsErrors } from '@elastic/elasticsearch'; import { elasticsearchClientMock } from '@kbn/core-elasticsearch-client-server-mocks'; -import { typeRegistryMock } from '../../../saved_objects_type_registry.mock'; -import { ALL_NAMESPACES_STRING } from '../utils'; +import { ALL_NAMESPACES_STRING } from '@kbn/core-saved-objects-utils-server'; +import { typeRegistryMock } from '@kbn/core-saved-objects-base-server-mocks'; import { deleteLegacyUrlAliases } from './delete_legacy_url_aliases'; import type { DeleteLegacyUrlAliasesParams } from './delete_legacy_url_aliases'; diff --git a/src/core/server/saved_objects/service/lib/legacy_url_aliases/delete_legacy_url_aliases.ts b/src/core/server/saved_objects/service/lib/legacy_url_aliases/delete_legacy_url_aliases.ts index 873f4ab9b6c9c3..73489308f59afc 100644 --- a/src/core/server/saved_objects/service/lib/legacy_url_aliases/delete_legacy_url_aliases.ts +++ b/src/core/server/saved_objects/service/lib/legacy_url_aliases/delete_legacy_url_aliases.ts @@ -10,11 +10,13 @@ import * as esKuery from '@kbn/es-query'; import { getErrorMessage as getEsErrorMessage } from '@kbn/core-elasticsearch-client-server-internal'; import type { ISavedObjectTypeRegistry } from '@kbn/core-saved-objects-server'; -import type { IndexMapping } from '../../../mappings'; -import { LEGACY_URL_ALIAS_TYPE } from '../../../object_types'; +import { ALL_NAMESPACES_STRING } from '@kbn/core-saved-objects-utils-server'; +import { + LEGACY_URL_ALIAS_TYPE, + type IndexMapping, +} from '@kbn/core-saved-objects-base-server-internal'; import type { RepositoryEsClient } from '../repository_es_client'; import { getSearchDsl } from '../search_dsl'; -import { ALL_NAMESPACES_STRING } from '../utils'; /** @internal */ export interface DeleteLegacyUrlAliasesParams { diff --git a/src/core/server/saved_objects/service/lib/legacy_url_aliases/find_legacy_url_aliases.test.ts b/src/core/server/saved_objects/service/lib/legacy_url_aliases/find_legacy_url_aliases.test.ts index 8200c7502fec61..36435b9828be42 100644 --- a/src/core/server/saved_objects/service/lib/legacy_url_aliases/find_legacy_url_aliases.test.ts +++ b/src/core/server/saved_objects/service/lib/legacy_url_aliases/find_legacy_url_aliases.test.ts @@ -9,7 +9,10 @@ import type { DeeplyMockedKeys } from '@kbn/utility-types-jest'; import type { ISavedObjectsRepository } from '@kbn/core-saved-objects-api-server'; -import { LegacyUrlAlias, LEGACY_URL_ALIAS_TYPE } from '../../../object_types'; +import { + type LegacyUrlAlias, + LEGACY_URL_ALIAS_TYPE, +} from '@kbn/core-saved-objects-base-server-internal'; import type { CreatePointInTimeFinderFn, PointInTimeFinder } from '../point_in_time_finder'; import { savedObjectsPointInTimeFinderMock } from '../point_in_time_finder.mock'; import { savedObjectsRepositoryMock } from '../repository.mock'; diff --git a/src/core/server/saved_objects/service/lib/legacy_url_aliases/find_legacy_url_aliases.ts b/src/core/server/saved_objects/service/lib/legacy_url_aliases/find_legacy_url_aliases.ts index 70b1730ec8f488..5a90a2e70d0737 100644 --- a/src/core/server/saved_objects/service/lib/legacy_url_aliases/find_legacy_url_aliases.ts +++ b/src/core/server/saved_objects/service/lib/legacy_url_aliases/find_legacy_url_aliases.ts @@ -7,7 +7,10 @@ */ import * as esKuery from '@kbn/es-query'; -import { LegacyUrlAlias, LEGACY_URL_ALIAS_TYPE } from '../../../object_types'; +import { + type LegacyUrlAlias, + LEGACY_URL_ALIAS_TYPE, +} from '@kbn/core-saved-objects-base-server-internal'; import { getObjectKey } from '../internal_utils'; import type { CreatePointInTimeFinderFn } from '../point_in_time_finder'; diff --git a/src/core/server/saved_objects/service/lib/preflight_check_for_create.test.ts b/src/core/server/saved_objects/service/lib/preflight_check_for_create.test.ts index 9563ebd51344f8..d23d2cf5e804e8 100644 --- a/src/core/server/saved_objects/service/lib/preflight_check_for_create.test.ts +++ b/src/core/server/saved_objects/service/lib/preflight_check_for_create.test.ts @@ -15,9 +15,11 @@ import type { DeeplyMockedKeys } from '@kbn/utility-types-jest'; import type { ElasticsearchClient } from '@kbn/core-elasticsearch-server'; import { elasticsearchClientMock } from '@kbn/core-elasticsearch-client-server-mocks'; -import { LEGACY_URL_ALIAS_TYPE } from '../../object_types'; -import { typeRegistryMock } from '../../saved_objects_type_registry.mock'; -import { SavedObjectsSerializer } from '../../serialization'; +import { + SavedObjectsSerializer, + LEGACY_URL_ALIAS_TYPE, +} from '@kbn/core-saved-objects-base-server-internal'; +import { typeRegistryMock } from '@kbn/core-saved-objects-base-server-mocks'; import type { CreatePointInTimeFinderFn } from './point_in_time_finder'; import { ALIAS_SEARCH_PER_PAGE, diff --git a/src/core/server/saved_objects/service/lib/preflight_check_for_create.ts b/src/core/server/saved_objects/service/lib/preflight_check_for_create.ts index b94302b2b990f6..a3fd4218c3eeb0 100644 --- a/src/core/server/saved_objects/service/lib/preflight_check_for_create.ts +++ b/src/core/server/saved_objects/service/lib/preflight_check_for_create.ts @@ -13,15 +13,20 @@ import type { SavedObjectsRawDoc, SavedObjectsRawDocSource, } from '@kbn/core-saved-objects-server'; -import { LegacyUrlAlias, LEGACY_URL_ALIAS_TYPE } from '../../object_types'; -import type { SavedObjectsSerializer } from '../../serialization'; +import { + SavedObjectsErrorHelpers, + ALL_NAMESPACES_STRING, +} from '@kbn/core-saved-objects-utils-server'; +import { + LEGACY_URL_ALIAS_TYPE, + type LegacyUrlAlias, + type SavedObjectsSerializer, +} from '@kbn/core-saved-objects-base-server-internal'; import { findLegacyUrlAliases } from './legacy_url_aliases'; import { Either, rawDocExistsInNamespaces } from './internal_utils'; import { getObjectKey, isLeft, isRight } from './internal_utils'; import type { CreatePointInTimeFinderFn } from './point_in_time_finder'; import type { RepositoryEsClient } from './repository_es_client'; -import { ALL_NAMESPACES_STRING } from './utils'; -import { SavedObjectsErrorHelpers } from './errors'; /** * If the object will be created in this many spaces (or "*" all current and future spaces), we use find to fetch all aliases. diff --git a/src/core/server/saved_objects/service/lib/repository.test.ts b/src/core/server/saved_objects/service/lib/repository.test.ts index 9af620101ab946..30a6b1ab36151e 100644 --- a/src/core/server/saved_objects/service/lib/repository.test.ts +++ b/src/core/server/saved_objects/service/lib/repository.test.ts @@ -55,17 +55,21 @@ import type { SavedObjectsMappingProperties, SavedObjectsTypeMappingDefinition, } from '@kbn/core-saved-objects-server'; +import { + SavedObjectsErrorHelpers, + ALL_NAMESPACES_STRING, +} from '@kbn/core-saved-objects-utils-server'; import { SavedObjectsRepository } from './repository'; -import { SavedObjectsErrorHelpers } from './errors'; import { PointInTimeFinder } from './point_in_time_finder'; -import { ALL_NAMESPACES_STRING } from './utils'; import { loggerMock } from '@kbn/logging-mocks'; -import { SavedObjectsSerializer } from '../../serialization'; -import { encodeHitVersion } from '../../version'; -import { SavedObjectTypeRegistry } from '../../saved_objects_type_registry'; +import { + SavedObjectTypeRegistry, + SavedObjectsSerializer, + encodeHitVersion, + LEGACY_URL_ALIAS_TYPE, +} from '@kbn/core-saved-objects-base-server-internal'; import { DocumentMigrator } from '../../migrations/core/document_migrator'; import { mockKibanaMigrator } from '../../migrations/kibana_migrator.mock'; -import { LEGACY_URL_ALIAS_TYPE } from '../../object_types'; import { elasticsearchClientMock } from '@kbn/core-elasticsearch-client-server-mocks'; import * as esKuery from '@kbn/es-query'; import { errors as EsErrors } from '@elastic/elasticsearch'; diff --git a/src/core/server/saved_objects/service/lib/repository.ts b/src/core/server/saved_objects/service/lib/repository.ts index 1ede13e1142b2b..524fe5f7eb966e 100644 --- a/src/core/server/saved_objects/service/lib/repository.ts +++ b/src/core/server/saved_objects/service/lib/repository.ts @@ -60,17 +60,31 @@ import type { SavedObjectsRawDocSource, ISavedObjectTypeRegistry, } from '@kbn/core-saved-objects-server'; -import { getRootPropertiesObjects, IndexMapping } from '../../mappings'; +import { + SavedObjectsErrorHelpers, + type DecoratedError, +} from '@kbn/core-saved-objects-utils-server'; +import { + ALL_NAMESPACES_STRING, + FIND_DEFAULT_PAGE, + FIND_DEFAULT_PER_PAGE, + SavedObjectsUtils, +} from '@kbn/core-saved-objects-utils-server'; +import { + SavedObjectsSerializer, + SavedObjectsTypeValidator, + decodeRequestVersion, + encodeVersion, + encodeHitVersion, + getRootPropertiesObjects, + LEGACY_URL_ALIAS_TYPE, + type IndexMapping, +} from '@kbn/core-saved-objects-base-server-internal'; import { PointInTimeFinder } from './point_in_time_finder'; import { createRepositoryEsClient, RepositoryEsClient } from './repository_es_client'; import { getSearchDsl } from './search_dsl'; import { includedFields } from './included_fields'; -import { SavedObjectsErrorHelpers, DecoratedError } from './errors'; -import { decodeRequestVersion, encodeVersion, encodeHitVersion } from '../../version'; import { IKibanaMigrator } from '../../migrations'; -import { SavedObjectsSerializer } from '../../serialization'; -import { LEGACY_URL_ALIAS_TYPE } from '../../object_types'; -import { SavedObjectsTypeValidator } from '../../validation'; import { internalBulkResolve, InternalBulkResolveError } from './internal_bulk_resolve'; import { validateConvertFilterToKueryNode } from './filter_utils'; import { validateAndConvertAggregations } from './aggregations'; @@ -86,12 +100,6 @@ import { isLeft, isRight, } from './internal_utils'; -import { - ALL_NAMESPACES_STRING, - FIND_DEFAULT_PAGE, - FIND_DEFAULT_PER_PAGE, - SavedObjectsUtils, -} from './utils'; import { collectMultiNamespaceReferences } from './collect_multi_namespace_references'; import { updateObjectsSpaces } from './update_objects_spaces'; import { getIndexForType } from './get_index_for_type'; diff --git a/src/core/server/saved_objects/service/lib/repository_create_repository.test.ts b/src/core/server/saved_objects/service/lib/repository_create_repository.test.ts index b1033012a4beb3..9a2d56cdaaa898 100644 --- a/src/core/server/saved_objects/service/lib/repository_create_repository.test.ts +++ b/src/core/server/saved_objects/service/lib/repository_create_repository.test.ts @@ -6,10 +6,10 @@ * Side Public License, v 1. */ +import { SavedObjectTypeRegistry } from '@kbn/core-saved-objects-base-server-internal'; import { SavedObjectsRepository } from './repository'; import { mockKibanaMigrator } from '../../migrations/kibana_migrator.mock'; import { KibanaMigrator } from '../../migrations'; -import { SavedObjectTypeRegistry } from '../../saved_objects_type_registry'; import { loggerMock, MockedLogger } from '@kbn/logging-mocks'; jest.mock('./repository'); diff --git a/src/core/server/saved_objects/service/lib/repository_es_client.test.ts b/src/core/server/saved_objects/service/lib/repository_es_client.test.ts index f465ffb6a3dab4..cbd8f81bfc0f50 100644 --- a/src/core/server/saved_objects/service/lib/repository_es_client.test.ts +++ b/src/core/server/saved_objects/service/lib/repository_es_client.test.ts @@ -10,7 +10,7 @@ import { retryCallClusterMock } from './repository_es_client.test.mock'; import { createRepositoryEsClient, RepositoryEsClient } from './repository_es_client'; import { elasticsearchClientMock } from '@kbn/core-elasticsearch-client-server-mocks'; -import { SavedObjectsErrorHelpers } from './errors'; +import { SavedObjectsErrorHelpers } from '@kbn/core-saved-objects-utils-server'; describe('RepositoryEsClient', () => { let client: ReturnType; diff --git a/src/core/server/saved_objects/service/lib/scoped_client_provider.test.ts b/src/core/server/saved_objects/service/lib/scoped_client_provider.test.ts index efc04f69e6ecf0..2641ecfb1cec6f 100644 --- a/src/core/server/saved_objects/service/lib/scoped_client_provider.test.ts +++ b/src/core/server/saved_objects/service/lib/scoped_client_provider.test.ts @@ -7,8 +7,8 @@ */ import { httpServerMock } from '@kbn/core-http-server-mocks'; +import { typeRegistryMock } from '@kbn/core-saved-objects-base-server-mocks'; import { SavedObjectsClientProvider } from './scoped_client_provider'; -import { typeRegistryMock } from '../../saved_objects_type_registry.mock'; test(`uses default client factory when one isn't set`, () => { const returnValue = Symbol(); diff --git a/src/core/server/saved_objects/service/lib/search_dsl/query_params.test.ts b/src/core/server/saved_objects/service/lib/search_dsl/query_params.test.ts index 3f27bef5c68af3..c502665468e6c9 100644 --- a/src/core/server/saved_objects/service/lib/search_dsl/query_params.test.ts +++ b/src/core/server/saved_objects/service/lib/search_dsl/query_params.test.ts @@ -12,8 +12,11 @@ import * as esKuery from '@kbn/es-query'; type KueryNode = any; -import { ALL_NAMESPACES_STRING, DEFAULT_NAMESPACE_STRING } from '../utils'; -import { SavedObjectTypeRegistry } from '../../../saved_objects_type_registry'; +import { + ALL_NAMESPACES_STRING, + DEFAULT_NAMESPACE_STRING, +} from '@kbn/core-saved-objects-utils-server'; +import { SavedObjectTypeRegistry } from '@kbn/core-saved-objects-base-server-internal'; import { getQueryParams } from './query_params'; const registerTypes = (registry: SavedObjectTypeRegistry) => { diff --git a/src/core/server/saved_objects/service/lib/search_dsl/query_params.ts b/src/core/server/saved_objects/service/lib/search_dsl/query_params.ts index 1c21a7177faf4b..669f2a273569ba 100644 --- a/src/core/server/saved_objects/service/lib/search_dsl/query_params.ts +++ b/src/core/server/saved_objects/service/lib/search_dsl/query_params.ts @@ -11,7 +11,10 @@ import * as esKuery from '@kbn/es-query'; type KueryNode = any; import type { ISavedObjectTypeRegistry } from '@kbn/core-saved-objects-server'; -import { ALL_NAMESPACES_STRING, DEFAULT_NAMESPACE_STRING } from '../utils'; +import { + ALL_NAMESPACES_STRING, + DEFAULT_NAMESPACE_STRING, +} from '@kbn/core-saved-objects-utils-server'; import { getReferencesFilter } from './references_filter'; /** diff --git a/src/core/server/saved_objects/service/lib/search_dsl/search_dsl.test.ts b/src/core/server/saved_objects/service/lib/search_dsl/search_dsl.test.ts index b15560b82ab317..d1ed7251b2414b 100644 --- a/src/core/server/saved_objects/service/lib/search_dsl/search_dsl.test.ts +++ b/src/core/server/saved_objects/service/lib/search_dsl/search_dsl.test.ts @@ -10,7 +10,7 @@ jest.mock('./pit_params'); jest.mock('./query_params'); jest.mock('./sorting_params'); -import { typeRegistryMock } from '../../../saved_objects_type_registry.mock'; +import { typeRegistryMock } from '@kbn/core-saved-objects-base-server-mocks'; import * as pitParamsNS from './pit_params'; import * as queryParamsNS from './query_params'; import { getSearchDsl } from './search_dsl'; diff --git a/src/core/server/saved_objects/service/lib/search_dsl/search_dsl.ts b/src/core/server/saved_objects/service/lib/search_dsl/search_dsl.ts index 7d6d31949739cf..980bf800755b93 100644 --- a/src/core/server/saved_objects/service/lib/search_dsl/search_dsl.ts +++ b/src/core/server/saved_objects/service/lib/search_dsl/search_dsl.ts @@ -11,7 +11,7 @@ import Boom from '@hapi/boom'; import * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import type { SavedObjectsPitParams } from '@kbn/core-saved-objects-api-server'; import type { ISavedObjectTypeRegistry } from '@kbn/core-saved-objects-server'; -import { IndexMapping } from '../../../mappings'; +import type { IndexMapping } from '@kbn/core-saved-objects-base-server-internal'; import { getQueryParams, HasReferenceQueryParams, SearchOperator } from './query_params'; import { getPitParams } from './pit_params'; import { getSortingParams } from './sorting_params'; diff --git a/src/core/server/saved_objects/service/lib/search_dsl/sorting_params.ts b/src/core/server/saved_objects/service/lib/search_dsl/sorting_params.ts index 030219b4ba5b10..d2308736b5dc29 100644 --- a/src/core/server/saved_objects/service/lib/search_dsl/sorting_params.ts +++ b/src/core/server/saved_objects/service/lib/search_dsl/sorting_params.ts @@ -8,7 +8,7 @@ import * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import Boom from '@hapi/boom'; -import { getProperty, IndexMapping } from '../../../mappings'; +import { getProperty, type IndexMapping } from '@kbn/core-saved-objects-base-server-internal'; const TOP_LEVEL_FIELDS = ['_id', '_score']; diff --git a/src/core/server/saved_objects/service/lib/update_objects_spaces.test.ts b/src/core/server/saved_objects/service/lib/update_objects_spaces.test.ts index dfd1600e6d218f..6e6c241965056b 100644 --- a/src/core/server/saved_objects/service/lib/update_objects_spaces.test.ts +++ b/src/core/server/saved_objects/service/lib/update_objects_spaces.test.ts @@ -17,12 +17,14 @@ import { elasticsearchClientMock } from '@kbn/core-elasticsearch-client-server-m import { loggerMock } from '@kbn/logging-mocks'; import type { SavedObjectsUpdateObjectsSpacesObject } from '@kbn/core-saved-objects-api-server'; -import { typeRegistryMock } from '../../saved_objects_type_registry.mock'; -import { SavedObjectsSerializer } from '../../serialization'; +import { + SavedObjectsErrorHelpers, + ALL_NAMESPACES_STRING, +} from '@kbn/core-saved-objects-utils-server'; +import { SavedObjectsSerializer } from '@kbn/core-saved-objects-base-server-internal'; +import { typeRegistryMock } from '@kbn/core-saved-objects-base-server-mocks'; import type { UpdateObjectsSpacesParams } from './update_objects_spaces'; import { updateObjectsSpaces } from './update_objects_spaces'; -import { ALL_NAMESPACES_STRING } from './utils'; -import { SavedObjectsErrorHelpers } from './errors'; type SetupParams = Partial< Pick diff --git a/src/core/server/saved_objects/service/lib/update_objects_spaces.ts b/src/core/server/saved_objects/service/lib/update_objects_spaces.ts index a92f9a952af185..4053fcff4a8ea0 100644 --- a/src/core/server/saved_objects/service/lib/update_objects_spaces.ts +++ b/src/core/server/saved_objects/service/lib/update_objects_spaces.ts @@ -22,10 +22,15 @@ import type { ISavedObjectTypeRegistry, SavedObjectsRawDocSource, } from '@kbn/core-saved-objects-server'; -import type { IndexMapping } from '../../mappings'; -import type { SavedObjectsSerializer } from '../../serialization'; -import type { DecoratedError } from './errors'; -import { SavedObjectsErrorHelpers } from './errors'; +import { + SavedObjectsErrorHelpers, + ALL_NAMESPACES_STRING, + type DecoratedError, +} from '@kbn/core-saved-objects-utils-server'; +import type { + IndexMapping, + SavedObjectsSerializer, +} from '@kbn/core-saved-objects-base-server-internal'; import { getBulkOperationError, getExpectedVersionProperties, @@ -36,7 +41,6 @@ import { } from './internal_utils'; import { DEFAULT_REFRESH_SETTING } from './repository'; import type { RepositoryEsClient } from './repository_es_client'; -import { ALL_NAMESPACES_STRING } from './utils'; import type { DeleteLegacyUrlAliasesParams } from './legacy_url_aliases'; import { deleteLegacyUrlAliases } from './legacy_url_aliases'; diff --git a/src/core/server/saved_objects/service/saved_objects_client.mock.ts b/src/core/server/saved_objects/service/saved_objects_client.mock.ts index fe5ea92ed07660..55a96ea3cecfc0 100644 --- a/src/core/server/saved_objects/service/saved_objects_client.mock.ts +++ b/src/core/server/saved_objects/service/saved_objects_client.mock.ts @@ -7,7 +7,7 @@ */ import type { SavedObjectsClientContract } from '@kbn/core-saved-objects-api-server'; -import { SavedObjectsErrorHelpers } from './lib/errors'; +import { SavedObjectsErrorHelpers } from '@kbn/core-saved-objects-utils-server'; import { savedObjectsPointInTimeFinderMock } from './lib/point_in_time_finder.mock'; const create = () => { diff --git a/src/core/server/saved_objects/service/saved_objects_client.ts b/src/core/server/saved_objects/service/saved_objects_client.ts index c9cfd9e7200567..7c2b3a205b76d5 100644 --- a/src/core/server/saved_objects/service/saved_objects_client.ts +++ b/src/core/server/saved_objects/service/saved_objects_client.ts @@ -40,7 +40,7 @@ import type { SavedObjectsCreatePointInTimeFinderOptions, SavedObjectsFindOptions, } from '@kbn/core-saved-objects-api-server'; -import { SavedObjectsErrorHelpers } from './lib/errors'; +import { SavedObjectsErrorHelpers } from '@kbn/core-saved-objects-utils-server'; /** * Core internal implementation of {@link SavedObjectsClientContract} diff --git a/src/core/server/saved_objects/version/index.ts b/src/core/server/saved_objects/version/index.ts deleted file mode 100644 index 715073fb98e7d5..00000000000000 --- a/src/core/server/saved_objects/version/index.ts +++ /dev/null @@ -1,12 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -export * from './encode_version'; -export * from './encode_hit_version'; -export * from './decode_version'; -export * from './decode_request_version'; diff --git a/src/core/server/server.ts b/src/core/server/server.ts index 42878ca66e6140..82705f2428e5cf 100644 --- a/src/core/server/server.ts +++ b/src/core/server/server.ts @@ -45,6 +45,10 @@ import { import { MetricsService, opsConfig } from '@kbn/core-metrics-server-internal'; import { CapabilitiesService } from '@kbn/core-capabilities-server-internal'; import type { SavedObjectsServiceStart } from '@kbn/core-saved-objects-server'; +import { + savedObjectsConfig, + savedObjectsMigrationConfig, +} from '@kbn/core-saved-objects-base-server-internal'; import { CoreApp } from './core_app'; import { I18nService } from './i18n'; import { HttpResourcesService } from './http_resources'; @@ -53,9 +57,8 @@ import { UiSettingsService } from './ui_settings'; import { PluginsService, config as pluginsConfig } from './plugins'; import { SavedObjectsService } from './saved_objects'; // do not try to shorten the import to `./status`, it will break server test mocking -import { StatusService } from './status/status_service'; -import { savedObjectsConfig, savedObjectsMigrationConfig } from './saved_objects'; +import { StatusService } from './status/status_service'; import { config as uiSettingsConfig } from './ui_settings'; import { config as statusConfig } from './status'; import { config as i18nConfig } from './i18n'; diff --git a/src/core/server/ui_settings/create_or_upgrade_saved_config/create_or_upgrade_saved_config.test.ts b/src/core/server/ui_settings/create_or_upgrade_saved_config/create_or_upgrade_saved_config.test.ts index c5a9c9729b78ae..6102ff6f7b1bee 100644 --- a/src/core/server/ui_settings/create_or_upgrade_saved_config/create_or_upgrade_saved_config.test.ts +++ b/src/core/server/ui_settings/create_or_upgrade_saved_config/create_or_upgrade_saved_config.test.ts @@ -10,7 +10,7 @@ import { mockTransform, mockGetUpgradeableConfig, } from './create_or_upgrade_saved_config.test.mock'; -import { SavedObjectsErrorHelpers } from '../../saved_objects'; +import { SavedObjectsErrorHelpers } from '@kbn/core-saved-objects-utils-server'; import { savedObjectsClientMock } from '../../saved_objects/service/saved_objects_client.mock'; import { loggingSystemMock } from '@kbn/core-logging-server-mocks'; diff --git a/src/core/server/ui_settings/create_or_upgrade_saved_config/create_or_upgrade_saved_config.ts b/src/core/server/ui_settings/create_or_upgrade_saved_config/create_or_upgrade_saved_config.ts index def1b587841742..e453c9cf46f31a 100644 --- a/src/core/server/ui_settings/create_or_upgrade_saved_config/create_or_upgrade_saved_config.ts +++ b/src/core/server/ui_settings/create_or_upgrade_saved_config/create_or_upgrade_saved_config.ts @@ -11,7 +11,7 @@ import { defaults } from 'lodash'; import type { Logger, LogMeta } from '@kbn/logging'; import { asyncForEach } from '@kbn/std'; import type { SavedObjectsClientContract } from '@kbn/core-saved-objects-api-server'; -import { SavedObjectsErrorHelpers } from '../../saved_objects'; +import { SavedObjectsErrorHelpers } from '@kbn/core-saved-objects-utils-server'; import { getUpgradeableConfig } from './get_upgradeable_config'; import { transforms } from '../saved_objects'; diff --git a/src/core/server/ui_settings/routes/delete.ts b/src/core/server/ui_settings/routes/delete.ts index 705a5319c1cf5b..4147358d4e1eef 100644 --- a/src/core/server/ui_settings/routes/delete.ts +++ b/src/core/server/ui_settings/routes/delete.ts @@ -8,7 +8,7 @@ import { schema } from '@kbn/config-schema'; -import { SavedObjectsErrorHelpers } from '../../saved_objects'; +import { SavedObjectsErrorHelpers } from '@kbn/core-saved-objects-utils-server'; import type { InternalUiSettingsRouter } from '../internal_types'; import { CannotOverrideError } from '../ui_settings_errors'; diff --git a/src/core/server/ui_settings/routes/get.ts b/src/core/server/ui_settings/routes/get.ts index c940c2e1fe71ef..2603526c375035 100644 --- a/src/core/server/ui_settings/routes/get.ts +++ b/src/core/server/ui_settings/routes/get.ts @@ -6,8 +6,8 @@ * Side Public License, v 1. */ +import { SavedObjectsErrorHelpers } from '@kbn/core-saved-objects-utils-server'; import type { InternalUiSettingsRouter } from '../internal_types'; -import { SavedObjectsErrorHelpers } from '../../saved_objects'; export function registerGetRoute(router: InternalUiSettingsRouter) { router.get( diff --git a/src/core/server/ui_settings/routes/set.ts b/src/core/server/ui_settings/routes/set.ts index af62fda0144b61..61493be876ad70 100644 --- a/src/core/server/ui_settings/routes/set.ts +++ b/src/core/server/ui_settings/routes/set.ts @@ -8,7 +8,7 @@ import { schema, ValidationError } from '@kbn/config-schema'; -import { SavedObjectsErrorHelpers } from '../../saved_objects'; +import { SavedObjectsErrorHelpers } from '@kbn/core-saved-objects-utils-server'; import type { InternalUiSettingsRouter } from '../internal_types'; import { CannotOverrideError } from '../ui_settings_errors'; diff --git a/src/core/server/ui_settings/routes/set_many.ts b/src/core/server/ui_settings/routes/set_many.ts index fe0ee1a0a721fd..3bbe14c4a00762 100644 --- a/src/core/server/ui_settings/routes/set_many.ts +++ b/src/core/server/ui_settings/routes/set_many.ts @@ -8,7 +8,7 @@ import { schema, ValidationError } from '@kbn/config-schema'; -import { SavedObjectsErrorHelpers } from '../../saved_objects'; +import { SavedObjectsErrorHelpers } from '@kbn/core-saved-objects-utils-server'; import type { InternalUiSettingsRouter } from '../internal_types'; import { CannotOverrideError } from '../ui_settings_errors'; diff --git a/src/core/server/ui_settings/saved_objects/migrations.test.ts b/src/core/server/ui_settings/saved_objects/migrations.test.ts index df561ef4152f6c..c08f75ad9d184a 100644 --- a/src/core/server/ui_settings/saved_objects/migrations.test.ts +++ b/src/core/server/ui_settings/saved_objects/migrations.test.ts @@ -310,3 +310,38 @@ describe('ui_settings 8.1.0 migrations', () => { }); }); }); + +describe('ui_settings 8.5.0 migrations', () => { + const migration = migrations['8.5.0']; + + test('returns doc on empty object', () => { + expect(migration({} as SavedObjectUnsanitizedDoc)).toEqual({ + references: [], + }); + }); + + test('removes "observability:enableInfrastructureView" setting', () => { + const doc = { + type: 'config', + id: '8.5.0', + attributes: { + buildNum: 9007199254740991, + 'observability:enableInfrastructureView': true, + }, + references: [], + updated_at: '2020-06-09T20:18:20.349Z', + migrationVersion: {}, + }; + + expect(migration(doc)).toEqual({ + type: 'config', + id: '8.5.0', + attributes: { + buildNum: 9007199254740991, + }, + references: [], + updated_at: '2020-06-09T20:18:20.349Z', + migrationVersion: {}, + }); + }); +}); diff --git a/src/core/server/ui_settings/saved_objects/migrations.ts b/src/core/server/ui_settings/saved_objects/migrations.ts index 7ed65cfe61894b..73b51254d18696 100644 --- a/src/core/server/ui_settings/saved_objects/migrations.ts +++ b/src/core/server/ui_settings/saved_objects/migrations.ts @@ -138,4 +138,25 @@ export const migrations = { }), references: doc.references || [], }), + '8.5.0': (doc: SavedObjectUnsanitizedDoc): SavedObjectSanitizedDoc => ({ + ...doc, + ...(doc.attributes && { + attributes: Object.keys(doc.attributes).reduce( + (acc, key) => + [ + // owner: Team:Apm + 'observability:enableInfrastructureView', + ].includes(key) + ? { + ...acc, + } + : { + ...acc, + [key]: doc.attributes[key], + }, + {} + ), + }), + references: doc.references || [], + }), }; diff --git a/src/core/server/ui_settings/saved_objects/transforms.test.ts b/src/core/server/ui_settings/saved_objects/transforms.test.ts index afcd525673aa09..279dfd637b9e28 100644 --- a/src/core/server/ui_settings/saved_objects/transforms.test.ts +++ b/src/core/server/ui_settings/saved_objects/transforms.test.ts @@ -7,7 +7,7 @@ */ import { savedObjectsClientMock } from '../../mocks'; -import { SavedObjectsErrorHelpers } from '../../saved_objects'; +import { SavedObjectsErrorHelpers } from '@kbn/core-saved-objects-utils-server'; import { SavedObject } from '../../types'; import type { UpgradeableConfigAttributes } from '../create_or_upgrade_saved_config'; import { transformDefaultIndex } from './transforms'; diff --git a/src/core/server/ui_settings/saved_objects/transforms.ts b/src/core/server/ui_settings/saved_objects/transforms.ts index cabf14a2e6469e..797b895f91556d 100644 --- a/src/core/server/ui_settings/saved_objects/transforms.ts +++ b/src/core/server/ui_settings/saved_objects/transforms.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import { SavedObjectsErrorHelpers } from '../../saved_objects'; +import { SavedObjectsErrorHelpers } from '@kbn/core-saved-objects-utils-server'; import type { SavedObjectsClientContract } from '../../types'; import type { UpgradeableConfigAttributes } from '../create_or_upgrade_saved_config'; diff --git a/src/core/server/ui_settings/ui_settings_client.ts b/src/core/server/ui_settings/ui_settings_client.ts index 5175af54ffe3ef..aa7d344881cf60 100644 --- a/src/core/server/ui_settings/ui_settings_client.ts +++ b/src/core/server/ui_settings/ui_settings_client.ts @@ -8,7 +8,7 @@ import type { Logger } from '@kbn/logging'; import type { SavedObjectsClientContract } from '@kbn/core-saved-objects-api-server'; -import { SavedObjectsErrorHelpers } from '../saved_objects'; +import { SavedObjectsErrorHelpers } from '@kbn/core-saved-objects-utils-server'; import { createOrUpgradeSavedConfig } from './create_or_upgrade_saved_config'; import { UiSettingsParams } from './types'; import { CannotOverrideError } from './ui_settings_errors'; diff --git a/src/dev/build/tasks/build_packages_task.ts b/src/dev/build/tasks/build_packages_task.ts index 607e0ac0f08baf..521b1299f423d0 100644 --- a/src/dev/build/tasks/build_packages_task.ts +++ b/src/dev/build/tasks/build_packages_task.ts @@ -8,6 +8,7 @@ import Path from 'path'; +import { REPO_ROOT } from '@kbn/utils'; import { discoverBazelPackages } from '@kbn/bazel-packages'; import { runBazel } from '@kbn/bazel-runner'; @@ -16,7 +17,7 @@ import { Task, scanCopy, write } from '../lib'; export const BuildBazelPackages: Task = { description: 'Building distributable versions of Bazel packages', async run(config, log, build) { - const packages = (await discoverBazelPackages()).filter((pkg) => !pkg.isDevOnly()); + const packages = (await discoverBazelPackages(REPO_ROOT)).filter((pkg) => !pkg.isDevOnly()); log.info(`Preparing Bazel projects production build non-devOnly packages`); await runBazel(['build', '//packages:build']); diff --git a/src/dev/build/tasks/clean_tasks.ts b/src/dev/build/tasks/clean_tasks.ts index 6184c568df07d9..409f6a77b50bfc 100644 --- a/src/dev/build/tasks/clean_tasks.ts +++ b/src/dev/build/tasks/clean_tasks.ts @@ -8,6 +8,7 @@ import minimatch from 'minimatch'; import { discoverBazelPackages } from '@kbn/bazel-packages'; +import { REPO_ROOT } from '@kbn/utils'; import { deleteAll, deleteEmptyFolders, scanDelete, Task, GlobalTask } from '../lib'; export const Clean: GlobalTask = { @@ -70,6 +71,8 @@ export const CleanExtraFilesFromModules: Task = { '**/Changelog.md', '**/changelog.md', + '**/CODE_OF_CONDUCT.md', + // examples '**/example', '**/examples', @@ -150,6 +153,9 @@ export const CleanExtraFilesFromModules: Task = { '**/.codecov.yml', '**/.airtap.yml', '**/.gitpod.yml', + '**/karma.conf.ci.js', + '**/karma.conf.js', + '**/karma-ci.conf.js', // metadata '**/package-lock.json', @@ -178,7 +184,25 @@ export const CleanExtraFilesFromModules: Task = { '**/*.tgz', '**/*.gz', + '**/*.cc', + '**/*.pl', + '**/*.py', + '**/*.gz', + '**/*.h', '**/*.xml', + '**/*.html', + + '**/*.development.js', + '**/*.dev.js', + '**/benchmark', + '**/benchmarks', + '**/benchmark.js', + '**/benchmarks.js', + + '**/rollup.config.js', + '**/webpack.config.js', + '**/commitlint.config.js', + '**/styleguide.config.js', '**/@elastic/eui/es', '**/@elastic/eui/test-env', @@ -236,7 +260,7 @@ export const DeleteBazelPackagesFromBuildRoot: Task = { 'Deleting bazel packages outputs from build folder root as they are now installed as node_modules', async run(config, log, build) { - const bazelPackagesOnBuildRoot = (await discoverBazelPackages()).map((pkg) => + const bazelPackagesOnBuildRoot = (await discoverBazelPackages(REPO_ROOT)).map((pkg) => build.resolvePath(pkg.normalizedRepoRelativeDir) ); diff --git a/src/dev/build/tasks/copy_source_task.ts b/src/dev/build/tasks/copy_source_task.ts index 0e4407cf767b01..27426f25b90f8f 100644 --- a/src/dev/build/tasks/copy_source_task.ts +++ b/src/dev/build/tasks/copy_source_task.ts @@ -40,10 +40,15 @@ export const CopySource: Task = { '!**/jest*', '!**/*.{story,stories}.{js,ts}', - '!**/test_mocks.ts', + '!**/{test_mocks,stubs}.ts', '!**/*.{scss,console,d.ts,sh,md,mdx,asciidoc,docnav.json}', '!**/*.{test,test.mocks,mock,mocks,spec}.*', '!**/{packages,dev_docs,docs,public,__stories__,storybook,.storybook,ftr_e2e,e2e,scripts,test,tests,test_resources,test_data,__tests__,manual_tests,__jest__,__snapshots__,__mocks__,mock_responses,mocks,fixtures,__fixtures__,cypress,integration_tests}/**', + + '!x-pack/plugins/lens/to_playground.gif', // README.md + '!x-pack/plugins/lens/layout.png', // README.md + '!x-pack/plugins/cases/images', // README.md + '!x-pack/plugins/canvas/images', // unused ]; const piscina = new Piscina({ diff --git a/src/dev/build/tasks/nodejs/clean_node_builds_task.ts b/src/dev/build/tasks/nodejs/clean_node_builds_task.ts index 350395f94c355e..bfa34d68f2a06f 100644 --- a/src/dev/build/tasks/nodejs/clean_node_builds_task.ts +++ b/src/dev/build/tasks/nodejs/clean_node_builds_task.ts @@ -19,6 +19,8 @@ export const CleanNodeBuilds: Task = { build.resolvePathForPlatform(platform, 'node/bin/npm'), build.resolvePathForPlatform(platform, 'node/bin/npx'), build.resolvePathForPlatform(platform, 'node/bin/corepack'), + build.resolvePathForPlatform(platform, 'node/CHANGELOG.md'), + build.resolvePathForPlatform(platform, 'node/README.md'), ], log ); diff --git a/src/dev/license_checker/config.ts b/src/dev/license_checker/config.ts index 02649c2fc5b881..fea4d101c64ea5 100644 --- a/src/dev/license_checker/config.ts +++ b/src/dev/license_checker/config.ts @@ -67,6 +67,7 @@ export const LICENSE_ALLOWED = [ 'WTFPL', 'Nuclide software', 'Python-2.0', + '(Apache-2.0 AND MIT)', ]; // The following list only applies to licenses that diff --git a/src/dev/precommit_hook/casing_check_config.js b/src/dev/precommit_hook/casing_check_config.js index 0c65b924f14b1d..418a8f448b2c82 100644 --- a/src/dev/precommit_hook/casing_check_config.js +++ b/src/dev/precommit_hook/casing_check_config.js @@ -54,7 +54,7 @@ export const IGNORE_FILE_GLOBS = [ '**/preview-head.html', // filename must match upstream filenames from lodash - 'packages/elastic-safer-lodash-set/**/*', + 'packages/kbn-safer-lodash-set/**/*', // filename must match upstream filenames from handlebars 'packages/kbn-handlebars/src/upstream/**/*', diff --git a/src/dev/storybook/aliases.ts b/src/dev/storybook/aliases.ts index 65035c0c95f720..7bb26e526be3d2 100644 --- a/src/dev/storybook/aliases.ts +++ b/src/dev/storybook/aliases.ts @@ -39,7 +39,7 @@ export const storybookAliases = { observability: 'x-pack/plugins/observability/.storybook', presentation: 'src/plugins/presentation_util/storybook', security_solution: 'x-pack/plugins/security_solution/.storybook', - shared_ux: 'packages/kbn-shared-ux-storybook/src/config', + shared_ux: 'packages/shared-ux/storybook/config', threat_intelligence: 'x-pack/plugins/threat_intelligence/.storybook', ui_actions_enhanced: 'src/plugins/ui_actions_enhanced/.storybook', unified_search: 'src/plugins/unified_search/.storybook', diff --git a/src/plugins/chart_expressions/expression_metric/common/expression_functions/metric_vis_function.ts b/src/plugins/chart_expressions/expression_metric/common/expression_functions/metric_vis_function.ts index d01a2400e038ad..10067f702d9068 100644 --- a/src/plugins/chart_expressions/expression_metric/common/expression_functions/metric_vis_function.ts +++ b/src/plugins/chart_expressions/expression_metric/common/expression_functions/metric_vis_function.ts @@ -102,6 +102,7 @@ export const metricVisFunction = (): MetricVisExpressionFunctionDefinition => ({ fn(input, args, handlers) { validateAccessor(args.metric, input.columns); validateAccessor(args.secondaryMetric, input.columns); + validateAccessor(args.max, input.columns); validateAccessor(args.breakdownBy, input.columns); if (handlers?.inspectorAdapters?.tables) { diff --git a/src/plugins/chart_expressions/expression_metric/public/components/metric_vis.test.tsx b/src/plugins/chart_expressions/expression_metric/public/components/metric_vis.test.tsx index a941bd760c4b8e..c94a0688588a1c 100644 --- a/src/plugins/chart_expressions/expression_metric/public/components/metric_vis.test.tsx +++ b/src/plugins/chart_expressions/expression_metric/public/components/metric_vis.test.tsx @@ -253,7 +253,7 @@ describe('MetricVisComponent', function () { } `); }); - it('should display subtitle and secondary prefix', () => { + it('should display subtitle', () => { const component = shallow( , - "subtitle": "subtitle", - "title": "Median products.base_price", - "value": 28.984375, - "valueFormatter": [Function], - } - `); }); it('should display secondary metric', () => { - const component = shallow( - + const getMetricConfig = (localConfig: MetricVisComponentProps['config']) => + shallow() + .find(Metric) + .props().data![0][0]!; + + const configNoPrefix = getMetricConfig({ + ...config, + metric: { ...config.metric, subtitle: 'subtitle', secondaryPrefix: undefined }, + dimensions: { ...config.dimensions, secondaryMetric: minPriceColumnId }, + }); + + expect(configNoPrefix!.extra).toEqual( + + {table.columns.find((col) => col.id === minPriceColumnId)!.name} + {' ' + 13.63} + ); - const [[visConfig]] = component.find(Metric).props().data!; + const configWithPrefix = getMetricConfig({ + ...config, + metric: { ...config.metric, subtitle: 'subtitle', secondaryPrefix: 'secondary prefix' }, + dimensions: { ...config.dimensions, secondaryMetric: minPriceColumnId }, + }); - expect(visConfig!.extra).toEqual( + expect(configWithPrefix!.extra).toEqual( {'secondary prefix'} {' ' + 13.63} ); - expect(visConfig).toMatchInlineSnapshot(` + expect(configWithPrefix).toMatchInlineSnapshot(` Object { "color": "#f5f7fa", "extra": @@ -1217,5 +1216,16 @@ describe('MetricVisComponent', function () { }, }); }); + + it('ignores suffix formatting', () => { + const { primary, secondary } = getFormattedMetrics(0.23939, 11.2, { + id: 'suffix', + params: { + id: 'percent', + }, + }); + expect(primary).toBe('23.94%'); + expect(secondary).toBe('1.12K%'); + }); }); }); diff --git a/src/plugins/chart_expressions/expression_metric/public/components/metric_vis.tsx b/src/plugins/chart_expressions/expression_metric/public/components/metric_vis.tsx index cbc92bfacba40c..05a0266e676d05 100644 --- a/src/plugins/chart_expressions/expression_metric/public/components/metric_vis.tsx +++ b/src/plugins/chart_expressions/expression_metric/public/components/metric_vis.tsx @@ -80,7 +80,10 @@ const getMetricFormatter = ( columns: Datatable['columns'] ) => { const serializedFieldFormat = getFormatByAccessor(accessor, columns); - const formatId = serializedFieldFormat?.id ?? 'number'; + const formatId = + (serializedFieldFormat?.id === 'suffix' + ? serializedFieldFormat.params?.id + : serializedFieldFormat?.id) ?? 'number'; if ( !['number', 'currency', 'percent', 'bytes', 'duration', 'string', 'null'].includes(formatId) @@ -160,16 +163,11 @@ const getColor = ( data: Datatable, rowNumber: number ) => { - let minBound = paletteParams.rangeMin; - let maxBound = paletteParams.rangeMax; - const { min, max } = getDataBoundsForPalette(accessors, data, rowNumber); - minBound = min; - maxBound = max; return getPaletteService().get(CUSTOM_PALETTE)?.getColorForValue?.(value, paletteParams, { - min: minBound, - max: maxBound, + min, + max, }); }; @@ -244,6 +242,7 @@ export const MetricVis = ({ ? formatBreakdownValue(row[breakdownByColumn.id]) : primaryMetricColumn.name; const subtitle = breakdownByColumn ? primaryMetricColumn.name : config.metric.subtitle; + const secondaryPrefix = config.metric.secondaryPrefix ?? secondaryMetricColumn?.name; return { value, valueFormatter: formatPrimaryMetric, @@ -251,9 +250,9 @@ export const MetricVis = ({ subtitle, extra: ( - {config.metric.secondaryPrefix} + {secondaryPrefix} {secondaryMetricColumn - ? `${config.metric.secondaryPrefix ? ' ' : ''}${formatSecondaryMetric!( + ? `${secondaryPrefix ? ' ' : ''}${formatSecondaryMetric!( row[secondaryMetricColumn.id] )}` : undefined} diff --git a/src/plugins/charts/public/index.ts b/src/plugins/charts/public/index.ts index d6cae90d50057d..8fd3fcf29f2cb3 100644 --- a/src/plugins/charts/public/index.ts +++ b/src/plugins/charts/public/index.ts @@ -9,6 +9,7 @@ // TODO: https://github.com/elastic/kibana/issues/110891 /* eslint-disable @kbn/eslint/no_export_all */ +import { RangeSelectContext, ValueClickContext } from '@kbn/embeddable-plugin/public'; import { ChartsPlugin } from './plugin'; export const plugin = () => new ChartsPlugin(); @@ -19,6 +20,16 @@ export * from './static'; export { lightenColor } from './services/palettes/lighten_color'; export { useActiveCursor } from './services/active_cursor'; +export interface ClickTriggerEvent { + name: 'filter'; + data: ValueClickContext['data']; +} + +export interface BrushTriggerEvent { + name: 'brush'; + data: RangeSelectContext['data']; +} + export type { CustomPaletteArguments, CustomPaletteState, diff --git a/src/plugins/charts/public/static/index.ts b/src/plugins/charts/public/static/index.ts index 53078eebe9c56f..031e90019d3c11 100644 --- a/src/plugins/charts/public/static/index.ts +++ b/src/plugins/charts/public/static/index.ts @@ -8,5 +8,4 @@ export * from './colors'; export * from './components'; -export * from './utils'; export * from '../../common/static/styles'; diff --git a/src/plugins/charts/public/static/utils/transform_click_event.ts b/src/plugins/charts/public/static/utils/transform_click_event.ts deleted file mode 100644 index ec35fa85d59a17..00000000000000 --- a/src/plugins/charts/public/static/utils/transform_click_event.ts +++ /dev/null @@ -1,282 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { - XYChartSeriesIdentifier, - GeometryValue, - XYBrushEvent, - Accessor, - AccessorFn, - Datum, -} from '@elastic/charts'; - -import { RangeSelectContext, ValueClickContext } from '@kbn/embeddable-plugin/public'; -import { Datatable } from '@kbn/expressions-plugin/public'; - -export interface ClickTriggerEvent { - name: 'filter'; - data: ValueClickContext['data']; -} - -export interface BrushTriggerEvent { - name: 'brush'; - data: RangeSelectContext['data']; -} - -type AllSeriesAccessors = Array< - [accessor: Accessor | AccessorFn, value: string | number] ->; - -/** - * returns accessor value from string or function accessor - * @param datum - * @param accessor - */ -function getAccessorValue(datum: D, accessor: Accessor | AccessorFn) { - if (typeof accessor === 'function') { - return accessor(datum); - } - - return (datum as Datum)[accessor]; -} - -/** - * This is a little unorthodox, but using functional accessors makes it - * difficult to match the correct column. This creates a test object to throw - * an error when the target id is accessed, thus matcing the target column. - */ -function validateAccessorId(id: string, accessor: Accessor | AccessorFn) { - if (typeof accessor !== 'function') { - return id === accessor; - } - - const matchedMessage = 'validateAccessorId matched'; - - try { - accessor({ - get [id]() { - throw new Error(matchedMessage); - }, - }); - return false; - } catch ({ message }) { - return message === matchedMessage; - } -} - -/** - * Groups split accessors by their accessor string or function and related value - * - * @param splitAccessors - * @param splitSeriesAccessorFnMap - */ -const getAllSplitAccessors = ( - splitAccessors: Map, - splitSeriesAccessorFnMap?: Map -): Array<[accessor: Accessor | AccessorFn, value: string | number]> => - [...splitAccessors.entries()].map(([key, value]) => [ - splitSeriesAccessorFnMap?.get?.(key) ?? key, - value, - ]); - -/** - * Gets value from small multiple accessors - * - * Only handles single small multiple accessor - */ -function getSplitChartValue({ - smHorizontalAccessorValue, - smVerticalAccessorValue, -}: Pick): - | string - | number - | undefined { - if (smHorizontalAccessorValue !== undefined) { - return smHorizontalAccessorValue; - } - - if (smVerticalAccessorValue !== undefined) { - return smVerticalAccessorValue; - } - - return; -} - -/** - * Reduces matching column indexes - * - * @param xAccessor - * @param yAccessor - * @param splitAccessors - */ -const columnReducer = - ( - xAccessor: Accessor | AccessorFn | null, - yAccessor: Accessor | AccessorFn | null, - splitAccessors: AllSeriesAccessors, - splitChartAccessor?: Accessor | AccessorFn - ) => - ( - acc: Array<[index: number, id: string]>, - { id }: Datatable['columns'][number], - index: number - ): Array<[index: number, id: string]> => { - if ( - (xAccessor !== null && validateAccessorId(id, xAccessor)) || - (yAccessor !== null && validateAccessorId(id, yAccessor)) || - (splitChartAccessor !== undefined && validateAccessorId(id, splitChartAccessor)) || - splitAccessors.some(([accessor]) => validateAccessorId(id, accessor)) - ) { - acc.push([index, id]); - } - - return acc; - }; - -/** - * Finds matching row index for given accessors and geometry values - * - * @param geometry - * @param xAccessor - * @param yAccessor - * @param splitAccessors - */ -const rowFindPredicate = - ( - geometry: GeometryValue | null, - xAccessor: Accessor | AccessorFn | null, - yAccessor: Accessor | AccessorFn | null, - splitAccessors: AllSeriesAccessors, - splitChartAccessor?: Accessor | AccessorFn, - splitChartValue?: string | number - ) => - (row: Datatable['rows'][number]): boolean => - (geometry === null || - (xAccessor !== null && - getAccessorValue(row, xAccessor) === getAccessorValue(geometry.datum, xAccessor) && - yAccessor !== null && - getAccessorValue(row, yAccessor) === getAccessorValue(geometry.datum, yAccessor) && - (splitChartAccessor === undefined || - (splitChartValue !== undefined && - getAccessorValue(row, splitChartAccessor) === splitChartValue)))) && - [...splitAccessors].every(([accessor, value]) => getAccessorValue(row, accessor) === value); - -/** - * Helper function to transform `@elastic/charts` click event into filter action event - * - * @param table - * @param xAccessor - * @param splitSeriesAccessorFnMap needed when using `splitSeriesAccessors` as `AccessorFn` - * @param negate - */ -export const getFilterFromChartClickEventFn = - ( - table: Datatable, - xAccessor: Accessor | AccessorFn, - splitSeriesAccessorFnMap?: Map, - splitChartAccessor?: Accessor | AccessorFn, - negate: boolean = false - ) => - (points: Array<[GeometryValue, XYChartSeriesIdentifier]>): ClickTriggerEvent => { - const data: ValueClickContext['data']['data'] = []; - - points.forEach((point) => { - const [geometry, { yAccessor, splitAccessors }] = point; - const splitChartValue = getSplitChartValue(point[1]); - const allSplitAccessors = getAllSplitAccessors(splitAccessors, splitSeriesAccessorFnMap); - const columns = table.columns.reduce>( - columnReducer(xAccessor, yAccessor, allSplitAccessors, splitChartAccessor), - [] - ); - const row = table.rows.findIndex( - rowFindPredicate( - geometry, - xAccessor, - yAccessor, - allSplitAccessors, - splitChartAccessor, - splitChartValue - ) - ); - const newData = columns.map(([column, id]) => ({ - table, - column, - row, - value: table.rows?.[row]?.[id] ?? null, - })); - - data.push(...newData); - }); - - return { - name: 'filter', - data: { - negate, - data, - }, - }; - }; - -/** - * Helper function to get filter action event from series - */ -export const getFilterFromSeriesFn = - (table: Datatable) => - ( - { splitAccessors, ...rest }: XYChartSeriesIdentifier, - splitSeriesAccessorFnMap?: Map, - splitChartAccessor?: Accessor | AccessorFn, - negate = false - ): ClickTriggerEvent => { - const splitChartValue = getSplitChartValue(rest); - const allSplitAccessors = getAllSplitAccessors(splitAccessors, splitSeriesAccessorFnMap); - const columns = table.columns.reduce>( - columnReducer(null, null, allSplitAccessors, splitChartAccessor), - [] - ); - const row = table.rows.findIndex( - rowFindPredicate(null, null, null, allSplitAccessors, splitChartAccessor, splitChartValue) - ); - const data: ValueClickContext['data']['data'] = columns.map(([column, id]) => ({ - table, - column, - row, - value: table.rows?.[row]?.[id] ?? null, - })); - - return { - name: 'filter', - data: { - negate, - data, - }, - }; - }; - -/** - * Helper function to transform `@elastic/charts` brush event into brush action event - */ -export function getBrushFromChartBrushEventFn( - table: Datatable, - xAccessor: Accessor | AccessorFn -) { - return ({ x: selectedRange }: XYBrushEvent): BrushTriggerEvent => { - const [start, end] = selectedRange ?? [0, 0]; - const range: [number, number] = [start, end]; - const column = table.columns.findIndex(({ id }) => validateAccessorId(id, xAccessor)); - - return { - data: { - table, - column, - range, - }, - name: 'brush', - }; - }; -} diff --git a/src/plugins/controls/common/control_types/time_slider/time_slider_persistable_state.ts b/src/plugins/controls/common/control_types/time_slider/time_slider_persistable_state.ts deleted file mode 100644 index b8b3a5f16b51f6..00000000000000 --- a/src/plugins/controls/common/control_types/time_slider/time_slider_persistable_state.ts +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { - EmbeddableStateWithType, - EmbeddablePersistableStateService, -} from '@kbn/embeddable-plugin/common'; -import { SavedObjectReference } from '@kbn/core/types'; -import { DATA_VIEW_SAVED_OBJECT_TYPE } from '@kbn/data-views-plugin/common'; -import { TimeSliderControlEmbeddableInput } from './types'; - -type TimeSliderInputWithType = Partial & { type: string }; -const dataViewReferenceName = 'timeSliderDataView'; - -export const createTimeSliderInject = (): EmbeddablePersistableStateService['inject'] => { - return (state: EmbeddableStateWithType, references: SavedObjectReference[]) => { - const workingState = { ...state } as EmbeddableStateWithType | TimeSliderInputWithType; - references.forEach((reference) => { - if (reference.name === dataViewReferenceName) { - (workingState as TimeSliderInputWithType).dataViewId = reference.id; - } - }); - return workingState as EmbeddableStateWithType; - }; -}; - -export const createTimeSliderExtract = (): EmbeddablePersistableStateService['extract'] => { - return (state: EmbeddableStateWithType) => { - const workingState = { ...state } as EmbeddableStateWithType | TimeSliderInputWithType; - const references: SavedObjectReference[] = []; - - if ('dataViewId' in workingState) { - references.push({ - name: dataViewReferenceName, - type: DATA_VIEW_SAVED_OBJECT_TYPE, - id: workingState.dataViewId!, - }); - delete workingState.dataViewId; - } - return { state: workingState as EmbeddableStateWithType, references }; - }; -}; diff --git a/src/plugins/controls/common/control_types/time_slider/types.ts b/src/plugins/controls/common/control_types/time_slider/types.ts deleted file mode 100644 index 31272380becde9..00000000000000 --- a/src/plugins/controls/common/control_types/time_slider/types.ts +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { DataControlInput } from '../../types'; - -export const TIME_SLIDER_CONTROL = 'timeSlider'; - -export interface TimeSliderControlEmbeddableInput extends DataControlInput { - value?: [number | null, number | null]; -} diff --git a/src/plugins/controls/common/index.ts b/src/plugins/controls/common/index.ts index b8d7699e8061ae..a201553c09ec12 100644 --- a/src/plugins/controls/common/index.ts +++ b/src/plugins/controls/common/index.ts @@ -27,6 +27,7 @@ export { persistableControlGroupInputIsEqual, getDefaultControlGroupInput, } from './control_group/control_group_persistence'; + export { DEFAULT_CONTROL_WIDTH, DEFAULT_CONTROL_STYLE, @@ -34,8 +35,4 @@ export { // Control Type exports export { OPTIONS_LIST_CONTROL, type OptionsListEmbeddableInput } from './options_list/types'; -export { - type RangeSliderEmbeddableInput, - RANGE_SLIDER_CONTROL, -} from './control_types/range_slider/types'; -export { TIME_SLIDER_CONTROL } from './control_types/time_slider/types'; +export { type RangeSliderEmbeddableInput, RANGE_SLIDER_CONTROL } from './range_slider/types'; diff --git a/src/plugins/controls/common/control_types/range_slider/range_slider_persistable_state.ts b/src/plugins/controls/common/range_slider/range_slider_persistable_state.ts similarity index 89% rename from src/plugins/controls/common/control_types/range_slider/range_slider_persistable_state.ts rename to src/plugins/controls/common/range_slider/range_slider_persistable_state.ts index bb4c703ba47be8..d0dc0bd135cee3 100644 --- a/src/plugins/controls/common/control_types/range_slider/range_slider_persistable_state.ts +++ b/src/plugins/controls/common/range_slider/range_slider_persistable_state.ts @@ -12,10 +12,9 @@ import { } from '@kbn/embeddable-plugin/common'; import { SavedObjectReference } from '@kbn/core/types'; import { DATA_VIEW_SAVED_OBJECT_TYPE } from '@kbn/data-views-plugin/common'; -import { RangeSliderEmbeddableInput } from './types'; +import { RangeSliderInputWithType } from './types'; -type RangeSliderInputWithType = Partial & { type: string }; -const dataViewReferenceName = 'optionsListDataView'; +const dataViewReferenceName = 'rangeSliderDataView'; export const createRangeSliderInject = (): EmbeddablePersistableStateService['inject'] => { return (state: EmbeddableStateWithType, references: SavedObjectReference[]) => { diff --git a/src/plugins/controls/common/control_types/range_slider/types.ts b/src/plugins/controls/common/range_slider/types.ts similarity index 79% rename from src/plugins/controls/common/control_types/range_slider/types.ts rename to src/plugins/controls/common/range_slider/types.ts index a975fdd27ac314..51c6d9e07e241d 100644 --- a/src/plugins/controls/common/control_types/range_slider/types.ts +++ b/src/plugins/controls/common/range_slider/types.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import { DataControlInput } from '../../types'; +import { DataControlInput } from '../types'; export const RANGE_SLIDER_CONTROL = 'rangeSliderControl'; @@ -15,3 +15,5 @@ export type RangeValue = [string, string]; export interface RangeSliderEmbeddableInput extends DataControlInput { value: RangeValue; } + +export type RangeSliderInputWithType = Partial & { type: string }; diff --git a/src/plugins/controls/public/__stories__/storybook_control_factories.ts b/src/plugins/controls/public/__stories__/storybook_control_factories.ts index 76968f104c275c..2e27339a9eaf87 100644 --- a/src/plugins/controls/public/__stories__/storybook_control_factories.ts +++ b/src/plugins/controls/public/__stories__/storybook_control_factories.ts @@ -7,8 +7,7 @@ */ import { OptionsListEmbeddableFactory } from '../options_list'; -import { RangeSliderEmbeddableFactory } from '../control_types/range_slider'; -import { TimesliderEmbeddableFactory } from '../control_types/time_slider'; +import { RangeSliderEmbeddableFactory } from '../range_slider'; import { ControlsService } from '../services/controls'; import { ControlFactory } from '..'; @@ -26,9 +25,4 @@ export const populateStorybookControlFactories = (controlsServiceStub: ControlsS const rangeSliderControlFactory = rangeSliderFactoryStub as unknown as ControlFactory; rangeSliderControlFactory.getDefaultInput = () => ({}); controlsServiceStub.registerControlType(rangeSliderControlFactory); - - const timesliderFactoryStub = new TimesliderEmbeddableFactory(); - const timeSliderControlFactory = timesliderFactoryStub as unknown as ControlFactory; - timeSliderControlFactory.getDefaultInput = () => ({}); - controlsServiceStub.registerControlType(timeSliderControlFactory); }; diff --git a/src/plugins/controls/public/control_types/range_slider/index.ts b/src/plugins/controls/public/control_types/range_slider/index.ts deleted file mode 100644 index 5fdd29672b86fa..00000000000000 --- a/src/plugins/controls/public/control_types/range_slider/index.ts +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -export { RANGE_SLIDER_CONTROL } from '../../../common/control_types/range_slider/types'; -export { RangeSliderEmbeddableFactory } from './range_slider_embeddable_factory'; - -export type { RangeSliderEmbeddable } from './range_slider_embeddable'; -export type { RangeSliderEmbeddableInput } from '../../../common/control_types/range_slider/types'; diff --git a/src/plugins/controls/public/control_types/range_slider/range_slider_strings.ts b/src/plugins/controls/public/control_types/range_slider/range_slider_strings.ts deleted file mode 100644 index 53d614fd54a2e3..00000000000000 --- a/src/plugins/controls/public/control_types/range_slider/range_slider_strings.ts +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { i18n } from '@kbn/i18n'; - -export const RangeSliderStrings = { - getDisplayName: () => - i18n.translate('controls.rangeSlider.displayName', { - defaultMessage: 'Range slider', - }), - getDescription: () => - i18n.translate('controls.rangeSlider.description', { - defaultMessage: 'Add a control for selecting a range of field values.', - }), - editor: { - getDataViewTitle: () => - i18n.translate('controls.rangeSlider.editor.dataViewTitle', { - defaultMessage: 'Data view', - }), - getNoDataViewTitle: () => - i18n.translate('controls.rangeSlider.editor.noDataViewTitle', { - defaultMessage: 'Select data view', - }), - getFieldTitle: () => - i18n.translate('controls.rangeSlider.editor.fieldTitle', { - defaultMessage: 'Field', - }), - }, - popover: { - getAllOptionsButtonTitle: () => - i18n.translate('controls.rangeSlider.popover.allOptionsTitle', { - defaultMessage: 'Show all options', - }), - getClearRangeButtonTitle: () => - i18n.translate('controls.rangeSlider.popover.clearRangeTitle', { - defaultMessage: 'Clear range', - }), - getNoDataHelpText: () => - i18n.translate('controls.rangeSlider.popover.noDataHelpText', { - defaultMessage: 'Selected range resulted in no data. No filter was applied.', - }), - getNoAvailableDataHelpText: () => - i18n.translate('controls.rangeSlider.popover.noAvailableDataHelpText', { - defaultMessage: 'There is no data to display. Adjust the time range and filters.', - }), - }, - errors: { - getDataViewNotFoundError: (dataViewId: string) => - i18n.translate('controls.optionsList.errors.dataViewNotFound', { - defaultMessage: 'Could not locate data view: {dataViewId}', - values: { dataViewId }, - }), - getUpperLessThanLowerErrorMessage: () => - i18n.translate('controls.rangeSlider.popover.upperLessThanLowerErrorMessage', { - defaultMessage: 'The upper bound must be greater than or equal to the lower bound.', - }), - }, -}; diff --git a/src/plugins/controls/public/control_types/time_slider/__stories__/time_slider.component.stories.tsx b/src/plugins/controls/public/control_types/time_slider/__stories__/time_slider.component.stories.tsx deleted file mode 100644 index 90ea07dc276bd5..00000000000000 --- a/src/plugins/controls/public/control_types/time_slider/__stories__/time_slider.component.stories.tsx +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ -import React, { FC, useCallback, useState } from 'react'; -import moment from 'moment'; -import { EuiFormControlLayout } from '@elastic/eui'; - -import { TimeSliderProps, TimeSlider } from '../time_slider.component'; - -export default { - title: 'Time Slider', - description: '', -}; - -const TimeSliderWrapper: FC> = (props) => { - const [value, setValue] = useState(props.value); - const onChange = useCallback( - (newValue: [number | null, number | null]) => { - const lowValue = newValue[0]; - const highValue = newValue[1]; - - setValue([lowValue, highValue]); - }, - [setValue] - ); - - return ( -
- - - -
- ); -}; - -const undefinedValue: [null, null] = [null, null]; -const undefinedRange: [undefined, undefined] = [undefined, undefined]; - -export const TimeSliderNoValuesOrRange = () => { - // If range is undefined, that should be inndicate that we are loading the range - return ; -}; - -export const TimeSliderUndefinedRangeNoValue = () => { - // If a range is [undefined, undefined] then it was loaded, but no values were found. - return ; -}; - -export const TimeSliderUndefinedRangeWithValue = () => { - const lastWeek = moment().subtract(7, 'days'); - const now = moment(); - - return ( - - ); -}; - -export const TimeSliderWithRangeAndNoValue = () => { - const lastWeek = moment().subtract(7, 'days'); - const now = moment(); - - return ( - - ); -}; - -export const TimeSliderWithRangeAndLowerValue = () => { - const lastWeek = moment().subtract(7, 'days'); - const now = moment(); - - const threeDays = moment().subtract(3, 'days'); - - return ( - - ); -}; - -export const TimeSliderWithRangeAndUpperValue = () => { - const lastWeek = moment().subtract(7, 'days'); - const now = moment(); - - const threeDays = moment().subtract(3, 'days'); - - return ( - - ); -}; - -export const TimeSliderWithLowRangeOverlap = () => { - const lastWeek = moment().subtract(7, 'days'); - const now = moment(); - - const threeDays = moment().subtract(3, 'days'); - const twoDays = moment().subtract(2, 'days'); - - return ( - - ); -}; - -export const TimeSliderWithLowRangeOverlapAndIgnoredValidation = () => { - const lastWeek = moment().subtract(7, 'days'); - const now = moment(); - - const threeDays = moment().subtract(3, 'days'); - const twoDays = moment().subtract(2, 'days'); - - return ( - - ); -}; - -export const TimeSliderWithRangeLowerThanValue = () => { - const twoWeeksAgo = moment().subtract(14, 'days'); - const lastWeek = moment().subtract(7, 'days'); - - const now = moment(); - const threeDays = moment().subtract(3, 'days'); - - return ( - - ); -}; - -export const TimeSliderWithRangeHigherThanValue = () => { - const twoWeeksAgo = moment().subtract(14, 'days'); - const lastWeek = moment().subtract(7, 'days'); - - const now = moment(); - const threeDays = moment().subtract(3, 'days'); - - return ( - - ); -}; - -export const PartialValueLowerThanRange = () => { - // Selected value is March 8 -> March 9 - // Range is March 11 -> 25 - const eightDaysAgo = moment().subtract(8, 'days'); - - const lastWeek = moment().subtract(7, 'days'); - const today = moment(); - - return ( - - ); -}; - -export const PartialValueHigherThanRange = () => { - // Selected value is March 8 -> March 9 - // Range is March 11 -> 25 - const eightDaysAgo = moment().subtract(8, 'days'); - - const lastWeek = moment().subtract(7, 'days'); - const today = moment(); - - return ( - - ); -}; diff --git a/src/plugins/controls/public/control_types/time_slider/index.ts b/src/plugins/controls/public/control_types/time_slider/index.ts deleted file mode 100644 index 1cd5900164676d..00000000000000 --- a/src/plugins/controls/public/control_types/time_slider/index.ts +++ /dev/null @@ -1,11 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -export { TimesliderEmbeddableFactory } from './time_slider_embeddable_factory'; -export { type TimeSliderControlEmbeddableInput } from '../../../common/control_types/time_slider/types'; -export {} from '../../../common'; diff --git a/src/plugins/controls/public/control_types/time_slider/time_slider.component.scss b/src/plugins/controls/public/control_types/time_slider/time_slider.component.scss deleted file mode 100644 index 3f8a37ec44d370..00000000000000 --- a/src/plugins/controls/public/control_types/time_slider/time_slider.component.scss +++ /dev/null @@ -1,47 +0,0 @@ -.timeSlider__anchorOverride { - display:block; - >div { - height: 100%; - } -} - -.timeSlider__popoverOverride { - width: 100%; - max-width: 100%; - height: 100%; -} - -.timeSlider__panelOverride { - min-width: $euiSizeXXL * 15; -} - -.timeSlider__anchor { - text-decoration: none; - width: 100%; - background-color: $euiFormBackgroundColor; - box-shadow: none; - @include euiFormControlSideBorderRadius($euiFormControlBorderRadius, $side: 'right', $internal: true); - overflow: hidden; - height: 100%; - - &:enabled:focus { - background-color: $euiFormBackgroundColor; - } - - .euiText { - background-color: $euiFormBackgroundColor; - } - - .timeSlider__anchorText { - font-weight: $euiFontWeightBold; - } - - .timeSlider__anchorText--default { - color: $euiColorMediumShade; - } - - .timeSlider__anchorText--invalid { - text-decoration: line-through; - color: $euiColorMediumShade; - } -} \ No newline at end of file diff --git a/src/plugins/controls/public/control_types/time_slider/time_slider.component.tsx b/src/plugins/controls/public/control_types/time_slider/time_slider.component.tsx deleted file mode 100644 index 1bb2f90b44121f..00000000000000 --- a/src/plugins/controls/public/control_types/time_slider/time_slider.component.tsx +++ /dev/null @@ -1,343 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import React, { FC, useState, useMemo, useCallback } from 'react'; -import { isNil } from 'lodash'; -import { - EuiText, - EuiLoadingSpinner, - EuiInputPopover, - EuiPopoverTitle, - EuiSpacer, - EuiFlexItem, - EuiFlexGroup, - EuiToolTip, - EuiButtonIcon, -} from '@elastic/eui'; -import { EuiRangeTick } from '@elastic/eui/src/components/form/range/range_ticks'; -import moment from 'moment-timezone'; -import { calcAutoIntervalNear } from '@kbn/data-plugin/common'; -import { ValidatedDualRange } from '@kbn/kibana-react-plugin/public'; -import { TimeSliderStrings } from './time_slider_strings'; -import './time_slider.component.scss'; - -function getScaledDateFormat(interval: number): string { - if (interval >= moment.duration(1, 'y').asMilliseconds()) { - return 'YYYY'; - } - - if (interval >= moment.duration(1, 'd').asMilliseconds()) { - return 'MMM D'; - } - - if (interval >= moment.duration(6, 'h').asMilliseconds()) { - return 'Do HH'; - } - - if (interval >= moment.duration(1, 'h').asMilliseconds()) { - return 'HH:mm'; - } - - if (interval >= moment.duration(1, 'm').asMilliseconds()) { - return 'HH:mm'; - } - - if (interval >= moment.duration(1, 's').asMilliseconds()) { - return 'mm:ss'; - } - - return 'ss.SSS'; -} - -export function getInterval(min: number, max: number, steps = 6): number { - const duration = max - min; - let interval = calcAutoIntervalNear(steps, duration).asMilliseconds(); - // Sometimes auto interval is not quite right and returns 2X or 3X requested ticks - // Adjust the interval to get closer to the requested number of ticks - const actualSteps = duration / interval; - if (actualSteps > steps * 1.5) { - const factor = Math.round(actualSteps / steps); - interval *= factor; - } else if (actualSteps < 5) { - interval *= 0.5; - } - return interval; -} - -export interface TimeSliderProps { - id: string; - range?: [number | undefined, number | undefined]; - value: [number | null, number | null]; - onChange: (range: [number | null, number | null]) => void; - dateFormat?: string; - timezone?: string; - fieldName: string; - ignoreValidation?: boolean; -} - -const isValidRange = (maybeRange: TimeSliderProps['range']): maybeRange is [number, number] => { - return maybeRange !== undefined && !isNil(maybeRange[0]) && !isNil(maybeRange[1]); -}; - -const unselectedClass = 'timeSlider__anchorText--default'; -const validClass = 'timeSlider__anchorText'; -const invalidClass = 'timeSlider__anchorText--invalid'; - -export const TimeSlider: FC = (props) => { - const defaultProps = { - dateFormat: 'MMM D, YYYY @ HH:mm:ss.SSS', - ignoreValidation: false, - timezone: 'Browser', - ...props, - }; - const { range, value, timezone, dateFormat, fieldName, ignoreValidation } = defaultProps; - const [isPopoverOpen, setIsPopoverOpen] = useState(false); - const togglePopover = useCallback(() => { - setIsPopoverOpen(!isPopoverOpen); - }, [isPopoverOpen, setIsPopoverOpen]); - - const getTimezone = useCallback(() => { - const detectedTimezone = moment.tz.guess(); - - return timezone === 'Browser' ? detectedTimezone : timezone; - }, [timezone]); - - const epochToKbnDateFormat = useCallback( - (epoch: number) => { - const tz = getTimezone(); - return moment.tz(epoch, tz).format(dateFormat); - }, - [dateFormat, getTimezone] - ); - - // If we don't have a range or we have is loading, show the loading state - const hasRange = range !== undefined; - - // We have values if we have a range or value entry for both position - const hasValues = - (value[0] !== null || (hasRange && range[0] !== undefined)) && - (value[1] !== null || (hasRange && range[1] !== undefined)); - - let valueText: JSX.Element | null = null; - if (hasValues) { - let lower = value[0] !== null ? value[0] : range![0]!; - let upper = value[1] !== null ? value[1] : range![1]!; - - if (value[0] !== null && lower > upper) { - upper = lower; - } else if (value[1] !== null && lower > upper) { - lower = upper; - } - - const hasLowerValueInRange = - value[0] !== null && isValidRange(range) && value[0] >= range[0] && value[0] <= range[1]; - // It's out of range if the upper value is above the upper range or below the lower range - const hasUpperValueInRange = - value[1] !== null && isValidRange(range) && value[1] <= range[1] && value[1] >= range[0]; - - let lowClass = unselectedClass; - let highClass = unselectedClass; - if (value[0] !== null && (hasLowerValueInRange || ignoreValidation)) { - lowClass = validClass; - } else if (value[0] !== null) { - lowClass = invalidClass; - } - - if (value[1] !== null && (hasUpperValueInRange || ignoreValidation)) { - highClass = validClass; - } else if (value[1] !== null) { - highClass = invalidClass; - } - - // if no value then anchorText default - // if hasLowerValueInRange || skipValidation then anchor text - // else strikethrough - - valueText = ( - - {epochToKbnDateFormat(lower)} -   →   - {epochToKbnDateFormat(upper)} - - ); - } - - const button = ( - - ); - - return ( - setIsPopoverOpen(false)} - panelPaddingSize="s" - anchorPosition="downCenter" - disableFocusTrap - attachToAnchor={false} - > - {isValidRange(range) ? ( - - ) : ( - - )} - - ); -}; - -const TimeSliderComponentPopoverNoDocuments: FC = () => { - return {TimeSliderStrings.noDocumentsPopover.getLabel()}; -}; - -export const TimeSliderComponentPopover: FC< - TimeSliderProps & { - range: [number, number]; - getTimezone: () => string; - epochToKbnDateFormat: (epoch: number) => string; - } -> = ({ range, value, onChange, getTimezone, epochToKbnDateFormat, fieldName }) => { - const [lowerBound, upperBound] = range; - let [lowerValue, upperValue] = value; - - if (lowerValue === null) { - lowerValue = lowerBound; - } - - if (upperValue === null) { - upperValue = upperBound; - } - - const fullRange = useMemo( - () => [Math.min(lowerValue!, lowerBound), Math.max(upperValue!, upperBound)], - [lowerValue, lowerBound, upperValue, upperBound] - ); - - const getTicks = useCallback( - (min: number, max: number, interval: number): EuiRangeTick[] => { - const format = getScaledDateFormat(interval); - const tz = getTimezone(); - - let tick = Math.ceil(min / interval) * interval; - const ticks: EuiRangeTick[] = []; - while (tick < max) { - ticks.push({ - value: tick, - label: moment.tz(tick, tz).format(format), - }); - tick += interval; - } - - return ticks; - }, - [getTimezone] - ); - - const ticks = useMemo(() => { - const interval = getInterval(fullRange[0], fullRange[1]); - return getTicks(fullRange[0], fullRange[1], interval); - }, [fullRange, getTicks]); - - const onChangeHandler = useCallback( - ([_min, _max]: [number | string, number | string]) => { - // If a value is undefined and the number that is given here matches the range bounds - // then we will ignore it, becuase they probably didn't actually select that value - const report: [number | null, number | null] = [null, null]; - - let min: number; - let max: number; - if (typeof _min === 'string') { - min = parseFloat(_min); - min = isNaN(min) ? range[0] : min; - } else { - min = _min; - } - - if (typeof _max === 'string') { - max = parseFloat(_max); - max = isNaN(max) ? range[0] : max; - } else { - max = _max; - } - - if (value[0] !== null || min !== range[0]) { - report[0] = min; - } - if (value[1] !== null || max !== range[1]) { - report[1] = max; - } - - onChange(report); - }, - [onChange, value, range] - ); - - const levels = [{ min: range[0], max: range[1], color: 'success' }]; - - return ( - <> - {fieldName} - - {epochToKbnDateFormat(lowerValue)} - {epochToKbnDateFormat(upperValue)} - - - - - - - - - onChange([null, null])} - aria-label={TimeSliderStrings.resetButton.getLabel()} - data-test-subj="timeSlider__clearRangeButton" - /> - - - - - - ); -}; diff --git a/src/plugins/controls/public/control_types/time_slider/time_slider.tsx b/src/plugins/controls/public/control_types/time_slider/time_slider.tsx deleted file mode 100644 index 0b519406ccf8d6..00000000000000 --- a/src/plugins/controls/public/control_types/time_slider/time_slider.tsx +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import React, { FC, useCallback, useMemo } from 'react'; -import { BehaviorSubject } from 'rxjs'; -import { debounce } from 'lodash'; -import { useReduxEmbeddableContext } from '@kbn/presentation-util-plugin/public'; - -import { timeSliderReducers } from './time_slider_reducers'; -import { TimeSlider as Component } from './time_slider.component'; -import { TimeSliderReduxState, TimeSliderSubjectState } from './types'; - -interface TimeSliderProps { - componentStateSubject: BehaviorSubject; - dateFormat: string; - timezone: string; - fieldName: string; - ignoreValidation: boolean; -} - -export const TimeSlider: FC = ({ - componentStateSubject, - dateFormat, - timezone, - fieldName, - ignoreValidation, -}) => { - const { - useEmbeddableDispatch, - useEmbeddableSelector: select, - actions: { selectRange }, - } = useReduxEmbeddableContext(); - const dispatch = useEmbeddableDispatch(); - - const availableRange = select((state) => state.componentState.range); - const value = select((state) => state.explicitInput.value); - const id = select((state) => state.explicitInput.id); - - const { min, max } = availableRange - ? availableRange - : ({} as { - min?: number; - max?: number; - }); - - const dispatchChange = useCallback( - (range: [number | null, number | null]) => { - dispatch(selectRange(range)); - }, - [dispatch, selectRange] - ); - - const debouncedDispatchChange = useMemo(() => debounce(dispatchChange, 500), [dispatchChange]); - - const onChangeComplete = useCallback( - (range: [number | null, number | null]) => { - debouncedDispatchChange(range); - }, - [debouncedDispatchChange] - ); - - return ( - - ); -}; diff --git a/src/plugins/controls/public/control_types/time_slider/time_slider_embeddable.test.ts b/src/plugins/controls/public/control_types/time_slider/time_slider_embeddable.test.ts deleted file mode 100644 index 4db5277a0e2f9d..00000000000000 --- a/src/plugins/controls/public/control_types/time_slider/time_slider_embeddable.test.ts +++ /dev/null @@ -1,300 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { of } from 'rxjs'; -import { delay, map } from 'rxjs/operators'; -import { TimeSliderControlEmbeddableInput } from '.'; -import { TimeSliderControlEmbeddable } from './time_slider_embeddable'; -import { stubLogstashDataView } from '@kbn/data-views-plugin/common/data_view.stub'; -import { pluginServices } from '../../services'; -import { TestScheduler } from 'rxjs/testing'; -import { buildRangeFilter } from '@kbn/es-query'; -import { ReduxEmbeddablePackage } from '@kbn/presentation-util-plugin/public'; - -const buildFilter = (range: [number | null, number | null]) => { - const filterPieces: Record = {}; - if (range[0] !== null) { - filterPieces.gte = range[0]; - } - if (range[1] !== null) { - filterPieces.lte = range[1]; - } - - const filter = buildRangeFilter( - stubLogstashDataView.getFieldByName('bytes')!, - filterPieces, - stubLogstashDataView - ); - filter.meta.key = 'bytes'; - - return filter; -}; - -const rangeMin = 20; -const rangeMax = 30; -const range = { min: rangeMin, max: rangeMax }; - -const lowerValue: [number, number] = [15, 25]; -const upperValue: [number, number] = [25, 35]; -const partialLowValue: [number, null] = [25, null]; -const partialHighValue: [null, number] = [null, 25]; -const withinRangeValue: [number, number] = [21, 29]; -const outOfRangeValue: [number, number] = [31, 40]; - -const rangeFilter = buildFilter([rangeMin, rangeMax]); -const lowerValueFilter = buildFilter(lowerValue); -const lowerValuePartialFilter = buildFilter([20, 25]); -const upperValueFilter = buildFilter(upperValue); -const upperValuePartialFilter = buildFilter([25, 30]); - -const partialLowValueFilter = buildFilter(partialLowValue); -const partialHighValueFilter = buildFilter(partialHighValue); -const withinRangeValueFilter = buildFilter(withinRangeValue); -const outOfRangeValueFilter = buildFilter(outOfRangeValue); - -const baseInput: TimeSliderControlEmbeddableInput = { - id: 'id', - fieldName: 'bytes', - dataViewId: stubLogstashDataView.id!, -}; - -const mockReduxEmbeddablePackage = { - createTools: () => {}, -} as unknown as ReduxEmbeddablePackage; - -describe('Time Slider Control Embeddable', () => { - const services = pluginServices.getServices(); - const fetchRange = jest.spyOn(services.data, 'fetchFieldRange'); - const getDataView = jest.spyOn(services.data, 'getDataView'); - const fetchRange$ = jest.spyOn(services.data, 'fetchFieldRange$'); - const getDataView$ = jest.spyOn(services.data, 'getDataView$'); - - beforeEach(() => { - jest.resetAllMocks(); - - fetchRange.mockResolvedValue(range); - fetchRange$.mockReturnValue(of(range).pipe(delay(100))); - getDataView.mockResolvedValue(stubLogstashDataView); - getDataView$.mockReturnValue(of(stubLogstashDataView)); - }); - - describe('outputting filters', () => { - let testScheduler: TestScheduler; - beforeEach(() => { - testScheduler = new TestScheduler((actual, expected) => { - expect(actual).toEqual(expected); - }); - }); - - const testFilterOutput = ( - input: any, - expectedFilterAfterRangeFetch: any, - mockRange: { min?: number; max?: number } = range - ) => { - testScheduler.run(({ expectObservable, cold }) => { - fetchRange$.mockReturnValue(cold('--b', { b: mockRange })); - const expectedMarbles = 'a-b'; - const expectedValues = { - a: undefined, - b: expectedFilterAfterRangeFetch ? [expectedFilterAfterRangeFetch] : undefined, - }; - - const embeddable = new TimeSliderControlEmbeddable(mockReduxEmbeddablePackage, input, {}); - const source$ = embeddable.getOutput$().pipe(map((o) => o.filters)); - - expectObservable(source$).toBe(expectedMarbles, expectedValues); - }); - }; - - it('outputs no filter when no value is given', () => { - testFilterOutput(baseInput, undefined); - }); - - it('outputs the value filter after the range is fetched', () => { - testFilterOutput({ ...baseInput, value: withinRangeValue }, withinRangeValueFilter); - }); - - it('outputs a partial filter for a low partial value', () => { - testFilterOutput({ ...baseInput, value: partialLowValue }, partialLowValueFilter); - }); - - it('outputs a partial filter for a high partial value', () => { - testFilterOutput({ ...baseInput, value: partialHighValue }, partialHighValueFilter); - }); - - describe('with validation', () => { - it('outputs a partial value filter if value is below range', () => { - testFilterOutput({ ...baseInput, value: lowerValue }, lowerValuePartialFilter); - }); - - it('outputs a partial value filter if value is above range', () => { - testFilterOutput({ ...baseInput, value: upperValue }, upperValuePartialFilter); - }); - - it('outputs range filter value if value is completely out of range', () => { - testFilterOutput({ ...baseInput, value: outOfRangeValue }, rangeFilter); - }); - - it('outputs no filter when no range available', () => { - testFilterOutput({ ...baseInput, value: withinRangeValue }, undefined, {}); - }); - }); - - describe('with validation off', () => { - it('outputs the lower value filter', () => { - testFilterOutput( - { ...baseInput, ignoreParentSettings: { ignoreValidations: true }, value: lowerValue }, - lowerValueFilter - ); - }); - - it('outputs the uppwer value filter', () => { - testFilterOutput( - { ...baseInput, ignoreParentSettings: { ignoreValidations: true }, value: upperValue }, - upperValueFilter - ); - }); - - it('outputs the out of range filter', () => { - testFilterOutput( - { - ...baseInput, - ignoreParentSettings: { ignoreValidations: true }, - value: outOfRangeValue, - }, - outOfRangeValueFilter - ); - }); - - it('outputs the value filter when no range found', () => { - testFilterOutput( - { - ...baseInput, - ignoreParentSettings: { ignoreValidations: true }, - value: withinRangeValue, - }, - withinRangeValueFilter, - { min: undefined, max: undefined } - ); - }); - }); - }); - - describe('fetching range', () => { - it('fetches range on init', () => { - const testScheduler = new TestScheduler((actual, expected) => { - expect(actual).toEqual(expected); - }); - - testScheduler.run(({ cold, expectObservable }) => { - const mockRange = { min: 1, max: 2 }; - fetchRange$.mockReturnValue(cold('--b', { b: mockRange })); - - const expectedMarbles = 'a-b'; - const expectedValues = { - a: undefined, - b: mockRange, - }; - - const embeddable = new TimeSliderControlEmbeddable( - mockReduxEmbeddablePackage, - baseInput, - {} - ); - const source$ = embeddable.getComponentState$().pipe(map((state) => state.range)); - - const { fieldName, ...inputForFetch } = baseInput; - - expectObservable(source$).toBe(expectedMarbles, expectedValues); - expect(fetchRange$).toBeCalledWith(stubLogstashDataView, fieldName, { - ...inputForFetch, - filters: undefined, - query: undefined, - timeRange: undefined, - viewMode: 'edit', - }); - }); - }); - - it('fetches range on input change', () => { - const testScheduler = new TestScheduler((actual, expected) => { - expect(actual).toEqual(expected); - }); - - testScheduler.run(({ cold, expectObservable, flush }) => { - const mockRange = { min: 1, max: 2 }; - fetchRange$.mockReturnValue(cold('a', { a: mockRange })); - - const embeddable = new TimeSliderControlEmbeddable( - mockReduxEmbeddablePackage, - baseInput, - {} - ); - const updatedInput = { ...baseInput, fieldName: '@timestamp' }; - - embeddable.updateInput(updatedInput); - - expect(fetchRange$).toBeCalledTimes(2); - expect(fetchRange$.mock.calls[1][1]).toBe(updatedInput.fieldName); - }); - }); - - it('passes input to fetch range to build the query', () => { - const testScheduler = new TestScheduler((actual, expected) => { - expect(actual).toEqual(expected); - }); - - testScheduler.run(({ cold, expectObservable, flush }) => { - const mockRange = { min: 1, max: 2 }; - fetchRange$.mockReturnValue(cold('a', { a: mockRange })); - - const input = { - ...baseInput, - query: {} as any, - filters: {} as any, - timeRange: {} as any, - }; - - new TimeSliderControlEmbeddable(mockReduxEmbeddablePackage, input, {}); - - expect(fetchRange$).toBeCalledTimes(1); - const args = fetchRange$.mock.calls[0][2]; - expect(args.query).toBe(input.query); - expect(args.filters).toBe(input.filters); - expect(args.timeRange).toBe(input.timeRange); - }); - }); - - it('does not pass ignored parent settings', () => { - const testScheduler = new TestScheduler((actual, expected) => { - expect(actual).toEqual(expected); - }); - - testScheduler.run(({ cold, expectObservable, flush }) => { - const mockRange = { min: 1, max: 2 }; - fetchRange$.mockReturnValue(cold('a', { a: mockRange })); - - const input = { - ...baseInput, - query: '' as any, - filters: {} as any, - timeRange: {} as any, - ignoreParentSettings: { ignoreFilters: true, ignoreQuery: true, ignoreTimerange: true }, - }; - - new TimeSliderControlEmbeddable(mockReduxEmbeddablePackage, input, {}); - - expect(fetchRange$).toBeCalledTimes(1); - const args = fetchRange$.mock.calls[0][2]; - expect(args.query).not.toBe(input.query); - expect(args.filters).not.toBe(input.filters); - expect(args.timeRange).not.toBe(input.timeRange); - }); - }); - }); -}); diff --git a/src/plugins/controls/public/control_types/time_slider/time_slider_embeddable.tsx b/src/plugins/controls/public/control_types/time_slider/time_slider_embeddable.tsx deleted file mode 100644 index a4098a72dfe1ab..00000000000000 --- a/src/plugins/controls/public/control_types/time_slider/time_slider_embeddable.tsx +++ /dev/null @@ -1,334 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { compareFilters, buildRangeFilter, RangeFilterParams } from '@kbn/es-query'; -import React from 'react'; -import ReactDOM from 'react-dom'; -import { isEqual } from 'lodash'; -import deepEqual from 'fast-deep-equal'; -import { merge, Subscription, BehaviorSubject, Observable } from 'rxjs'; -import { map, distinctUntilChanged, skip, take, mergeMap } from 'rxjs/operators'; - -import { Embeddable, IContainer } from '@kbn/embeddable-plugin/public'; -import { ReduxEmbeddableTools, ReduxEmbeddablePackage } from '@kbn/presentation-util-plugin/public'; -import { DataView } from '@kbn/data-views-plugin/public'; - -import { TimeSliderControlEmbeddableInput } from '../../../common/control_types/time_slider/types'; -import { TIME_SLIDER_CONTROL } from '../..'; -import { ControlsSettingsService } from '../../services/settings'; -import { ControlsDataService } from '../../services/data'; -import { ControlOutput } from '../..'; -import { pluginServices } from '../../services'; - -import { TimeSlider as TimeSliderComponent } from './time_slider'; -import { timeSliderReducers } from './time_slider_reducers'; -import { TimeSliderReduxState, TimeSliderSubjectState } from './types'; - -const diffDataFetchProps = (current?: any, last?: any) => { - if (!current || !last) return false; - const { filters: currentFilters, ...currentWithoutFilters } = current; - const { filters: lastFilters, ...lastWithoutFilters } = last; - if (!deepEqual(currentWithoutFilters, lastWithoutFilters)) return false; - if (!compareFilters(lastFilters ?? [], currentFilters ?? [])) return false; - return true; -}; - -export class TimeSliderControlEmbeddable extends Embeddable< - TimeSliderControlEmbeddableInput, - ControlOutput -> { - public readonly type = TIME_SLIDER_CONTROL; - public deferEmbeddableLoad = true; - - private subscriptions: Subscription = new Subscription(); - private node?: HTMLElement; - - // Internal data fetching state for this input control. - private dataView?: DataView; - - private componentState: TimeSliderSubjectState; - private componentStateSubject$ = new BehaviorSubject({ - range: undefined, - loading: false, - }); - - // Internal state subject will let us batch updates to the externally accessible state subject - private internalComponentStateSubject$ = new BehaviorSubject({ - range: undefined, - loading: false, - }); - - private internalOutput: ControlOutput; - - private fetchRange$: ControlsDataService['fetchFieldRange$']; - private getDataView$: ControlsDataService['getDataView$']; - private getDateFormat: ControlsSettingsService['getDateFormat']; - private getTimezone: ControlsSettingsService['getTimezone']; - - private reduxEmbeddableTools: ReduxEmbeddableTools< - TimeSliderReduxState, - typeof timeSliderReducers - >; - - constructor( - reduxEmbeddablePackage: ReduxEmbeddablePackage, - input: TimeSliderControlEmbeddableInput, - output: ControlOutput, - parent?: IContainer - ) { - super(input, output, parent); // get filters for initial output... - - const { - data: { fetchFieldRange$, getDataView$ }, - settings: { getDateFormat, getTimezone }, - } = pluginServices.getServices(); - this.fetchRange$ = fetchFieldRange$; - this.getDataView$ = getDataView$; - this.getDateFormat = getDateFormat; - this.getTimezone = getTimezone; - - this.componentState = { loading: true }; - this.updateComponentState(this.componentState, true); - - this.internalOutput = {}; - - // build redux embeddable tools - this.reduxEmbeddableTools = reduxEmbeddablePackage.createTools< - TimeSliderReduxState, - typeof timeSliderReducers - >({ - embeddable: this, - reducers: timeSliderReducers, - }); - - this.initialize(); - } - - private initialize() { - // If value is undefined, then we can be finished with initialization because we're not going to output a filter - if (this.getInput().value === undefined) { - this.setInitializationFinished(); - } - - this.setupSubscriptions(); - } - - private setupSubscriptions() { - // We need to fetch data when any of these values change - const dataFetchPipe = this.getInput$().pipe( - map((newInput) => ({ - lastReloadRequestTime: newInput.lastReloadRequestTime, - dataViewId: newInput.dataViewId, - fieldName: newInput.fieldName, - timeRange: newInput.timeRange, - filters: newInput.filters, - query: newInput.query, - })), - distinctUntilChanged(diffDataFetchProps) - ); - - // When data fetch pipe emits, we start the fetch - this.subscriptions.add(dataFetchPipe.subscribe(this.fetchAvailableTimerange)); - - const availableRangePipe = this.internalComponentStateSubject$.pipe( - map((state) => (state.range ? { min: state.range.min, max: state.range.max } : {})), - distinctUntilChanged((a, b) => isEqual(a, b)) - ); - - this.subscriptions.add( - merge( - this.getInput$().pipe( - skip(1), // Skip the first input value - distinctUntilChanged((a, b) => isEqual(a.value, b.value)) - ), - availableRangePipe.pipe(skip(1)) - ).subscribe(() => { - this.setInitializationFinished(); - this.buildFilter(); - - this.componentStateSubject$.next(this.componentState); - }) - ); - } - - private buildFilter = () => { - const { fieldName, value, ignoreParentSettings } = this.getInput(); - - const min = value ? value[0] : null; - const max = value ? value[1] : null; - const hasRange = - this.componentState.range?.max !== undefined && this.componentState.range?.min !== undefined; - - this.getCurrentDataView$().subscribe((dataView) => { - const range: RangeFilterParams = {}; - let filterMin: number | undefined; - let filterMax: number | undefined; - const field = dataView.getFieldByName(fieldName); - - if (ignoreParentSettings?.ignoreValidations) { - if (min !== null) { - range.gte = min; - } - - if (max !== null) { - range.lte = max; - } - } else { - // If we have a value or a range use the min/max of those, otherwise undefined - if (min !== null && this.componentState.range!.min !== undefined) { - filterMin = Math.max(min || 0, this.componentState.range!.min || 0); - } - - if (max !== null && this.componentState.range!.max) { - filterMax = Math.min( - max || Number.MAX_SAFE_INTEGER, - this.componentState.range!.max || Number.MAX_SAFE_INTEGER - ); - } - - // Last check, if the value is completely outside the range then we will just default to the range - if ( - hasRange && - ((min !== null && min > this.componentState.range!.max!) || - (max !== null && max < this.componentState.range!.min!)) - ) { - filterMin = this.componentState.range!.min; - filterMax = this.componentState.range!.max; - } - - if (hasRange && filterMin !== undefined) { - range.gte = filterMin; - } - if (hasRange && filterMax !== undefined) { - range.lte = filterMax; - } - } - - if (range.lte !== undefined || range.gte !== undefined) { - const rangeFilter = buildRangeFilter(field!, range, dataView); - rangeFilter.meta.key = field?.name; - - this.updateInternalOutput({ filters: [rangeFilter] }, true); - this.updateComponentState({ loading: false }); - } else { - this.updateInternalOutput({ filters: undefined, dataViewId: dataView.id }, true); - this.updateComponentState({ loading: false }); - } - }); - }; - - private updateComponentState(changes: Partial, publish = false) { - this.componentState = { - ...this.componentState, - ...changes, - }; - - this.internalComponentStateSubject$.next(this.componentState); - - if (publish) { - this.componentStateSubject$.next(this.componentState); - } - } - - private updateInternalOutput(changes: Partial, publish = false) { - this.internalOutput = { - ...this.internalOutput, - ...changes, - }; - - if (publish) { - this.updateOutput(this.internalOutput); - } - } - - private getCurrentDataView$ = () => { - const { dataViewId } = this.getInput(); - if (this.dataView && this.dataView.id === dataViewId) - return new Observable((subscriber) => { - subscriber.next(this.dataView); - subscriber.complete(); - }); - - return this.getDataView$(dataViewId); - }; - - private fetchAvailableTimerange = () => { - this.updateComponentState({ loading: true }, true); - this.updateInternalOutput({ loading: true }, true); - - const { fieldName, ignoreParentSettings, query, filters, timeRange, ...input } = - this.getInput(); - - const inputForFetch = { - ...input, - ...(ignoreParentSettings?.ignoreQuery ? {} : { query }), - ...(ignoreParentSettings?.ignoreFilters ? {} : { filters }), - ...(ignoreParentSettings?.ignoreTimerange ? {} : { timeRange }), - }; - - try { - this.getCurrentDataView$() - .pipe( - mergeMap((dataView) => this.fetchRange$(dataView, fieldName, inputForFetch)), - take(1) - ) - .subscribe(({ min, max }) => { - this.updateInternalOutput({ loading: false }); - this.updateComponentState({ - range: { - min: min === null ? undefined : min, - max: max === null ? undefined : max, - }, - loading: false, - }); - }); - } catch (e) { - this.updateComponentState({ loading: false }, true); - this.updateInternalOutput({ loading: false }, true); - } - }; - - public getComponentState$ = () => { - return this.componentStateSubject$; - }; - - public destroy = () => { - super.destroy(); - this.subscriptions.unsubscribe(); - }; - - public reload = () => { - this.fetchAvailableTimerange(); - }; - - public render = (node: HTMLElement) => { - if (this.node) { - ReactDOM.unmountComponentAtNode(this.node); - } - this.node = node; - - const { Wrapper: TimeSliderControlReduxWrapper } = this.reduxEmbeddableTools; - - ReactDOM.render( - - - , - node - ); - }; -} diff --git a/src/plugins/controls/public/control_types/time_slider/time_slider_embeddable_factory.tsx b/src/plugins/controls/public/control_types/time_slider/time_slider_embeddable_factory.tsx deleted file mode 100644 index 51048489ccae9b..00000000000000 --- a/src/plugins/controls/public/control_types/time_slider/time_slider_embeddable_factory.tsx +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import deepEqual from 'fast-deep-equal'; - -import { lazyLoadReduxEmbeddablePackage } from '@kbn/presentation-util-plugin/public'; -import { EmbeddableFactoryDefinition, IContainer } from '@kbn/embeddable-plugin/public'; - -import { TIME_SLIDER_CONTROL } from '../..'; -import { ControlEmbeddable, DataControlField, IEditableControlFactory } from '../../types'; -import { - createOptionsListExtract, - createOptionsListInject, -} from '../../../common/options_list/options_list_persistable_state'; -import { TimeSliderControlEmbeddableInput } from '../../../common/control_types/time_slider/types'; -import { TimeSliderStrings } from './time_slider_strings'; - -export class TimesliderEmbeddableFactory - implements EmbeddableFactoryDefinition, IEditableControlFactory -{ - public type = TIME_SLIDER_CONTROL; - public canCreateNew = () => false; - - constructor() {} - - public async create(initialInput: TimeSliderControlEmbeddableInput, parent?: IContainer) { - const reduxEmbeddablePackage = await lazyLoadReduxEmbeddablePackage(); - const { TimeSliderControlEmbeddable } = await import('./time_slider_embeddable'); - - return Promise.resolve( - new TimeSliderControlEmbeddable(reduxEmbeddablePackage, initialInput, {}, parent) - ); - } - - public presaveTransformFunction = ( - newInput: Partial, - embeddable?: ControlEmbeddable - ) => { - if ( - embeddable && - ((newInput.fieldName && !deepEqual(newInput.fieldName, embeddable.getInput().fieldName)) || - (newInput.dataViewId && !deepEqual(newInput.dataViewId, embeddable.getInput().dataViewId))) - ) { - // if the field name or data view id has changed in this editing session, selected options are invalid, so reset them. - newInput.value = undefined; - } - return newInput; - }; - - public isFieldCompatible = (dataControlField: DataControlField) => { - if (dataControlField.field.type === 'date') { - dataControlField.compatibleControlTypes.push(this.type); - } - }; - - public isEditable = () => Promise.resolve(false); - - public getDisplayName = () => TimeSliderStrings.getDisplayName(); - public getIconType = () => 'clock'; - public getDescription = () => TimeSliderStrings.getDescription(); - - public inject = createOptionsListInject(); - public extract = createOptionsListExtract(); -} diff --git a/src/plugins/controls/public/control_types/time_slider/time_slider_reducers.ts b/src/plugins/controls/public/control_types/time_slider/time_slider_reducers.ts deleted file mode 100644 index 95b8d87dc902e5..00000000000000 --- a/src/plugins/controls/public/control_types/time_slider/time_slider_reducers.ts +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { PayloadAction } from '@reduxjs/toolkit'; -import { WritableDraft } from 'immer/dist/types/types-external'; -import { TimeSliderReduxState } from './types'; - -export const timeSliderReducers = { - selectRange: ( - state: WritableDraft, - action: PayloadAction<[number | null, number | null]> - ) => { - state.explicitInput.value = action.payload; - }, -}; diff --git a/src/plugins/controls/public/control_types/time_slider/time_slider_strings.ts b/src/plugins/controls/public/control_types/time_slider/time_slider_strings.ts deleted file mode 100644 index 2c61d7d43a7976..00000000000000 --- a/src/plugins/controls/public/control_types/time_slider/time_slider_strings.ts +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { i18n } from '@kbn/i18n'; - -export const TimeSliderStrings = { - getDisplayName: () => - i18n.translate('controls.timeSlider.displayName', { - defaultMessage: 'Time slider', - }), - getDescription: () => - i18n.translate('controls.timeSlider.description', { - defaultMessage: 'Add a slider for selecting a time range', - }), - editor: { - getDataViewTitle: () => - i18n.translate('controls.timeSlider.editor.dataViewTitle', { - defaultMessage: 'Data view', - }), - getNoDataViewTitle: () => - i18n.translate('controls.timeSlider.editor.noDataViewTitle', { - defaultMessage: 'Select data view', - }), - getFieldTitle: () => - i18n.translate('controls.timeSlider.editor.fieldTitle', { - defaultMessage: 'Field', - }), - }, - resetButton: { - getLabel: () => - i18n.translate('controls.timeSlider.resetButton.label', { - defaultMessage: 'Reset selections', - }), - }, - noDocumentsPopover: { - getLabel: () => - i18n.translate('controls.timeSlider.noDocuments.label', { - defaultMessage: 'There were no documents found. Range selection unavailable.', - }), - }, -}; diff --git a/src/plugins/controls/public/control_types/time_slider/types.ts b/src/plugins/controls/public/control_types/time_slider/types.ts deleted file mode 100644 index fc147dc3ba9596..00000000000000 --- a/src/plugins/controls/public/control_types/time_slider/types.ts +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { ReduxEmbeddableState } from '@kbn/presentation-util-plugin/public'; - -import { ControlOutput } from '../../types'; -import { TimeSliderControlEmbeddableInput } from '../../../common/control_types/time_slider/types'; - -export * from '../../../common/control_types/time_slider/types'; - -// Component state is only used by public components. -export interface TimeSliderSubjectState { - range?: { - min?: number; - max?: number; - }; - loading: boolean; -} - -// public only - redux embeddable state type -export type TimeSliderReduxState = ReduxEmbeddableState< - TimeSliderControlEmbeddableInput, - ControlOutput, - TimeSliderSubjectState ->; diff --git a/src/plugins/controls/public/index.ts b/src/plugins/controls/public/index.ts index a3c54a73b07c14..ecf430f6cc9277 100644 --- a/src/plugins/controls/public/index.ts +++ b/src/plugins/controls/public/index.ts @@ -24,12 +24,7 @@ export type { ControlInput, } from '../common/types'; -export { - CONTROL_GROUP_TYPE, - OPTIONS_LIST_CONTROL, - RANGE_SLIDER_CONTROL, - TIME_SLIDER_CONTROL, -} from '../common'; +export { CONTROL_GROUP_TYPE, OPTIONS_LIST_CONTROL, RANGE_SLIDER_CONTROL } from '../common'; export { ControlGroupContainer, @@ -48,7 +43,7 @@ export { RangeSliderEmbeddableFactory, RangeSliderEmbeddable, type RangeSliderEmbeddableInput, -} from './control_types'; +} from './range_slider'; export { LazyControlsCallout, type CalloutProps } from './controls_callout'; diff --git a/src/plugins/controls/public/plugin.ts b/src/plugins/controls/public/plugin.ts index 13fc4d977c9f6a..01375b174a9349 100644 --- a/src/plugins/controls/public/plugin.ts +++ b/src/plugins/controls/public/plugin.ts @@ -8,7 +8,17 @@ import { CoreSetup, CoreStart, Plugin } from '@kbn/core/public'; import { EmbeddableFactory } from '@kbn/embeddable-plugin/public'; + +import { + ControlGroupContainerFactory, + CONTROL_GROUP_TYPE, + OPTIONS_LIST_CONTROL, + RANGE_SLIDER_CONTROL, +} from '.'; +import { OptionsListEmbeddableFactory, OptionsListEmbeddableInput } from './options_list'; +import { RangeSliderEmbeddableFactory, RangeSliderEmbeddableInput } from './range_slider'; import { pluginServices } from './services'; +import { controlsService } from './services/kibana/controls'; import { ControlsPluginSetup, ControlsPluginStart, @@ -17,25 +27,6 @@ import { IEditableControlFactory, ControlInput, } from './types'; -import { OptionsListEmbeddableFactory, OptionsListEmbeddableInput } from './options_list'; -import { - RangeSliderEmbeddableFactory, - RangeSliderEmbeddableInput, -} from './control_types/range_slider'; -import { - ControlGroupContainerFactory, - CONTROL_GROUP_TYPE, - OPTIONS_LIST_CONTROL, - RANGE_SLIDER_CONTROL, - // TIME_SLIDER_CONTROL, -} from '.'; -/* -import { - TimesliderEmbeddableFactory, - TimeSliderControlEmbeddableInput, -} from './control_types/time_slider'; -*/ -import { controlsService } from './services/kibana/controls'; export class ControlsPlugin implements @@ -102,22 +93,6 @@ export class ControlsPlugin rangeSliderFactory ); registerControlType(rangeSliderFactory); - - // Time Slider Control Factory Setup - /* Temporary disabling Time Slider - const timeSliderFactoryDef = new TimesliderEmbeddableFactory(); - const timeSliderFactory = embeddable.registerEmbeddableFactory( - TIME_SLIDER_CONTROL, - timeSliderFactoryDef - )(); - this.transferEditorFunctions( - timeSliderFactoryDef, - timeSliderFactory - ); - - - registerControlType(timeSliderFactory); - */ }); return { diff --git a/src/plugins/controls/public/control_types/range_slider/range_slider.scss b/src/plugins/controls/public/range_slider/components/range_slider.scss similarity index 100% rename from src/plugins/controls/public/control_types/range_slider/range_slider.scss rename to src/plugins/controls/public/range_slider/components/range_slider.scss diff --git a/src/plugins/controls/public/range_slider/components/range_slider_control.tsx b/src/plugins/controls/public/range_slider/components/range_slider_control.tsx new file mode 100644 index 00000000000000..8a88ba65609e44 --- /dev/null +++ b/src/plugins/controls/public/range_slider/components/range_slider_control.tsx @@ -0,0 +1,155 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import React, { FC, useState, useRef } from 'react'; + +import { + EuiFieldNumber, + EuiText, + EuiInputPopover, + EuiLoadingSpinner, + EuiFlexGroup, + EuiFlexItem, + EuiDualRange, +} from '@elastic/eui'; +import { useReduxEmbeddableContext } from '@kbn/presentation-util-plugin/public'; + +import { rangeSliderReducers } from '../range_slider_reducers'; +import { RangeSliderReduxState } from '../types'; +import { RangeSliderPopover } from './range_slider_popover'; + +import './range_slider.scss'; + +const INVALID_CLASS = 'rangeSliderAnchor__fieldNumber--invalid'; + +export const RangeSliderControl: FC = () => { + const rangeRef = useRef(null); + const [isPopoverOpen, setIsPopoverOpen] = useState(false); + + // Controls Services Context + const { + useEmbeddableDispatch, + useEmbeddableSelector: select, + actions: { setSelectedRange }, + } = useReduxEmbeddableContext(); + const dispatch = useEmbeddableDispatch(); + + // Select current state from Redux using multiple selectors to avoid rerenders. + const min = select((state) => state.componentState.min); + const max = select((state) => state.componentState.max); + const isInvalid = select((state) => state.componentState.isInvalid); + const id = select((state) => state.explicitInput.id); + const value = select((state) => state.explicitInput.value) ?? ['', '']; + const isLoading = select((state) => state.output.loading); + + const hasAvailableRange = min !== '' && max !== ''; + + const hasLowerBoundSelection = value[0] !== ''; + const hasUpperBoundSelection = value[1] !== ''; + + const lowerBoundValue = parseFloat(value[0]); + const upperBoundValue = parseFloat(value[1]); + const minValue = parseFloat(min); + const maxValue = parseFloat(max); + + // EuiDualRange can only handle integers as min/max + const roundedMin = hasAvailableRange ? Math.floor(minValue) : minValue; + const roundedMax = hasAvailableRange ? Math.ceil(maxValue) : maxValue; + + const button = ( + + ); + + return ( + setIsPopoverOpen(false)} + anchorPosition="downCenter" + attachToAnchor={false} + disableFocusTrap + onPanelResize={() => { + if (rangeRef?.current) { + rangeRef.current.onResize(); + } + }} + > + + + ); +}; diff --git a/src/plugins/controls/public/control_types/range_slider/range_slider_popover.tsx b/src/plugins/controls/public/range_slider/components/range_slider_popover.tsx similarity index 52% rename from src/plugins/controls/public/control_types/range_slider/range_slider_popover.tsx rename to src/plugins/controls/public/range_slider/components/range_slider_popover.tsx index 4e674e752edaa0..c14467fee33c84 100644 --- a/src/plugins/controls/public/control_types/range_slider/range_slider_popover.tsx +++ b/src/plugins/controls/public/range_slider/components/range_slider_popover.tsx @@ -6,90 +6,56 @@ * Side Public License, v 1. */ +import React, { FC, useEffect, useRef, useState } from 'react'; +import useMount from 'react-use/lib/useMount'; + import { - EuiFieldNumber, EuiPopoverTitle, - EuiText, - EuiInputPopover, - EuiButtonIcon, - EuiToolTip, - EuiLoadingSpinner, EuiFlexGroup, EuiFlexItem, EuiDualRange, + EuiText, + EuiToolTip, + EuiButtonIcon, } from '@elastic/eui'; -import React, { useState, useRef, useEffect } from 'react'; import { useReduxEmbeddableContext } from '@kbn/presentation-util-plugin/public'; -import { RangeSliderStrings } from './range_slider_strings'; -import { RangeSliderReduxState, RangeValue } from './types'; -import { rangeSliderReducers } from './range_slider_reducers'; import { pluginServices } from '../../services'; +import { rangeSliderReducers } from '../range_slider_reducers'; +import { RangeSliderReduxState, RangeValue } from '../types'; +import { RangeSliderStrings } from './range_slider_strings'; -const INVALID_CLASS = 'rangeSliderAnchor__fieldNumber--invalid'; +export const RangeSliderPopover: FC = () => { + const [fieldFormatter, setFieldFormatter] = useState(() => (toFormat: string) => toFormat); + const rangeRef = useRef(null); -export const RangeSliderPopover = () => { // Controls Services Context const { dataViews } = pluginServices.getHooks(); const { get: getDataViewById } = dataViews.useService(); - - const [isPopoverOpen, setIsPopoverOpen] = useState(false); - const [rangeSliderMin, setRangeSliderMin] = useState(-Infinity); - const [rangeSliderMax, setRangeSliderMax] = useState(Infinity); - const [fieldFormatter, setFieldFormatter] = useState(() => (toFormat: string) => toFormat); - - const rangeRef = useRef(null); - const { useEmbeddableDispatch, useEmbeddableSelector: select, actions: { setSelectedRange }, } = useReduxEmbeddableContext(); + const dispatch = useEmbeddableDispatch(); // Select current state from Redux using multiple selectors to avoid rerenders. - const min = select((state) => state.componentState.min); - const max = select((state) => state.componentState.max); - const isInvalid = select((state) => state.componentState.isInvalid); + const dataViewId = select((state) => state.output.dataViewId); const fieldSpec = select((state) => state.componentState.field); - const id = select((state) => state.explicitInput.id); - const value = select((state) => state.explicitInput.value) ?? ['', '']; + const isInvalid = select((state) => state.componentState.isInvalid); + const max = select((state) => state.componentState.max); + const min = select((state) => state.componentState.min); const title = select((state) => state.explicitInput.title); - - const isLoading = select((state) => state.output.loading); - const dataViewId = select((state) => state.output.dataViewId); - - // derive field formatter from fieldSpec and dataViewId - useEffect(() => { - (async () => { - if (!dataViewId || !fieldSpec) return; - // dataViews are cached, and should always be available without having to hit ES. - const dataView = await getDataViewById(dataViewId); - setFieldFormatter( - () => - dataView?.getFormatterForField(fieldSpec).getConverterFor('text') ?? - ((toFormat: string) => toFormat) - ); - })(); - }, [fieldSpec, dataViewId, getDataViewById]); - - let errorMessage = ''; - let helpText = ''; + const value = select((state) => state.explicitInput.value) ?? ['', '']; const hasAvailableRange = min !== '' && max !== ''; - - if (!hasAvailableRange) { - helpText = RangeSliderStrings.popover.getNoAvailableDataHelpText(); - } else if (isInvalid) { - helpText = RangeSliderStrings.popover.getNoDataHelpText(); - } - const hasLowerBoundSelection = value[0] !== ''; const hasUpperBoundSelection = value[1] !== ''; - const lowerBoundValue = parseFloat(value[0]); - const upperBoundValue = parseFloat(value[1]); + const lowerBoundSelection = parseFloat(value[0]); + const upperBoundSelection = parseFloat(value[1]); const minValue = parseFloat(min); const maxValue = parseFloat(max); @@ -97,132 +63,74 @@ export const RangeSliderPopover = () => { const roundedMin = hasAvailableRange ? Math.floor(minValue) : minValue; const roundedMax = hasAvailableRange ? Math.ceil(maxValue) : maxValue; - if (lowerBoundValue > upperBoundValue) { - errorMessage = RangeSliderStrings.errors.getUpperLessThanLowerErrorMessage(); + // Caches min and max displayed on popover open so the range slider doesn't resize as selections change + const [rangeSliderMin, setRangeSliderMin] = useState(roundedMin); + const [rangeSliderMax, setRangeSliderMax] = useState(roundedMax); + + useMount(() => { + setRangeSliderMin( + Math.min( + roundedMin, + isNaN(lowerBoundSelection) ? Infinity : lowerBoundSelection, + isNaN(upperBoundSelection) ? Infinity : upperBoundSelection + ) + ); + setRangeSliderMax( + Math.max( + roundedMax, + isNaN(lowerBoundSelection) ? -Infinity : lowerBoundSelection, + isNaN(upperBoundSelection) ? -Infinity : upperBoundSelection + ) + ); + }); + + const errorMessage = ''; + let helpText = ''; + + if (!hasAvailableRange) { + helpText = RangeSliderStrings.popover.getNoAvailableDataHelpText(); + } else if (isInvalid) { + helpText = RangeSliderStrings.popover.getNoDataHelpText(); } const displayedValue = [ - hasLowerBoundSelection ? String(lowerBoundValue) : hasAvailableRange ? String(roundedMin) : '', - hasUpperBoundSelection ? String(upperBoundValue) : hasAvailableRange ? String(roundedMax) : '', + hasLowerBoundSelection + ? String(lowerBoundSelection) + : hasAvailableRange + ? String(roundedMin) + : '', + hasUpperBoundSelection + ? String(upperBoundSelection) + : hasAvailableRange + ? String(roundedMax) + : '', ] as RangeValue; const ticks = []; const levels = []; - if (hasAvailableRange && isPopoverOpen) { + if (hasAvailableRange) { ticks.push({ value: rangeSliderMin, label: fieldFormatter(String(rangeSliderMin)) }); ticks.push({ value: rangeSliderMax, label: fieldFormatter(String(rangeSliderMax)) }); levels.push({ min: roundedMin, max: roundedMax, color: 'success' }); } - const button = ( - - ); + // derive field formatter from fieldSpec and dataViewId + useEffect(() => { + (async () => { + if (!dataViewId || !fieldSpec) return; + // dataViews are cached, and should always be available without having to hit ES. + const dataView = await getDataViewById(dataViewId); + setFieldFormatter( + () => + dataView?.getFormatterForField(fieldSpec).getConverterFor('text') ?? + ((toFormat: string) => toFormat) + ); + })(); + }, [fieldSpec, dataViewId, getDataViewById]); return ( - setIsPopoverOpen(false)} - anchorPosition="downCenter" - attachToAnchor={false} - disableFocusTrap - onPanelResize={() => { - if (rangeRef?.current) { - rangeRef.current.onResize(); - } - }} - > + <> {title} { dispatch(setSelectedRange(['', '']))} + onClick={() => { + dispatch(setSelectedRange(['', ''])); + }} aria-label={RangeSliderStrings.popover.getClearRangeButtonTitle()} data-test-subj="rangeSlider__clearRangeButton" /> - + ); }; diff --git a/src/plugins/controls/public/range_slider/components/range_slider_strings.ts b/src/plugins/controls/public/range_slider/components/range_slider_strings.ts new file mode 100644 index 00000000000000..c016bc386b05a9 --- /dev/null +++ b/src/plugins/controls/public/range_slider/components/range_slider_strings.ts @@ -0,0 +1,26 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { i18n } from '@kbn/i18n'; + +export const RangeSliderStrings = { + popover: { + getClearRangeButtonTitle: () => + i18n.translate('controls.rangeSlider.popover.clearRangeTitle', { + defaultMessage: 'Clear range', + }), + getNoDataHelpText: () => + i18n.translate('controls.rangeSlider.popover.noDataHelpText', { + defaultMessage: 'Selected range resulted in no data. No filter was applied.', + }), + getNoAvailableDataHelpText: () => + i18n.translate('controls.rangeSlider.popover.noAvailableDataHelpText', { + defaultMessage: 'There is no data to display. Adjust the time range and filters.', + }), + }, +}; diff --git a/src/plugins/controls/public/control_types/range_slider/range_slider_embeddable.tsx b/src/plugins/controls/public/range_slider/embeddable/range_slider_embeddable.tsx similarity index 93% rename from src/plugins/controls/public/control_types/range_slider/range_slider_embeddable.tsx rename to src/plugins/controls/public/range_slider/embeddable/range_slider_embeddable.tsx index 699c0c42ceae7f..bface6a8c40aef 100644 --- a/src/plugins/controls/public/control_types/range_slider/range_slider_embeddable.tsx +++ b/src/plugins/controls/public/range_slider/embeddable/range_slider_embeddable.tsx @@ -6,14 +6,6 @@ * Side Public License, v 1. */ -import { - compareFilters, - buildRangeFilter, - COMPARE_ALL_OPTIONS, - RangeFilterParams, - Filter, - Query, -} from '@kbn/es-query'; import React from 'react'; import ReactDOM from 'react-dom'; import { isEmpty } from 'lodash'; @@ -23,20 +15,27 @@ import deepEqual from 'fast-deep-equal'; import { Subscription, lastValueFrom } from 'rxjs'; import { debounceTime, distinctUntilChanged, skip, map } from 'rxjs/operators'; -import { ReduxEmbeddableTools, ReduxEmbeddablePackage } from '@kbn/presentation-util-plugin/public'; -import { Embeddable, IContainer } from '@kbn/embeddable-plugin/public'; import { DataView, DataViewField } from '@kbn/data-views-plugin/public'; +import { Embeddable, IContainer } from '@kbn/embeddable-plugin/public'; +import { + compareFilters, + buildRangeFilter, + COMPARE_ALL_OPTIONS, + RangeFilterParams, + Filter, + Query, +} from '@kbn/es-query'; +import { i18n } from '@kbn/i18n'; import { KibanaThemeProvider } from '@kbn/kibana-react-plugin/public'; +import { ReduxEmbeddableTools, ReduxEmbeddablePackage } from '@kbn/presentation-util-plugin/public'; -import { pluginServices } from '../../services'; import { ControlInput, ControlOutput } from '../..'; +import { pluginServices } from '../../services'; import { ControlsDataService } from '../../services/data'; import { ControlsDataViewsService } from '../../services/data_views'; - -import { RangeSliderStrings } from './range_slider_strings'; -import { RangeSliderComponent } from './range_slider.component'; -import { getDefaultComponentState, rangeSliderReducers } from './range_slider_reducers'; -import { RangeSliderEmbeddableInput, RangeSliderReduxState, RANGE_SLIDER_CONTROL } from './types'; +import { RangeSliderControl } from '../components/range_slider_control'; +import { getDefaultComponentState, rangeSliderReducers } from '../range_slider_reducers'; +import { RangeSliderEmbeddableInput, RangeSliderReduxState, RANGE_SLIDER_CONTROL } from '../types'; const diffDataFetchProps = ( current?: RangeSliderDataFetchProps, @@ -164,8 +163,16 @@ export class RangeSliderEmbeddable extends Embeddable - + , diff --git a/src/plugins/controls/public/control_types/range_slider/range_slider_embeddable_factory.tsx b/src/plugins/controls/public/range_slider/embeddable/range_slider_embeddable_factory.tsx similarity index 84% rename from src/plugins/controls/public/control_types/range_slider/range_slider_embeddable_factory.tsx rename to src/plugins/controls/public/range_slider/embeddable/range_slider_embeddable_factory.tsx index 8610624a45daf1..a0cf10f9593900 100644 --- a/src/plugins/controls/public/control_types/range_slider/range_slider_embeddable_factory.tsx +++ b/src/plugins/controls/public/range_slider/embeddable/range_slider_embeddable_factory.tsx @@ -10,26 +10,40 @@ import deepEqual from 'fast-deep-equal'; import { EmbeddableFactoryDefinition, IContainer } from '@kbn/embeddable-plugin/public'; import { lazyLoadReduxEmbeddablePackage } from '@kbn/presentation-util-plugin/public'; +import { i18n } from '@kbn/i18n'; -import { ControlEmbeddable, DataControlField, IEditableControlFactory } from '../../types'; -import { RangeSliderEmbeddableInput, RANGE_SLIDER_CONTROL } from './types'; import { createRangeSliderExtract, createRangeSliderInject, -} from '../../../common/control_types/range_slider/range_slider_persistable_state'; -import { RangeSliderStrings } from './range_slider_strings'; +} from '../../../common/range_slider/range_slider_persistable_state'; +import { ControlEmbeddable, DataControlField, IEditableControlFactory } from '../../types'; +import { RangeSliderEmbeddableInput, RANGE_SLIDER_CONTROL } from '../types'; export class RangeSliderEmbeddableFactory implements EmbeddableFactoryDefinition, IEditableControlFactory { public type = RANGE_SLIDER_CONTROL; + + public getDisplayName = () => + i18n.translate('controls.rangeSlider.displayName', { + defaultMessage: 'Range slider', + }); + + public getDescription = () => + i18n.translate('controls.rangeSlider.description', { + defaultMessage: 'Add a control for selecting a range of field values.', + }); + + public getIconType = () => 'controlsHorizontal'; + public canCreateNew = () => false; - constructor() {} + public isEditable = () => Promise.resolve(false); public async create(initialInput: RangeSliderEmbeddableInput, parent?: IContainer) { const reduxEmbeddablePackage = await lazyLoadReduxEmbeddablePackage(); const { RangeSliderEmbeddable } = await import('./range_slider_embeddable'); + return Promise.resolve( new RangeSliderEmbeddable(reduxEmbeddablePackage, initialInput, {}, parent) ); @@ -47,6 +61,7 @@ export class RangeSliderEmbeddableFactory // if the field name or data view id has changed in this editing session, selected values are invalid, so reset them. newInput.value = ['', '']; } + return newInput; }; @@ -56,12 +71,6 @@ export class RangeSliderEmbeddableFactory } }; - public isEditable = () => Promise.resolve(false); - - public getDisplayName = () => RangeSliderStrings.getDisplayName(); - public getIconType = () => 'controlsHorizontal'; - public getDescription = () => RangeSliderStrings.getDescription(); - public inject = createRangeSliderInject(); public extract = createRangeSliderExtract(); } diff --git a/packages/kbn-shared-ux-storybook/src/config/preview.ts b/src/plugins/controls/public/range_slider/index.ts similarity index 51% rename from packages/kbn-shared-ux-storybook/src/config/preview.ts rename to src/plugins/controls/public/range_slider/index.ts index 194a16474af2cb..bac4f92caa4a23 100644 --- a/packages/kbn-shared-ux-storybook/src/config/preview.ts +++ b/src/plugins/controls/public/range_slider/index.ts @@ -6,7 +6,8 @@ * Side Public License, v 1. */ -import { addDecorator } from '@storybook/react'; -import { servicesDecorator } from '../decorators'; +export type { RangeSliderEmbeddableInput } from '../../common/range_slider/types'; +export { RANGE_SLIDER_CONTROL } from '../../common/range_slider/types'; -addDecorator(servicesDecorator); +export type { RangeSliderEmbeddable } from './embeddable/range_slider_embeddable'; +export { RangeSliderEmbeddableFactory } from './embeddable/range_slider_embeddable_factory'; diff --git a/src/plugins/controls/public/control_types/range_slider/range_slider_reducers.ts b/src/plugins/controls/public/range_slider/range_slider_reducers.ts similarity index 99% rename from src/plugins/controls/public/control_types/range_slider/range_slider_reducers.ts rename to src/plugins/controls/public/range_slider/range_slider_reducers.ts index 5bcf55770998fa..c62347e3958f0a 100644 --- a/src/plugins/controls/public/control_types/range_slider/range_slider_reducers.ts +++ b/src/plugins/controls/public/range_slider/range_slider_reducers.ts @@ -6,10 +6,11 @@ * Side Public License, v 1. */ -import { Filter } from '@kbn/es-query'; -import { PayloadAction } from '@reduxjs/toolkit'; import { WritableDraft } from 'immer/dist/types/types-external'; +import { PayloadAction } from '@reduxjs/toolkit'; + import { FieldSpec } from '@kbn/data-views-plugin/common'; +import { Filter } from '@kbn/es-query'; import { RangeSliderReduxState, RangeValue } from './types'; diff --git a/src/plugins/controls/public/control_types/range_slider/types.ts b/src/plugins/controls/public/range_slider/types.ts similarity index 80% rename from src/plugins/controls/public/control_types/range_slider/types.ts rename to src/plugins/controls/public/range_slider/types.ts index 390d91de08b884..8b30a797885d41 100644 --- a/src/plugins/controls/public/control_types/range_slider/types.ts +++ b/src/plugins/controls/public/range_slider/types.ts @@ -9,8 +9,8 @@ import { FieldSpec } from '@kbn/data-views-plugin/common'; import type { ReduxEmbeddableState } from '@kbn/presentation-util-plugin/public'; -import { RangeSliderEmbeddableInput } from '../../../common/control_types/range_slider/types'; -import { ControlOutput } from '../../types'; +import { RangeSliderEmbeddableInput } from '../../common/range_slider/types'; +import { ControlOutput } from '../types'; // Component state is only used by public components. export interface RangeSliderComponentState { @@ -27,4 +27,4 @@ export type RangeSliderReduxState = ReduxEmbeddableState< RangeSliderComponentState >; -export * from '../../../common/control_types/range_slider/types'; +export * from '../../common/range_slider/types'; diff --git a/src/plugins/controls/server/control_group/control_group_telemetry.test.ts b/src/plugins/controls/server/control_group/control_group_telemetry.test.ts index 140b58fd790fca..1e66bb15fbc2bd 100644 --- a/src/plugins/controls/server/control_group/control_group_telemetry.test.ts +++ b/src/plugins/controls/server/control_group/control_group_telemetry.test.ts @@ -24,7 +24,7 @@ const rawControlAttributes2: RawControlGroupAttributes = { controlStyle: 'oneLine', chainingSystem: 'NONE', panelsJSON: - '{"9cf90205-e94d-43c9-a3aa-45f359a7522f":{"order":0,"width":"auto","type":"rangeSliderControl","explicitInput":{"title":"DistanceKilometers","fieldName":"DistanceKilometers","id":"9cf90205-e94d-43c9-a3aa-45f359a7522f","enhancements":{}}},"b47916fd-fc03-4dcd-bef1-5c3b7a315723":{"order":1,"width":"auto","type":"timeSlider","explicitInput":{"title":"timestamp","fieldName":"timestamp","id":"b47916fd-fc03-4dcd-bef1-5c3b7a315723","enhancements":{}}},"f6b076c6-9ef5-483e-b08d-d313d60d4b8c":{"order":2,"width":"auto","type":"rangeSliderControl","explicitInput":{"title":"DistanceMiles","fieldName":"DistanceMiles","id":"f6b076c6-9ef5-483e-b08d-d313d60d4b8c","enhancements":{}}}}', + '{"9cf90205-e94d-43c9-a3aa-45f359a7522f":{"order":0,"width":"auto","type":"rangeSliderControl","explicitInput":{"title":"DistanceKilometers","fieldName":"DistanceKilometers","id":"9cf90205-e94d-43c9-a3aa-45f359a7522f","enhancements":{}}},"f6b076c6-9ef5-483e-b08d-d313d60d4b8c":{"order":2,"width":"auto","type":"rangeSliderControl","explicitInput":{"title":"DistanceMiles","fieldName":"DistanceMiles","id":"f6b076c6-9ef5-483e-b08d-d313d60d4b8c","enhancements":{}}}}', ignoreParentSettingsJSON: '{"ignoreFilters":true,"ignoreQuery":false,"ignoreTimerange":false,"ignoreValidations":false}', }; @@ -34,7 +34,7 @@ const rawControlAttributes3: RawControlGroupAttributes = { controlStyle: 'oneLine', chainingSystem: 'HIERARCHICAL', panelsJSON: - '{"9cf90205-e94d-43c9-a3aa-45f359a7522f":{"order":0,"width":"auto","type":"rangeSliderControl","explicitInput":{"title":"DistanceKilometers","fieldName":"DistanceKilometers","id":"9cf90205-e94d-43c9-a3aa-45f359a7522f","enhancements":{}}},"b47916fd-fc03-4dcd-bef1-5c3b7a315723":{"order":1,"width":"auto","type":"timeSlider","explicitInput":{"title":"timestamp","fieldName":"timestamp","id":"b47916fd-fc03-4dcd-bef1-5c3b7a315723","enhancements":{}}},"ee325e9e-6ec1-41f9-953f-423d59850d44":{"order":2,"width":"auto","type":"optionsListControl","explicitInput":{"title":"Carrier","fieldName":"Carrier","id":"ee325e9e-6ec1-41f9-953f-423d59850d44","enhancements":{}}},"cb0f5fcd-9ad9-4d4a-b489-b75bd060399b":{"order":3,"width":"auto","type":"optionsListControl","explicitInput":{"title":"DestCityName","fieldName":"DestCityName","id":"cb0f5fcd-9ad9-4d4a-b489-b75bd060399b","enhancements":{}}}}', + '{"9cf90205-e94d-43c9-a3aa-45f359a7522f":{"order":0,"width":"auto","type":"rangeSliderControl","explicitInput":{"title":"DistanceKilometers","fieldName":"DistanceKilometers","id":"9cf90205-e94d-43c9-a3aa-45f359a7522f","enhancements":{}}},"ee325e9e-6ec1-41f9-953f-423d59850d44":{"order":2,"width":"auto","type":"optionsListControl","explicitInput":{"title":"Carrier","fieldName":"Carrier","id":"ee325e9e-6ec1-41f9-953f-423d59850d44","enhancements":{}}},"cb0f5fcd-9ad9-4d4a-b489-b75bd060399b":{"order":3,"width":"auto","type":"optionsListControl","explicitInput":{"title":"DestCityName","fieldName":"DestCityName","id":"cb0f5fcd-9ad9-4d4a-b489-b75bd060399b","enhancements":{}}}}', ignoreParentSettingsJSON: '{"ignoreFilters":false,"ignoreQuery":false,"ignoreTimerange":false,"ignoreValidations":false}', }; @@ -97,7 +97,7 @@ describe('Control group telemetry function', () => { }); test('counts all telemetry over multiple runs', () => { - expect(finalTelemetry.total).toBe(10); + expect(finalTelemetry.total).toBe(8); }); test('counts control types over multiple runs.', () => { @@ -110,10 +110,6 @@ describe('Control group telemetry function', () => { details: {}, total: 3, }, - timeSlider: { - details: {}, - total: 2, - }, }); }); diff --git a/src/plugins/controls/server/plugin.ts b/src/plugins/controls/server/plugin.ts index 97e40306ae25a9..019430166ff6fa 100644 --- a/src/plugins/controls/server/plugin.ts +++ b/src/plugins/controls/server/plugin.ts @@ -7,14 +7,13 @@ */ import { CoreSetup, Plugin } from '@kbn/core/server'; - -import { EmbeddableSetup } from '@kbn/embeddable-plugin/server'; import { PluginSetup as DataSetup } from '@kbn/data-plugin/server'; +import { EmbeddableSetup } from '@kbn/embeddable-plugin/server'; import { PluginSetup as UnifiedSearchSetup } from '@kbn/unified-search-plugin/server'; import { setupOptionsListSuggestionsRoute } from './options_list/options_list_suggestions_route'; import { controlGroupContainerPersistableStateServiceFactory } from './control_group/control_group_container_factory'; import { optionsListPersistableStateServiceFactory } from './options_list/options_list_embeddable_factory'; -// import { timeSliderPersistableStateServiceFactory } from './control_types/time_slider/time_slider_embeddable_factory'; +import { rangeSliderPersistableStateServiceFactory } from './range_slider/range_slider_embeddable_factory'; interface SetupDeps { embeddable: EmbeddableSetup; @@ -24,13 +23,11 @@ interface SetupDeps { export class ControlsPlugin implements Plugin { public setup(core: CoreSetup, { embeddable, unifiedSearch }: SetupDeps) { - embeddable.registerEmbeddableFactory(optionsListPersistableStateServiceFactory()); - // Temporary disabling Time Slider - // embeddable.registerEmbeddableFactory(timeSliderPersistableStateServiceFactory()); - embeddable.registerEmbeddableFactory( controlGroupContainerPersistableStateServiceFactory(embeddable) ); + embeddable.registerEmbeddableFactory(optionsListPersistableStateServiceFactory()); + embeddable.registerEmbeddableFactory(rangeSliderPersistableStateServiceFactory()); setupOptionsListSuggestionsRoute(core, unifiedSearch.autocomplete.getAutocompleteSettings); return {}; diff --git a/src/plugins/controls/server/control_types/time_slider/time_slider_embeddable_factory.ts b/src/plugins/controls/server/range_slider/range_slider_embeddable_factory.ts similarity index 54% rename from src/plugins/controls/server/control_types/time_slider/time_slider_embeddable_factory.ts rename to src/plugins/controls/server/range_slider/range_slider_embeddable_factory.ts index 8e8920f12f5545..3b0c9ab7d1d4b3 100644 --- a/src/plugins/controls/server/control_types/time_slider/time_slider_embeddable_factory.ts +++ b/src/plugins/controls/server/range_slider/range_slider_embeddable_factory.ts @@ -7,16 +7,17 @@ */ import { EmbeddableRegistryDefinition } from '@kbn/embeddable-plugin/server'; -import { TIME_SLIDER_CONTROL } from '../../../common'; + +import { RANGE_SLIDER_CONTROL } from '../../common'; import { - createTimeSliderExtract, - createTimeSliderInject, -} from '../../../common/control_types/time_slider/time_slider_persistable_state'; + createRangeSliderExtract, + createRangeSliderInject, +} from '../../common/range_slider/range_slider_persistable_state'; -export const timeSliderPersistableStateServiceFactory = (): EmbeddableRegistryDefinition => { +export const rangeSliderPersistableStateServiceFactory = (): EmbeddableRegistryDefinition => { return { - id: TIME_SLIDER_CONTROL, - extract: createTimeSliderExtract(), - inject: createTimeSliderInject(), + id: RANGE_SLIDER_CONTROL, + extract: createRangeSliderExtract(), + inject: createRangeSliderInject(), }; }; diff --git a/src/plugins/dashboard/public/application/lib/dashboard_session_storage.ts b/src/plugins/dashboard/public/application/lib/dashboard_session_storage.ts index a696c8bc15b839..0c6aaba99b9eec 100644 --- a/src/plugins/dashboard/public/application/lib/dashboard_session_storage.ts +++ b/src/plugins/dashboard/public/application/lib/dashboard_session_storage.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import { set } from '@elastic/safer-lodash-set'; +import { set } from '@kbn/safer-lodash-set'; import { Storage } from '../../services/kibana_utils'; import { NotificationsStart } from '../../services/core'; import { panelStorageErrorStrings } from '../../dashboard_strings'; diff --git a/src/plugins/data/common/search/search_source/search_source.ts b/src/plugins/data/common/search/search_source/search_source.ts index 9f16795efa37a3..5f4ce4be637a88 100644 --- a/src/plugins/data/common/search/search_source/search_source.ts +++ b/src/plugins/data/common/search/search_source/search_source.ts @@ -58,7 +58,7 @@ * `appSearchSource`. */ -import { setWith } from '@elastic/safer-lodash-set'; +import { setWith } from '@kbn/safer-lodash-set'; import { difference, isEqual, isFunction, isObject, keyBy, pick, uniqueId, uniqWith } from 'lodash'; import { catchError, diff --git a/src/plugins/data/public/index.ts b/src/plugins/data/public/index.ts index c26b5a6ad81142..d970287253e3f2 100644 --- a/src/plugins/data/public/index.ts +++ b/src/plugins/data/public/index.ts @@ -111,6 +111,7 @@ import { toAbsoluteDates, boundsDescendingRaw, getResponseInspectorStats, + calcAutoIntervalLessThan, // tabify tabifyAggResponse, tabifyGetColumns, @@ -217,6 +218,7 @@ export const search = { termsAggFilter, toAbsoluteDates, boundsDescendingRaw, + calcAutoIntervalLessThan, }, getResponseInspectorStats, tabifyAggResponse, diff --git a/src/plugins/data/server/ui_settings.ts b/src/plugins/data/server/ui_settings.ts index 31c360e7610789..fce2680f5fc030 100644 --- a/src/plugins/data/server/ui_settings.ts +++ b/src/plugins/data/server/ui_settings.ts @@ -493,8 +493,9 @@ export function getUiSettings( description: i18n.translate('data.advancedSettings.autocompleteValueSuggestionMethodText', { defaultMessage: 'The method used for querying suggestions for values in KQL autocomplete. Select terms_enum to use the ' + - 'Elasticsearch terms enum API for improved autocomplete suggestion performance. Select terms_agg to use an ' + - 'Elasticsearch terms aggregation. {learnMoreLink}', + 'Elasticsearch terms enum API for improved autocomplete suggestion performance. (Note that terms_enum is ' + + 'incompatible with Document Level Security.) Select terms_agg to use an Elasticsearch terms aggregation. ' + + '{learnMoreLink}', values: { learnMoreLink: `` + diff --git a/src/plugins/data_view_editor/public/components/form_fields/title_field.tsx b/src/plugins/data_view_editor/public/components/form_fields/title_field.tsx index 6c41700ead5319..822de9506500a0 100644 --- a/src/plugins/data_view_editor/public/components/form_fields/title_field.tsx +++ b/src/plugins/data_view_editor/public/components/form_fields/title_field.tsx @@ -182,7 +182,6 @@ export const TitleField = ({ isInvalid={isInvalid} value={field.value} onChange={(e: ChangeEvent) => { - e.persist(); let query = e.target.value; if (query.length === 1 && !appendedWildcard && canAppendWildcard(query)) { query += '*'; diff --git a/src/plugins/data_view_field_editor/public/components/field_format_editor/editors/url/url.test.tsx b/src/plugins/data_view_field_editor/public/components/field_format_editor/editors/url/url.test.tsx index 4390d488e420ae..56dbcceb189d72 100644 --- a/src/plugins/data_view_field_editor/public/components/field_format_editor/editors/url/url.test.tsx +++ b/src/plugins/data_view_field_editor/public/components/field_format_editor/editors/url/url.test.tsx @@ -104,7 +104,7 @@ describe('UrlFormatEditor', () => { userEvent.selectOptions(getByLabelText('Type'), 'img'); expect(sampleImageUrlTemplate).toContain(MY_BASE_PATH); expect(sampleImageUrlTemplate).toMatchInlineSnapshot( - `"my-base-path/plugins/indexPatternManagement/assets/icons/{{value}}.png"` + `"my-base-path/plugins/dataViewFieldEditor/assets/icons/{{value}}.png"` ); }); }); diff --git a/src/plugins/data_view_field_editor/public/components/field_format_editor/editors/url/url.tsx b/src/plugins/data_view_field_editor/public/components/field_format_editor/editors/url/url.tsx index fc10a23d9e12da..f298af2c29a0c8 100644 --- a/src/plugins/data_view_field_editor/public/components/field_format_editor/editors/url/url.tsx +++ b/src/plugins/data_view_field_editor/public/components/field_format_editor/editors/url/url.tsx @@ -56,7 +56,7 @@ export class UrlFormatEditor extends DefaultFormatEditor< static contextType = contextType; static formatId = formatId; private get sampleIconPath() { - const sampleIconPath = `/plugins/indexPatternManagement/assets/icons/{{value}}.png`; + const sampleIconPath = `/plugins/dataViewFieldEditor/assets/icons/{{value}}.png`; return this.context?.services.http ? this.context.services.http.basePath.prepend(sampleIconPath) : sampleIconPath; diff --git a/src/plugins/data_view_management/public/assets/icons/LICENSE.txt b/src/plugins/data_view_management/public/assets/icons/LICENSE.txt deleted file mode 100644 index 1a86627c4a6b8c..00000000000000 --- a/src/plugins/data_view_management/public/assets/icons/LICENSE.txt +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2014 Steven Skelton - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/src/plugins/data_view_management/public/assets/icons/cv.png b/src/plugins/data_view_management/public/assets/icons/cv.png deleted file mode 100644 index 8f2ff8432e6bd2..00000000000000 Binary files a/src/plugins/data_view_management/public/assets/icons/cv.png and /dev/null differ diff --git a/src/plugins/data_view_management/public/assets/icons/de.png b/src/plugins/data_view_management/public/assets/icons/de.png deleted file mode 100644 index 78279117b4d101..00000000000000 Binary files a/src/plugins/data_view_management/public/assets/icons/de.png and /dev/null differ diff --git a/src/plugins/data_view_management/public/assets/icons/go.png b/src/plugins/data_view_management/public/assets/icons/go.png deleted file mode 100644 index 34c317db5adf34..00000000000000 Binary files a/src/plugins/data_view_management/public/assets/icons/go.png and /dev/null differ diff --git a/src/plugins/data_view_management/public/assets/icons/ne.png b/src/plugins/data_view_management/public/assets/icons/ne.png deleted file mode 100644 index d331209e179988..00000000000000 Binary files a/src/plugins/data_view_management/public/assets/icons/ne.png and /dev/null differ diff --git a/src/plugins/data_view_management/public/assets/icons/ni.png b/src/plugins/data_view_management/public/assets/icons/ni.png deleted file mode 100644 index e5bdb0b668d415..00000000000000 Binary files a/src/plugins/data_view_management/public/assets/icons/ni.png and /dev/null differ diff --git a/src/plugins/data_view_management/public/assets/icons/stop.png b/src/plugins/data_view_management/public/assets/icons/stop.png deleted file mode 100644 index 4bf65fc96f59fd..00000000000000 Binary files a/src/plugins/data_view_management/public/assets/icons/stop.png and /dev/null differ diff --git a/src/plugins/data_view_management/public/assets/icons/us.png b/src/plugins/data_view_management/public/assets/icons/us.png deleted file mode 100644 index f30f21f85d06a0..00000000000000 Binary files a/src/plugins/data_view_management/public/assets/icons/us.png and /dev/null differ diff --git a/src/plugins/discover/public/application/context/context_app_content.tsx b/src/plugins/discover/public/application/context/context_app_content.tsx index 3ba518c4a3df8d..7471f15092c3b3 100644 --- a/src/plugins/discover/public/application/context/context_app_content.tsx +++ b/src/plugins/discover/public/application/context/context_app_content.tsx @@ -11,6 +11,7 @@ import { FormattedMessage } from '@kbn/i18n-react'; import { EuiHorizontalRule, EuiText } from '@elastic/eui'; import type { DataView } from '@kbn/data-views-plugin/public'; import { SortDirection } from '@kbn/data-plugin/public'; +import type { SortOrder } from '@kbn/saved-search-plugin/public'; import { CONTEXT_STEP_SETTING, DOC_HIDE_TIME_COLUMN_SETTING } from '../../../common'; import { LoadingStatus } from './services/context_query_state'; import { ActionBar } from './components/action_bar/action_bar'; @@ -20,7 +21,6 @@ import { AppState } from './services/context_state'; import { SurrDocType } from './services/context'; import { MAX_CONTEXT_SIZE, MIN_CONTEXT_SIZE } from './services/constants'; import { DocTableContext } from '../../components/doc_table/doc_table_context'; -import type { SortPairArr } from '../../components/doc_table/utils/get_sort'; import { useDiscoverServices } from '../../hooks/use_discover_services'; import type { DataTableRecord } from '../../types'; @@ -151,7 +151,7 @@ export function ContextAppContent({ expandedDoc={expandedDoc} isLoading={isAnchorLoading} sampleSize={0} - sort={sort as SortPairArr[]} + sort={sort as SortOrder[]} isSortEnabled={false} showTimeCol={showTimeCol} useNewFieldsApi={useNewFieldsApi} diff --git a/src/plugins/discover/public/application/main/components/layout/discover_documents.tsx b/src/plugins/discover/public/application/main/components/layout/discover_documents.tsx index 92443cea9f1aed..dfff574659744c 100644 --- a/src/plugins/discover/public/application/main/components/layout/discover_documents.tsx +++ b/src/plugins/discover/public/application/main/components/layout/discover_documents.tsx @@ -15,7 +15,7 @@ import { } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; import { DataView } from '@kbn/data-views-plugin/public'; -import { SavedSearch } from '@kbn/saved-search-plugin/public'; +import { SavedSearch, SortOrder } from '@kbn/saved-search-plugin/public'; import { useDiscoverServices } from '../../../../hooks/use_discover_services'; import { DocViewFilterFn } from '../../../../services/doc_views/doc_views_types'; import { DiscoverGrid } from '../../../../components/discover_grid/discover_grid'; @@ -32,7 +32,6 @@ import { DataDocuments$, DataDocumentsMsg, RecordRawType } from '../../hooks/use import { AppState, GetStateReturn } from '../../services/discover_state'; import { useDataState } from '../../hooks/use_data_state'; import { DocTableInfinite } from '../../../../components/doc_table/doc_table_infinite'; -import { SortPairArr } from '../../../../components/doc_table/utils/get_sort'; import { DocumentExplorerCallout } from '../document_explorer_callout'; import { DocumentExplorerUpdateCallout } from '../document_explorer_callout/document_explorer_update_callout'; import { DiscoverTourProvider } from '../../../../components/discover_tour'; @@ -195,7 +194,7 @@ function DiscoverDocumentsComponent({ dataView={dataView} isLoading={isLoading} rows={rows} - sort={(state.sort as SortPairArr[]) || []} + sort={(state.sort as SortOrder[]) || []} sampleSize={sampleSize} searchDescription={savedSearch.description} searchTitle={savedSearch.title} diff --git a/src/plugins/discover/public/application/main/components/sidebar/discover_field.tsx b/src/plugins/discover/public/application/main/components/sidebar/discover_field.tsx index 6fbeca677bc63e..743e0005ec756e 100644 --- a/src/plugins/discover/public/application/main/components/sidebar/discover_field.tsx +++ b/src/plugins/discover/public/application/main/components/sidebar/discover_field.tsx @@ -397,6 +397,9 @@ function DiscoverFieldComponent({ const renderPopover = () => { const details = getDetails(field); + + // TODO: integrate + return ( <> {showFieldStats && ( diff --git a/src/plugins/discover/public/application/main/components/top_nav/on_save_search.tsx b/src/plugins/discover/public/application/main/components/top_nav/on_save_search.tsx index 9f0c1f9552f2ce..e99295fee9e977 100644 --- a/src/plugins/discover/public/application/main/components/top_nav/on_save_search.tsx +++ b/src/plugins/discover/public/application/main/components/top_nav/on_save_search.tsx @@ -6,8 +6,10 @@ * Side Public License, v 1. */ -import React from 'react'; +import React, { useState } from 'react'; import { i18n } from '@kbn/i18n'; +import { EuiFormRow, EuiSwitch } from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n-react'; import { SavedObjectSaveModal, showSaveModal, OnSaveProps } from '@kbn/saved-objects-plugin/public'; import { DataView } from '@kbn/data-views-plugin/public'; import { SavedSearch, SaveSavedSearchOptions } from '@kbn/saved-search-plugin/public'; @@ -108,20 +110,24 @@ export async function onSaveSearch({ const onSave = async ({ newTitle, newCopyOnSave, + newTimeRestore, newDescription, isTitleDuplicateConfirmed, onTitleDuplicate, }: { newTitle: string; + newTimeRestore: boolean; newCopyOnSave: boolean; newDescription: string; isTitleDuplicateConfirmed: boolean; onTitleDuplicate: () => void; }) => { const currentTitle = savedSearch.title; + const currentTimeRestore = savedSearch.timeRestore; const currentRowsPerPage = savedSearch.rowsPerPage; savedSearch.title = newTitle; savedSearch.description = newDescription; + savedSearch.timeRestore = newTimeRestore; savedSearch.rowsPerPage = uiSettings.get(DOC_TABLE_LEGACY) ? currentRowsPerPage : state.appStateContainer.getState().rowsPerPage; @@ -143,6 +149,7 @@ export async function onSaveSearch({ // If the save wasn't successful, put the original values back. if (!response.id || response.error) { savedSearch.title = currentTitle; + savedSearch.timeRestore = currentTimeRestore; savedSearch.rowsPerPage = currentRowsPerPage; } else { state.resetInitialAppState(); @@ -156,6 +163,7 @@ export async function onSaveSearch({ title={savedSearch.title ?? ''} showCopyOnSave={!!savedSearch.id} description={savedSearch.description} + timeRestore={savedSearch.timeRestore} onSave={onSave} onClose={onClose ?? (() => {})} /> @@ -167,13 +175,42 @@ const SaveSearchObjectModal: React.FC<{ title: string; showCopyOnSave: boolean; description?: string; - onSave: (props: OnSaveProps & { newRowsPerPage?: number }) => void; + timeRestore?: boolean; + onSave: (props: OnSaveProps & { newTimeRestore: boolean }) => void; onClose: () => void; -}> = ({ title, description, showCopyOnSave, onSave, onClose }) => { +}> = ({ title, description, showCopyOnSave, timeRestore: savedTimeRestore, onSave, onClose }) => { + const [timeRestore, setTimeRestore] = useState(savedTimeRestore || false); + const onModalSave = (params: OnSaveProps) => { - onSave(params); + onSave({ + ...params, + newTimeRestore: timeRestore, + }); }; + const options = ( + + } + > + setTimeRestore(event.target.checked)} + label={ + + } + /> + + ); + return ( diff --git a/src/plugins/discover/public/application/main/discover_main_route.test.tsx b/src/plugins/discover/public/application/main/discover_main_route.test.tsx index 6734864210ee64..aead62c038e479 100644 --- a/src/plugins/discover/public/application/main/discover_main_route.test.tsx +++ b/src/plugins/discover/public/application/main/discover_main_route.test.tsx @@ -22,7 +22,7 @@ import { searchSourceInstanceMock } from '@kbn/data-plugin/common/search/search_ import { findTestSubject } from '@elastic/eui/lib/test'; jest.mock('./discover_main_app', () => { return { - DiscoverMainApp: jest.fn(), + DiscoverMainApp: jest.fn().mockReturnValue(<>), }; }); diff --git a/src/plugins/discover/public/application/main/discover_main_route.tsx b/src/plugins/discover/public/application/main/discover_main_route.tsx index cec20f64d82b28..e8e1ec43bd42d6 100644 --- a/src/plugins/discover/public/application/main/discover_main_route.tsx +++ b/src/plugins/discover/public/application/main/discover_main_route.tsx @@ -32,6 +32,7 @@ import { LoadingIndicator } from '../../components/common/loading_indicator'; import { DiscoverError } from '../../components/common/error_alert'; import { useDiscoverServices } from '../../hooks/use_discover_services'; import { getUrlTracker } from '../../kibana_services'; +import { restoreStateFromSavedSearch } from '../../services/saved_searches/restore_from_saved_search'; const DiscoverMainAppMemoized = memo(DiscoverMainApp); @@ -129,6 +130,11 @@ export function DiscoverMainRoute(props: Props) { currentSavedSearch.searchSource.setField('index', currentDataView); } + restoreStateFromSavedSearch({ + savedSearch: currentSavedSearch, + timefilter: services.timefilter, + }); + setSavedSearch(currentSavedSearch); if (currentSavedSearch.id) { @@ -163,8 +169,9 @@ export function DiscoverMainRoute(props: Props) { } }, [ id, - services.data.search, + services.data, services.spaces, + services.timefilter, core.savedObjects.client, core.application.navigateToApp, core.theme, diff --git a/src/plugins/discover/public/application/main/hooks/use_discover_state.ts b/src/plugins/discover/public/application/main/hooks/use_discover_state.ts index b5cf634ebe3a08..b3aaed0d880db5 100644 --- a/src/plugins/discover/public/application/main/hooks/use_discover_state.ts +++ b/src/plugins/discover/public/application/main/hooks/use_discover_state.ts @@ -17,6 +17,7 @@ import { Query, } from '@kbn/es-query'; import { SavedSearch, getSavedSearch } from '@kbn/saved-search-plugin/public'; +import type { SortOrder } from '@kbn/saved-search-plugin/public'; import { getState } from '../services/discover_state'; import { getStateDefaults } from '../utils/get_state_defaults'; import { DiscoverServices } from '../../../build_services'; @@ -32,8 +33,8 @@ import { useSearchSession } from './use_search_session'; import { useDataState } from './use_data_state'; import { FetchStatus } from '../../types'; import { getDataViewAppState } from '../utils/get_switch_data_view_app_state'; -import { SortPairArr } from '../../../components/doc_table/utils/get_sort'; import { DataTableRecord } from '../../../types'; +import { restoreStateFromSavedSearch } from '../../../services/saved_searches/restore_from_saved_search'; const MAX_NUM_OF_COLUMNS = 50; @@ -193,6 +194,12 @@ export function useDiscoverState({ savedSearch: newSavedSearch, storage, }); + + restoreStateFromSavedSearch({ + savedSearch: newSavedSearch, + timefilter: services.timefilter, + }); + await stateContainer.replaceUrlAppState(newAppState); setState(newAppState); }, @@ -210,7 +217,7 @@ export function useDiscoverState({ dataView, nextDataView, state.columns || [], - (state.sort || []) as SortPairArr[], + (state.sort || []) as SortOrder[], config.get(MODIFY_COLUMNS_ON_SWITCH), config.get(SORT_DEFAULT_ORDER_SETTING), state.query diff --git a/src/plugins/discover/public/application/main/utils/get_state_defaults.ts b/src/plugins/discover/public/application/main/utils/get_state_defaults.ts index 5eb863372d90ce..f058c473127d4d 100644 --- a/src/plugins/discover/public/application/main/utils/get_state_defaults.ts +++ b/src/plugins/discover/public/application/main/utils/get_state_defaults.ts @@ -11,6 +11,7 @@ import { IUiSettingsClient } from '@kbn/core/public'; import { DataPublicPluginStart } from '@kbn/data-plugin/public'; import { Storage } from '@kbn/kibana-utils-plugin/public'; import { SavedSearch } from '@kbn/saved-search-plugin/public'; +import { getDefaultSort, getSortArray } from '../../../utils/sorting'; import { DEFAULT_COLUMNS_SETTING, DOC_HIDE_TIME_COLUMN_SETTING, @@ -19,7 +20,6 @@ import { } from '../../../../common'; import { AppState } from '../services/discover_state'; -import { getDefaultSort, getSortArray } from '../../../components/doc_table'; import { CHART_HIDDEN_KEY } from '../components/chart/discover_chart'; function getDefaultColumns(savedSearch: SavedSearch, config: IUiSettingsClient) { diff --git a/src/plugins/discover/public/application/main/utils/get_switch_data_view_app_state.ts b/src/plugins/discover/public/application/main/utils/get_switch_data_view_app_state.ts index 6ed489e5042319..064fe36d974ec2 100644 --- a/src/plugins/discover/public/application/main/utils/get_switch_data_view_app_state.ts +++ b/src/plugins/discover/public/application/main/utils/get_switch_data_view_app_state.ts @@ -7,7 +7,8 @@ */ import { isOfAggregateQueryType, Query, AggregateQuery } from '@kbn/es-query'; import type { DataView } from '@kbn/data-views-plugin/public'; -import { getSortArray, SortPairArr } from '../../../components/doc_table/utils/get_sort'; +import type { SortOrder } from '@kbn/saved-search-plugin/public'; +import { getSortArray } from '../../../utils/sorting'; /** * Helper function to remove or adapt the currently selected columns/sort to be valid with the next @@ -17,7 +18,7 @@ export function getDataViewAppState( currentDataView: DataView, nextDataView: DataView, currentColumns: string[], - currentSort: SortPairArr[], + currentSort: SortOrder[], modifyColumns: boolean = true, sortDirection: string = 'desc', query?: Query | AggregateQuery diff --git a/src/plugins/discover/public/application/main/utils/persist_saved_search.ts b/src/plugins/discover/public/application/main/utils/persist_saved_search.ts index 691a8a6604194b..488f9598aaae71 100644 --- a/src/plugins/discover/public/application/main/utils/persist_saved_search.ts +++ b/src/plugins/discover/public/application/main/utils/persist_saved_search.ts @@ -8,9 +8,7 @@ import { isOfAggregateQueryType } from '@kbn/es-query'; import { DataView } from '@kbn/data-views-plugin/public'; import { SavedObjectSaveOpts } from '@kbn/saved-objects-plugin/public'; -import { SavedSearch } from '@kbn/saved-search-plugin/public'; -import type { SortOrder } from '@kbn/saved-search-plugin/public'; -import { saveSavedSearch } from '@kbn/saved-search-plugin/public'; +import { SavedSearch, SortOrder, saveSavedSearch } from '@kbn/saved-search-plugin/public'; import { updateSearchSource } from './update_search_source'; import { AppState } from '../services/discover_state'; import { DiscoverServices } from '../../../build_services'; @@ -69,6 +67,20 @@ export async function persistSavedSearch( savedSearch.isTextBasedQuery = isTextBasedQuery; } + const { from, to } = services.timefilter.getTime(); + const refreshInterval = services.timefilter.getRefreshInterval(); + savedSearch.timeRange = + savedSearch.timeRestore || savedSearch.timeRange + ? { + from, + to, + } + : undefined; + savedSearch.refreshInterval = + savedSearch.timeRestore || savedSearch.refreshInterval + ? { value: refreshInterval.value, pause: refreshInterval.pause } + : undefined; + try { const id = await saveSavedSearch(savedSearch, saveOptions, services.core.savedObjects.client); if (id) { diff --git a/src/plugins/discover/public/application/main/utils/update_search_source.ts b/src/plugins/discover/public/application/main/utils/update_search_source.ts index aea864af91d816..4966a66cf9687a 100644 --- a/src/plugins/discover/public/application/main/utils/update_search_source.ts +++ b/src/plugins/discover/public/application/main/utils/update_search_source.ts @@ -11,7 +11,7 @@ import { DataViewType, DataView } from '@kbn/data-views-plugin/public'; import type { SortOrder } from '@kbn/saved-search-plugin/public'; import { SORT_DEFAULT_ORDER_SETTING } from '../../../../common'; import { DiscoverServices } from '../../../build_services'; -import { getSortForSearchSource } from '../../../components/doc_table'; +import { getSortForSearchSource } from '../../../utils/sorting'; /** * Helper function to update the given searchSource before fetching/sharing/persisting diff --git a/src/plugins/discover/public/application/main/utils/validate_time_range.ts b/src/plugins/discover/public/application/main/utils/validate_time_range.ts index 83d5f18de7f95b..65748bbd75ce9c 100644 --- a/src/plugins/discover/public/application/main/utils/validate_time_range.ts +++ b/src/plugins/discover/public/application/main/utils/validate_time_range.ts @@ -6,9 +6,9 @@ * Side Public License, v 1. */ -import dateMath from '@kbn/datemath'; import { i18n } from '@kbn/i18n'; import { ToastsStart } from '@kbn/core/public'; +import { isTimeRangeValid } from '../../../utils/validate_time'; /** * Validates a given time filter range, provided by URL or UI @@ -18,9 +18,7 @@ export function validateTimeRange( { from, to }: { from: string; to: string }, toastNotifications: ToastsStart ): boolean { - const fromMoment = dateMath.parse(from); - const toMoment = dateMath.parse(to); - if (!fromMoment || !toMoment || !fromMoment.isValid() || !toMoment.isValid()) { + if (!isTimeRangeValid({ from, to })) { toastNotifications.addDanger({ title: i18n.translate('discover.notifications.invalidTimeRangeTitle', { defaultMessage: `Invalid time range`, diff --git a/src/plugins/discover/public/components/discover_grid/discover_grid.tsx b/src/plugins/discover/public/components/discover_grid/discover_grid.tsx index d02529d924e3f0..1987542931676a 100644 --- a/src/plugins/discover/public/components/discover_grid/discover_grid.tsx +++ b/src/plugins/discover/public/components/discover_grid/discover_grid.tsx @@ -23,6 +23,7 @@ import { EuiLink, } from '@elastic/eui'; import type { DataView } from '@kbn/data-views-plugin/public'; +import type { SortOrder } from '@kbn/saved-search-plugin/public'; import { DocViewFilterFn } from '../../services/doc_views/doc_views_types'; import { getSchemaDetectors } from './discover_grid_schema'; import { DiscoverGridFlyout } from './discover_grid_flyout'; @@ -43,7 +44,6 @@ import { SHOW_MULTIFIELDS, } from '../../../common'; import { DiscoverGridDocumentToolbarBtn } from './discover_grid_document_selection'; -import { SortPairArr } from '../doc_table/utils/get_sort'; import { getFieldsToShow } from '../../utils/get_fields_to_show'; import type { DataTableRecord, ValueToStringConverter } from '../../types'; import { useRowHeightsOptions } from '../../hooks/use_row_heights_options'; @@ -141,7 +141,7 @@ export interface DiscoverGridProps { /** * Current sort setting */ - sort: SortPairArr[]; + sort: SortOrder[]; /** * How the data is fetched */ diff --git a/src/plugins/discover/public/components/doc_table/components/table_header/helpers.tsx b/src/plugins/discover/public/components/doc_table/components/table_header/helpers.tsx index 47b96d266067b0..57cdc35bad0166 100644 --- a/src/plugins/discover/public/components/doc_table/components/table_header/helpers.tsx +++ b/src/plugins/discover/public/components/doc_table/components/table_header/helpers.tsx @@ -9,7 +9,6 @@ import { i18n } from '@kbn/i18n'; import type { DataView } from '@kbn/data-views-plugin/public'; -export type SortOrder = [string, string]; export interface ColumnProps { name: string; displayName: string; diff --git a/src/plugins/discover/public/components/doc_table/components/table_header/table_header.test.tsx b/src/plugins/discover/public/components/doc_table/components/table_header/table_header.test.tsx index 2b1937c177e151..78d15870e6353e 100644 --- a/src/plugins/discover/public/components/doc_table/components/table_header/table_header.test.tsx +++ b/src/plugins/discover/public/components/doc_table/components/table_header/table_header.test.tsx @@ -9,9 +9,9 @@ import React from 'react'; import { mountWithIntl } from '@kbn/test-jest-helpers'; import type { DataView, DataViewField } from '@kbn/data-views-plugin/public'; +import type { SortOrder } from '@kbn/saved-search-plugin/public'; import { TableHeader } from './table_header'; import { findTestSubject } from '@elastic/eui/lib/test'; -import { SortOrder } from './helpers'; import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public'; import { DOC_HIDE_TIME_COLUMN_SETTING } from '../../../../../common'; import { FORMATS_UI_SETTINGS } from '@kbn/field-formats-plugin/common'; diff --git a/src/plugins/discover/public/components/doc_table/components/table_header/table_header.tsx b/src/plugins/discover/public/components/doc_table/components/table_header/table_header.tsx index ac9dc4c8e204f1..ef5ca408d2bd8e 100644 --- a/src/plugins/discover/public/components/doc_table/components/table_header/table_header.tsx +++ b/src/plugins/discover/public/components/doc_table/components/table_header/table_header.tsx @@ -9,9 +9,10 @@ import React, { useMemo } from 'react'; import type { DataView } from '@kbn/data-views-plugin/public'; import { FORMATS_UI_SETTINGS } from '@kbn/field-formats-plugin/common'; +import type { SortOrder } from '@kbn/saved-search-plugin/public'; import { TableHeaderColumn } from './table_header_column'; -import { SortOrder, getDisplayedColumns } from './helpers'; -import { getDefaultSort } from '../../utils/get_default_sort'; +import { getDisplayedColumns } from './helpers'; +import { getDefaultSort } from '../../../../utils/sorting'; import { useDiscoverServices } from '../../../../hooks/use_discover_services'; import { DOC_HIDE_TIME_COLUMN_SETTING, SORT_DEFAULT_ORDER_SETTING } from '../../../../../common'; diff --git a/src/plugins/discover/public/components/doc_table/components/table_header/table_header_column.tsx b/src/plugins/discover/public/components/doc_table/components/table_header/table_header_column.tsx index 80a1aee5e920f1..f7322b778a5583 100644 --- a/src/plugins/discover/public/components/doc_table/components/table_header/table_header_column.tsx +++ b/src/plugins/discover/public/components/doc_table/components/table_header/table_header_column.tsx @@ -9,7 +9,7 @@ import React from 'react'; import { i18n } from '@kbn/i18n'; import { EuiButtonIcon, EuiToolTip, EuiIconTip } from '@elastic/eui'; -import { SortOrder } from './helpers'; +import type { SortOrder } from '@kbn/saved-search-plugin/public'; import { DocViewTableScoreSortWarning } from './score_sort_warning'; interface Props { diff --git a/src/plugins/discover/public/components/doc_table/doc_table_wrapper.tsx b/src/plugins/discover/public/components/doc_table/doc_table_wrapper.tsx index c7036deaff50b2..23f8b3e2e888bf 100644 --- a/src/plugins/discover/public/components/doc_table/doc_table_wrapper.tsx +++ b/src/plugins/discover/public/components/doc_table/doc_table_wrapper.tsx @@ -9,10 +9,10 @@ import React, { forwardRef, useCallback, useMemo } from 'react'; import { EuiIcon, EuiSpacer, EuiText } from '@elastic/eui'; import type { DataView, DataViewField } from '@kbn/data-views-plugin/public'; +import type { SortOrder } from '@kbn/saved-search-plugin/public'; import { FormattedMessage } from '@kbn/i18n-react'; import { TableHeader } from './components/table_header/table_header'; import { SHOW_MULTIFIELDS } from '../../../common'; -import { SortOrder } from './components/table_header/helpers'; import { TableRow } from './components/table_row'; import { DocViewFilterFn } from '../../services/doc_views/doc_views_types'; import { getFieldsToShow } from '../../utils/get_fields_to_show'; diff --git a/src/plugins/discover/public/components/doc_table/index.ts b/src/plugins/discover/public/components/doc_table/index.ts deleted file mode 100644 index e79276b0c9687b..00000000000000 --- a/src/plugins/discover/public/components/doc_table/index.ts +++ /dev/null @@ -1,11 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -export { getSort, getSortArray } from './utils/get_sort'; -export { getSortForSearchSource } from './utils/get_sort_for_search_source'; -export { getDefaultSort } from './utils/get_default_sort'; diff --git a/src/plugins/discover/public/embeddable/saved_search_embeddable.tsx b/src/plugins/discover/public/embeddable/saved_search_embeddable.tsx index b4c3f41e4ba36f..fc9afe946fae03 100644 --- a/src/plugins/discover/public/embeddable/saved_search_embeddable.tsx +++ b/src/plugins/discover/public/embeddable/saved_search_embeddable.tsx @@ -22,6 +22,7 @@ import { I18nProvider } from '@kbn/i18n-react'; import type { KibanaExecutionContext } from '@kbn/core/public'; import { Container, Embeddable, FilterableEmbeddable } from '@kbn/embeddable-plugin/public'; import { Adapters, RequestAdapter } from '@kbn/inspector-plugin/common'; +import type { SortOrder } from '@kbn/saved-search-plugin/public'; import { APPLY_FILTER_TRIGGER, FilterManager, @@ -33,6 +34,7 @@ import { DataView, DataViewField } from '@kbn/data-views-plugin/public'; import { UiActionsStart } from '@kbn/ui-actions-plugin/public'; import { KibanaContextProvider, KibanaThemeProvider } from '@kbn/kibana-react-plugin/public'; import { SavedSearch } from '@kbn/saved-search-plugin/public'; +import { getSortForEmbeddable, SortPair } from '../utils/sorting'; import { RecordRawType } from '../application/main/hooks/use_saved_search'; import { buildDataTableRecord } from '../utils/build_data_record'; import { DataTableRecord, EsHitRecord } from '../types'; @@ -53,8 +55,6 @@ import { handleSourceColumnState } from '../utils/state_helpers'; import { DiscoverGridProps } from '../components/discover_grid/discover_grid'; import { DiscoverGridSettings } from '../components/discover_grid/types'; import { DocTableProps } from '../components/doc_table/doc_table_wrapper'; -import { getDefaultSort } from '../components/doc_table'; -import { SortOrder } from '../components/doc_table/components/table_header/helpers'; import { VIEW_MODE } from '../components/view_mode_toggle'; import { updateSearchSource } from './utils/update_search_source'; import { FieldStatisticsTable } from '../application/main/components/field_stats_table'; @@ -103,6 +103,7 @@ export class SavedSearchEmbeddable private prevTimeRange?: TimeRange; private prevFilters?: Filter[]; private prevQuery?: Query; + private prevSort?: SortOrder[]; private prevSearchSessionId?: string; private searchProps?: SearchProps; @@ -285,10 +286,8 @@ export class SavedSearchEmbeddable } }; - private getDefaultSort(dataView?: DataView) { - const defaultSortOrder = this.services.uiSettings.get(SORT_DEFAULT_ORDER_SETTING, 'desc'); - const hidingTimeColumn = this.services.uiSettings.get(DOC_HIDE_TIME_COLUMN_SETTING, false); - return getDefaultSort(dataView, defaultSortOrder, hidingTimeColumn); + private getSort(sort: SortPair[] | undefined, dataView?: DataView) { + return getSortForEmbeddable(sort, dataView, this.services.uiSettings); } private initializeSearchEmbeddableProps() { @@ -299,16 +298,13 @@ export class SavedSearchEmbeddable if (!dataView) { return; } - - if (!this.savedSearch.sort || !this.savedSearch.sort.length) { - this.savedSearch.sort = this.getDefaultSort(dataView); - } + const sort = this.getSort(this.savedSearch.sort, dataView); const props: SearchProps = { columns: this.savedSearch.columns, dataView, isLoading: false, - sort: this.getDefaultSort(dataView), + sort, rows: [], searchDescription: this.savedSearch.description, description: this.savedSearch.description, @@ -339,9 +335,9 @@ export class SavedSearchEmbeddable onSetColumns: (columns: string[]) => { this.updateInput({ columns }); }, - onSort: (sort: string[][]) => { + onSort: (nextSort: string[][]) => { const sortOrderArr: SortOrder[] = []; - sort.forEach((arr) => { + nextSort.forEach((arr) => { sortOrderArr.push(arr as SortOrder); }); this.updateInput({ sort: sortOrderArr }); @@ -400,14 +396,15 @@ export class SavedSearchEmbeddable } private isFetchRequired(searchProps?: SearchProps) { - if (!searchProps) { + if (!searchProps || !searchProps.dataView) { return false; } + return ( !onlyDisabledFiltersChanged(this.input.filters, this.prevFilters) || !isEqual(this.prevQuery, this.input.query) || !isEqual(this.prevTimeRange, this.input.timeRange) || - !isEqual(searchProps.sort, this.input.sort || this.savedSearch.sort) || + !isEqual(this.prevSort, this.input.sort) || this.prevSearchSessionId !== this.input.searchSessionId ); } @@ -431,12 +428,11 @@ export class SavedSearchEmbeddable { columns: this.input.columns || this.savedSearch.columns }, this.services.core.uiSettings ).columns; + searchProps.sort = this.getSort( + this.input.sort || this.savedSearch.sort, + searchProps?.dataView + ); - const savedSearchSort = - this.savedSearch.sort && this.savedSearch.sort.length - ? this.savedSearch.sort - : this.getDefaultSort(this.searchProps?.dataView); - searchProps.sort = this.input.sort || savedSearchSort; searchProps.sharedItemTitle = this.panelTitle; searchProps.rowHeightState = this.input.rowHeight || this.savedSearch.rowHeight; searchProps.rowsPerPageState = this.input.rowsPerPage || this.savedSearch.rowsPerPage; @@ -453,6 +449,7 @@ export class SavedSearchEmbeddable this.prevQuery = this.input.query; this.prevTimeRange = this.input.timeRange; this.prevSearchSessionId = this.input.searchSessionId; + this.prevSort = this.input.sort; this.searchProps = searchProps; await this.fetch(); } else if (this.searchProps && this.node) { diff --git a/src/plugins/discover/public/embeddable/types.ts b/src/plugins/discover/public/embeddable/types.ts index dacb9b7d81d437..6038aa5a0625c2 100644 --- a/src/plugins/discover/public/embeddable/types.ts +++ b/src/plugins/discover/public/embeddable/types.ts @@ -15,7 +15,7 @@ import { import type { Filter, TimeRange, Query } from '@kbn/es-query'; import { DataView } from '@kbn/data-views-plugin/public'; import { SavedSearch } from '@kbn/saved-search-plugin/public'; -import { SortOrder } from '../components/doc_table/components/table_header/helpers'; +import type { SortOrder } from '@kbn/saved-search-plugin/public'; export interface SearchInput extends EmbeddableInput { timeRange: TimeRange; diff --git a/src/plugins/discover/public/embeddable/utils/update_search_source.ts b/src/plugins/discover/public/embeddable/utils/update_search_source.ts index 0126ed4d021e64..87ee137aed7966 100644 --- a/src/plugins/discover/public/embeddable/utils/update_search_source.ts +++ b/src/plugins/discover/public/embeddable/utils/update_search_source.ts @@ -6,14 +6,14 @@ * Side Public License, v 1. */ import type { DataView } from '@kbn/data-views-plugin/public'; -import { ISearchSource } from '@kbn/data-plugin/public'; -import { getSortForSearchSource } from '../../components/doc_table'; -import { SortPairArr } from '../../components/doc_table/utils/get_sort'; +import type { ISearchSource } from '@kbn/data-plugin/public'; +import type { SortOrder } from '@kbn/saved-search-plugin/public'; +import { getSortForSearchSource } from '../../utils/sorting'; export const updateSearchSource = ( searchSource: ISearchSource, dataView: DataView | undefined, - sort: (SortPairArr[] & string[][]) | undefined, + sort: (SortOrder[] & string[][]) | undefined, useNewFieldsApi: boolean, defaults: { sampleSize: number; diff --git a/src/plugins/discover/public/services/saved_searches/restore_from_saved_search.test.ts b/src/plugins/discover/public/services/saved_searches/restore_from_saved_search.test.ts new file mode 100644 index 00000000000000..355f80b78b2aca --- /dev/null +++ b/src/plugins/discover/public/services/saved_searches/restore_from_saved_search.test.ts @@ -0,0 +1,101 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import type { TimefilterContract } from '@kbn/data-plugin/public'; +import type { TimeRange, RefreshInterval } from '@kbn/data-plugin/common'; +import type { SavedSearch } from '@kbn/saved-search-plugin/public'; +import { restoreStateFromSavedSearch } from './restore_from_saved_search'; + +describe('discover restore state from saved search', () => { + let timefilterMock: TimefilterContract; + const timeRange: TimeRange = { + from: 'now-30m', + to: 'now', + }; + const refreshInterval: RefreshInterval = { + value: 5000, + pause: false, + }; + + beforeEach(() => { + timefilterMock = { + setTime: jest.fn(), + setRefreshInterval: jest.fn(), + } as unknown as TimefilterContract; + }); + + test('should not update timefilter if attributes are not set', async () => { + restoreStateFromSavedSearch({ + savedSearch: {} as SavedSearch, + timefilter: timefilterMock, + }); + + expect(timefilterMock.setTime).not.toHaveBeenCalled(); + expect(timefilterMock.setRefreshInterval).not.toHaveBeenCalled(); + }); + + test('should not update timefilter if timeRestore is disabled', async () => { + restoreStateFromSavedSearch({ + savedSearch: { + timeRestore: false, + timeRange, + refreshInterval, + } as SavedSearch, + timefilter: timefilterMock, + }); + + expect(timefilterMock.setTime).not.toHaveBeenCalled(); + expect(timefilterMock.setRefreshInterval).not.toHaveBeenCalled(); + }); + + test('should update timefilter if timeRestore is enabled', async () => { + restoreStateFromSavedSearch({ + savedSearch: { + timeRestore: true, + timeRange, + refreshInterval, + } as SavedSearch, + timefilter: timefilterMock, + }); + + expect(timefilterMock.setTime).toHaveBeenCalledWith(timeRange); + expect(timefilterMock.setRefreshInterval).toHaveBeenCalledWith(refreshInterval); + }); + + test('should not update timefilter if attributes are missing', async () => { + restoreStateFromSavedSearch({ + savedSearch: { + timeRestore: true, + } as SavedSearch, + timefilter: timefilterMock, + }); + + expect(timefilterMock.setTime).not.toHaveBeenCalled(); + expect(timefilterMock.setRefreshInterval).not.toHaveBeenCalled(); + }); + + test('should not update timefilter if attributes are invalid', async () => { + restoreStateFromSavedSearch({ + savedSearch: { + timeRestore: true, + timeRange: { + from: 'test', + to: 'now', + }, + refreshInterval: { + pause: false, + value: -500, + }, + } as SavedSearch, + timefilter: timefilterMock, + }); + + expect(timefilterMock.setTime).not.toHaveBeenCalled(); + expect(timefilterMock.setRefreshInterval).not.toHaveBeenCalled(); + }); +}); diff --git a/src/plugins/discover/public/services/saved_searches/restore_from_saved_search.ts b/src/plugins/discover/public/services/saved_searches/restore_from_saved_search.ts new file mode 100644 index 00000000000000..550c36408977b4 --- /dev/null +++ b/src/plugins/discover/public/services/saved_searches/restore_from_saved_search.ts @@ -0,0 +1,34 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import type { TimefilterContract } from '@kbn/data-plugin/public'; +import type { SavedSearch } from '@kbn/saved-search-plugin/public'; +import { isRefreshIntervalValid, isTimeRangeValid } from '../../utils/validate_time'; + +export const restoreStateFromSavedSearch = ({ + savedSearch, + timefilter, +}: { + savedSearch: SavedSearch; + timefilter: TimefilterContract; +}) => { + if (!savedSearch) { + return; + } + + if (savedSearch.timeRestore && savedSearch.timeRange && isTimeRangeValid(savedSearch.timeRange)) { + timefilter.setTime(savedSearch.timeRange); + } + if ( + savedSearch.timeRestore && + savedSearch.refreshInterval && + isRefreshIntervalValid(savedSearch.refreshInterval) + ) { + timefilter.setRefreshInterval(savedSearch.refreshInterval); + } +}; diff --git a/src/plugins/discover/public/utils/get_sharing_data.ts b/src/plugins/discover/public/utils/get_sharing_data.ts index 6d99edd3d9fe1d..ace169359e318d 100644 --- a/src/plugins/discover/public/utils/get_sharing_data.ts +++ b/src/plugins/discover/public/utils/get_sharing_data.ts @@ -15,12 +15,12 @@ import type { } from '@kbn/data-plugin/public'; import type { Filter } from '@kbn/es-query'; import type { SavedSearch, SortOrder } from '@kbn/saved-search-plugin/public'; +import { getSortForSearchSource } from './sorting'; import { DOC_HIDE_TIME_COLUMN_SETTING, SEARCH_FIELDS_FROM_SOURCE, SORT_DEFAULT_ORDER_SETTING, } from '../../common'; -import { getSortForSearchSource } from '../components/doc_table'; import { AppState, isEqualFilters } from '../application/main/services/discover_state'; /** diff --git a/src/plugins/discover/public/components/doc_table/utils/get_default_sort.test.ts b/src/plugins/discover/public/utils/sorting/get_default_sort.test.ts similarity index 100% rename from src/plugins/discover/public/components/doc_table/utils/get_default_sort.test.ts rename to src/plugins/discover/public/utils/sorting/get_default_sort.test.ts diff --git a/src/plugins/discover/public/components/doc_table/utils/get_default_sort.ts b/src/plugins/discover/public/utils/sorting/get_default_sort.ts similarity index 93% rename from src/plugins/discover/public/components/doc_table/utils/get_default_sort.ts rename to src/plugins/discover/public/utils/sorting/get_default_sort.ts index 82055e94f54074..d5b72c4b13949b 100644 --- a/src/plugins/discover/public/components/doc_table/utils/get_default_sort.ts +++ b/src/plugins/discover/public/utils/sorting/get_default_sort.ts @@ -7,8 +7,8 @@ */ import type { DataView } from '@kbn/data-views-plugin/public'; +import type { SortOrder } from '@kbn/saved-search-plugin/public'; import { isSortable } from './get_sort'; -import { SortOrder } from '../components/table_header/helpers'; /** * use in case the user didn't manually sort. diff --git a/src/plugins/discover/public/components/doc_table/utils/get_sort.test.ts b/src/plugins/discover/public/utils/sorting/get_sort.test.ts similarity index 66% rename from src/plugins/discover/public/components/doc_table/utils/get_sort.test.ts rename to src/plugins/discover/public/utils/sorting/get_sort.test.ts index f778bbd8fecaab..0656a2e36c4ca3 100644 --- a/src/plugins/discover/public/components/doc_table/utils/get_sort.test.ts +++ b/src/plugins/discover/public/utils/sorting/get_sort.test.ts @@ -6,11 +6,12 @@ * Side Public License, v 1. */ -import { getSort, getSortArray } from './get_sort'; +import { getSort, getSortArray, getSortForEmbeddable } from './get_sort'; import { stubDataView, stubDataViewWithoutTimeField, } from '@kbn/data-views-plugin/common/data_view.stub'; +import { uiSettingsMock } from '../../__mocks__/ui_settings'; describe('docTable', function () { describe('getSort function', function () { @@ -47,7 +48,6 @@ describe('docTable', function () { expect(getSort(['foo', 'asc'], stubDataView)).toEqual([{ foo: 'asc' }]); }); }); - describe('getSortArray function', function () { test('should have an array method', function () { expect(getSortArray).toBeInstanceOf(Function); @@ -64,14 +64,42 @@ describe('docTable', function () { test('should sort by an empty array when an unsortable field is given', function () { expect(getSortArray([{ 'non-sortable': 'asc' }], stubDataView)).toEqual([]); expect(getSortArray([{ lol_nope: 'asc' }], stubDataView)).toEqual([]); - expect(getSortArray([{ 'non-sortable': 'asc' }], stubDataViewWithoutTimeField)).toEqual([]); }); test('should return an empty array when passed an empty sort array', () => { expect(getSortArray([], stubDataView)).toEqual([]); - expect(getSortArray([], stubDataViewWithoutTimeField)).toEqual([]); }); }); + describe('getSortForEmbeddable function', function () { + test('should return an array of arrays for sortable fields', function () { + expect(getSortForEmbeddable([['bytes', 'desc']], stubDataView)).toEqual([['bytes', 'desc']]); + }); + + test('should return an array of arrays from an array of elasticsearch sort objects', function () { + expect(getSortForEmbeddable([{ bytes: 'desc' }], stubDataView)).toEqual([['bytes', 'desc']]); + }); + + test('should sort by an empty array when an unsortable field is given', function () { + expect(getSortForEmbeddable([{ 'non-sortable': 'asc' }], stubDataView)).toEqual([]); + expect(getSortForEmbeddable([{ lol_nope: 'asc' }], stubDataView)).toEqual([]); + expect( + getSortForEmbeddable([{ 'non-sortable': 'asc' }], stubDataViewWithoutTimeField) + ).toEqual([]); + }); + + test('should return an empty array when passed an empty sort array', () => { + expect(getSortForEmbeddable([], stubDataView)).toEqual([]); + expect(getSortForEmbeddable([], stubDataViewWithoutTimeField)).toEqual([]); + }); + + test('should provide fallback results', () => { + expect(getSortForEmbeddable(undefined)).toEqual([]); + expect(getSortForEmbeddable(undefined, stubDataView)).toEqual([]); + expect(getSortForEmbeddable(undefined, stubDataView, uiSettingsMock)).toEqual([ + ['@timestamp', 'desc'], + ]); + }); + }); }); diff --git a/src/plugins/discover/public/components/doc_table/utils/get_sort.ts b/src/plugins/discover/public/utils/sorting/get_sort.ts similarity index 67% rename from src/plugins/discover/public/components/doc_table/utils/get_sort.ts rename to src/plugins/discover/public/utils/sorting/get_sort.ts index 31d4375a5f2660..59d414d8e1eea4 100644 --- a/src/plugins/discover/public/components/doc_table/utils/get_sort.ts +++ b/src/plugins/discover/public/utils/sorting/get_sort.ts @@ -8,10 +8,13 @@ import { isPlainObject } from 'lodash'; import { DataView } from '@kbn/data-views-plugin/public'; +import { IUiSettingsClient } from '@kbn/core/public'; +import type { SortOrder } from '@kbn/saved-search-plugin/public'; +import { DOC_HIDE_TIME_COLUMN_SETTING, SORT_DEFAULT_ORDER_SETTING } from '../../../common'; +import { getDefaultSort } from './get_default_sort'; export type SortPairObj = Record; -export type SortPairArr = [string, string]; -export type SortPair = SortPairArr | SortPairObj; +export type SortPair = SortOrder | SortPairObj; export type SortInput = SortPair | SortPair[]; export function isSortable(fieldName: string, dataView: DataView): boolean { @@ -25,7 +28,7 @@ function createSortObject(sortPair: SortInput, dataView: DataView): SortPairObj sortPair.length === 2 && isSortable(String(sortPair[0]), dataView) ) { - const [field, direction] = sortPair as SortPairArr; + const [field, direction] = sortPair as SortOrder; return { [field]: direction }; } else if (isPlainObject(sortPair) && isSortable(Object.keys(sortPair)[0], dataView)) { return sortPair as SortPairObj; @@ -62,8 +65,8 @@ export function getSort(sort: SortPair[] | SortPair, dataView: DataView): SortPa * compared to getSort it doesn't return an array of objects, it returns an array of arrays * [[fieldToSort: directionToSort]] */ -export function getSortArray(sort: SortPair[], dataView: DataView): SortPairArr[] { - return getSort(sort, dataView).reduce((acc: SortPairArr[], sortPair) => { +export function getSortArray(sort: SortInput, dataView: DataView): SortOrder[] { + return getSort(sort, dataView).reduce((acc: SortOrder[], sortPair) => { const entries = Object.entries(sortPair); if (entries && entries[0]) { acc.push(entries[0]); @@ -71,3 +74,22 @@ export function getSortArray(sort: SortPair[], dataView: DataView): SortPairArr[ return acc; }, []); } + +/** + * sorting for embeddable, like getSortArray,but returning a default in the case the given sort or dataView is not valid + */ +export function getSortForEmbeddable( + sort?: SortInput, + dataView?: DataView, + uiSettings?: IUiSettingsClient +): SortOrder[] { + if (!sort || !sort.length || !dataView) { + if (!uiSettings) { + return []; + } + const defaultSortOrder = uiSettings.get(SORT_DEFAULT_ORDER_SETTING, 'desc'); + const hidingTimeColumn = uiSettings.get(DOC_HIDE_TIME_COLUMN_SETTING, false); + return getDefaultSort(dataView, defaultSortOrder, hidingTimeColumn); + } + return getSortArray(sort, dataView); +} diff --git a/src/plugins/discover/public/components/doc_table/utils/get_sort_for_search_source.test.ts b/src/plugins/discover/public/utils/sorting/get_sort_for_search_source.test.ts similarity index 96% rename from src/plugins/discover/public/components/doc_table/utils/get_sort_for_search_source.test.ts rename to src/plugins/discover/public/utils/sorting/get_sort_for_search_source.test.ts index 729d74cb710faa..dd54b5d2a70a23 100644 --- a/src/plugins/discover/public/components/doc_table/utils/get_sort_for_search_source.test.ts +++ b/src/plugins/discover/public/utils/sorting/get_sort_for_search_source.test.ts @@ -5,9 +5,8 @@ * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ - +import type { SortOrder } from '@kbn/saved-search-plugin/public'; import { getSortForSearchSource } from './get_sort_for_search_source'; -import { SortOrder } from '../components/table_header/helpers'; import { stubDataView, stubDataViewWithoutTimeField } from '@kbn/data-plugin/common/stubs'; describe('getSortForSearchSource function', function () { diff --git a/src/plugins/discover/public/components/doc_table/utils/get_sort_for_search_source.ts b/src/plugins/discover/public/utils/sorting/get_sort_for_search_source.ts similarity index 96% rename from src/plugins/discover/public/components/doc_table/utils/get_sort_for_search_source.ts rename to src/plugins/discover/public/utils/sorting/get_sort_for_search_source.ts index c3f8badc0a536f..bcf0ccf4d0e30f 100644 --- a/src/plugins/discover/public/components/doc_table/utils/get_sort_for_search_source.ts +++ b/src/plugins/discover/public/utils/sorting/get_sort_for_search_source.ts @@ -8,7 +8,7 @@ import type { DataView } from '@kbn/data-views-plugin/public'; import type { EsQuerySortValue } from '@kbn/data-plugin/public'; -import { SortOrder } from '../components/table_header/helpers'; +import type { SortOrder } from '@kbn/saved-search-plugin/public'; import { getSort } from './get_sort'; /** diff --git a/packages/kbn-bazel-packages/src/index.ts b/src/plugins/discover/public/utils/sorting/index.ts similarity index 59% rename from packages/kbn-bazel-packages/src/index.ts rename to src/plugins/discover/public/utils/sorting/index.ts index 55d5db9bb3adb2..1d7f3ce6d671a7 100644 --- a/packages/kbn-bazel-packages/src/index.ts +++ b/src/plugins/discover/public/utils/sorting/index.ts @@ -5,7 +5,7 @@ * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ - -export * from './bazel_package_dirs'; -export * from './discover_packages'; -export type { BazelPackage } from './bazel_package'; +export { getSort, getSortArray, getSortForEmbeddable } from './get_sort'; +export { getSortForSearchSource } from './get_sort_for_search_source'; +export { getDefaultSort } from './get_default_sort'; +export type { SortPair } from './get_sort'; diff --git a/src/plugins/discover/public/utils/validate_time.test.ts b/src/plugins/discover/public/utils/validate_time.test.ts new file mode 100644 index 00000000000000..771c2a7bb029f1 --- /dev/null +++ b/src/plugins/discover/public/utils/validate_time.test.ts @@ -0,0 +1,38 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import type { RefreshInterval, TimeRange } from '@kbn/data-plugin/common'; +import { isTimeRangeValid, isRefreshIntervalValid } from './validate_time'; + +describe('discover validate time', () => { + test('should validate time ranges correctly', async () => { + expect(isTimeRangeValid({ from: '2020-06-02T13:36:13.689Z', to: 'now' })).toEqual(true); + expect(isTimeRangeValid({ from: 'now', to: 'now+1h' })).toEqual(true); + expect(isTimeRangeValid({ from: '', to: '' })).toEqual(false); + expect(isTimeRangeValid({} as unknown as TimeRange)).toEqual(false); + expect(isTimeRangeValid(undefined)).toEqual(false); + }); + + test('should validate that refresh interval is valid', async () => { + expect(isRefreshIntervalValid({ value: 5000, pause: false })).toEqual(true); + expect(isRefreshIntervalValid({ value: 0, pause: false })).toEqual(true); + expect(isRefreshIntervalValid({ value: 4000, pause: true })).toEqual(true); + }); + + test('should validate that refresh interval is invalid', async () => { + expect(isRefreshIntervalValid({ value: -5000, pause: false })).toEqual(false); + expect( + isRefreshIntervalValid({ value: 'test', pause: false } as unknown as RefreshInterval) + ).toEqual(false); + expect( + isRefreshIntervalValid({ value: 4000, pause: 'test' } as unknown as RefreshInterval) + ).toEqual(false); + expect(isRefreshIntervalValid({} as unknown as RefreshInterval)).toEqual(false); + expect(isRefreshIntervalValid(undefined)).toEqual(false); + }); +}); diff --git a/src/plugins/discover/public/utils/validate_time.ts b/src/plugins/discover/public/utils/validate_time.ts new file mode 100644 index 00000000000000..a6ad44e2112c6f --- /dev/null +++ b/src/plugins/discover/public/utils/validate_time.ts @@ -0,0 +1,30 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import dateMath from '@kbn/datemath'; +import type { RefreshInterval } from '@kbn/data-plugin/common'; + +export function isTimeRangeValid(timeRange?: { from: string; to: string }): boolean { + if (!timeRange?.from || !timeRange?.to) { + return false; + } + const fromMoment = dateMath.parse(timeRange.from); + const toMoment = dateMath.parse(timeRange.to); + return Boolean(fromMoment && toMoment && fromMoment.isValid() && toMoment.isValid()); +} + +export function isRefreshIntervalValid(refreshInterval?: RefreshInterval): boolean { + if (!refreshInterval) { + return false; + } + return ( + typeof refreshInterval?.value === 'number' && + refreshInterval?.value >= 0 && + typeof refreshInterval?.pause === 'boolean' + ); +} diff --git a/src/plugins/embeddable/README.md b/src/plugins/embeddable/README.md index fc6632252bb01b..14fab2f8412f3f 100644 --- a/src/plugins/embeddable/README.md +++ b/src/plugins/embeddable/README.md @@ -4,6 +4,7 @@ The Embeddables Plugin provides an opportunity to expose reusable interactive wi ## Capabilities - Framework-agnostic API. - Out-of-the-box React support. +- Integration with Redux. - Integration with the [UI Actions](https://github.com/elastic/kibana/tree/HEAD/src/plugins/ui_actions) plugin. - Hierarchical structure to enclose multiple widgets. - Error handling. @@ -354,6 +355,251 @@ The plugin provides a set of ready-to-use React components that abstract renderi Apart from the React components, there is also a way to construct an embeddable object using `useEmbeddableFactory` hook. This React hook takes care of producing an embeddable and updating its input state if passed state changes. +### Redux +The plugin provides an adapter for Redux over the embeddable state. +It uses the Redux Toolkit library underneath and works as a decorator on top of the [`configureStore`](https://redux-toolkit.js.org/api/configureStore) function. +In other words, it provides a way to use the full power of the library together with the embeddable plugin features. + +The adapter implements a bi-directional sync mechanism between the embeddable instance and the Redux state. +To perform state mutations, the plugin also exposes a pre-defined state of the actions that can be extended by an additional reducer. + +Here is an example of initializing a Redux store: +```tsx +import React from 'react'; +import { render } from 'react-dom'; +import { connect, Provider } from 'react-redux'; +import { Embeddable, IEmbeddable } from '@kbn/embeddable-plugin/public'; +import { createStore, State } from '@kbn/embeddable-plugin/public/store'; +import { HelloWorldComponent } from './hello_world_component'; + +export const HELLO_WORLD = 'HELLO_WORLD'; + +export class HelloWorld extends Embeddable { + readonly type = HELLO_WORLD; + + readonly store = createStore(this); + + reload() {} + + render(node: HTMLElement) { + const Component = connect((state: State) => ({ title: state.input.title }))( + HelloWorldComponent + ); + + render( + + + , + node + ); + } +} +``` + +Then inside the embedded component, it is possible to use the [`useSelector`](https://react-redux.js.org/api/hooks#useselector) and [`useDispatch`](https://react-redux.js.org/api/hooks#usedispatch) hooks. +```tsx +import React from 'react'; +import { useDispatch, useSelector } from 'react-redux'; +import { actions, State } from '@kbn/embeddable-plugin/public/store'; +import { ViewMode } from '@kbn/embeddable-plugin/public'; +import type { HelloWorld } from './hello_world'; + +interface HelloWorldComponentProps { + title?: string; +} + +export function HelloWorldComponent({ title }: HelloWorldComponentProps) { + const viewMode = useSelector>(({ input }) => input.viewMode); + const dispatch = useDispatch(); + + return ( +
+

{title}

+ {viewMode === ViewMode.EDIT && ( + dispatch(actions.input.setTitle(target.value))} + /> + )} +
+ ); +} +``` + +#### Custom Properties +The `createStore` function provides an option to pass a custom reducer in the second argument. +That reducer will be merged with the one the embeddable plugin provides. +That means there is no need to reimplement already existing actions. + +```tsx +import React from 'react'; +import { render } from 'react-dom'; +import { createSlice } from '@reduxjs/toolkit'; +import { + Embeddable, + EmbeddableInput, + EmbeddableOutput, + IEmbeddable +} from '@kbn/embeddable-plugin/public'; +import { createStore, State } from '@kbn/embeddable-plugin/public/store'; + +interface HelloWorldInput extends EmbeddableInput { + greeting?: string; +} + +interface HelloWorldOutput extends EmbeddableOutput { + message?: string; +} + +const input = createSlice({ + name: 'hello-world-input', + initialState: {} as HelloWorldInput, + reducers: { + setGreeting(state, action: PayloadAction) { + state.greeting = action.payload; + }, + }, +}); + +const output = createSlice({ + name: 'hello-world-input', + initialState: {} as HelloWorldOutput, + reducers: { + setMessage(state, action: PayloadAction) { + state.message = action.payload; + }, + }, +}); + +export const actions = { + ...input.actions, + ...output.actions, +}; + +export class HelloWorld extends Embeddable { + readonly store = createStore(this, { + reducer: { + input: input.reducer, + output: output.reducer, + } + }); + + // ... +} +``` + +There is a way to provide a custom reducer that will manipulate the root state: +```typescript +// ... + +import { createAction, createRducer } from '@reduxjs/toolkit'; + +// ... + +const setGreeting = createAction('greeting'); +const setMessage = createAction('message'); +const reducer = createReducer({} as State, (builder) => + builder + .addCase(setGreeting, (state, action) => ({ ...state, input: { ...state.input, greeting: action.payload } })) + .addCase(setMessage, (state, action) => ({ ...state, output: { ...state.output, message: action.payload } })) +); + +export const actions = { + setGreeting, + setMessage, +}; + +export class HelloWorld extends Embeddable { + readonly store = createStore(this, { reducer }); + + // ... +} +``` + +#### Custom State +Sometimes, there is a need to store a custom state next to the embeddable state. +This can be achieved by passing a custom reducer. + +```tsx +import React from 'react'; +import { render } from 'react-dom'; +import { createSlice } from '@reduxjs/toolkit'; +import { Embeddable, IEmbeddable } from '@kbn/embeddable-plugin/public'; +import { createStore, State } from '@kbn/embeddable-plugin/public/store'; + +interface ComponentState { + foo?: string; + bar?: string; +} + +export interface HelloWorldState extends State { + component: ComponentState; +} + +const component = createSlice({ + name: 'hello-world-component', + initialState: {} as ComponentState, + reducers: { + setFoo(state, action: PayloadAction) { + state.foo = action.payload; + }, + setBar(state, action: PayloadAction) { + state.bar = action.payload; + }, + }, +}); + +export const { actions } = component; + +export class HelloWorld extends Embeddable { + readonly store = createStore(this, { + preloadedState: { + component: { + foo: 'bar', + bar: 'foo', + } + }, + reducer: { component: component.reducer } + }); + + // ... +} +``` + +#### Typings +When using the `useSelector` hook, it is convenient to have a `State` type to guarantee type safety and determine types implicitly. + +For the state containing input and output substates only, it is enough to use a utility type `State`: +```typescript +import { useSelector } from 'react-redux'; +import type { State } from '@kbn/embeddable-plugin/public/store'; +import type { Embeddable } from './some_embeddable'; + +// ... +const title = useSelector>((state) => state.input.title); +``` + +For the more complex case, the best way would be to define a state type separately: +```typescript +import { useSelector } from 'react-redux'; +import type { State } from '@kbn/embeddable-plugin/public/store'; +import type { Embeddable } from './some_embeddable'; + +interface EmbeddableState extends State { + foo?: string; + bar?: Bar; +} + +// ... +const foo = useSelector((state) => state.foo); +``` + +#### Advanced Usage +In case when there is a need to enhance the produced store in some way (e.g., perform custom serialization or debugging), it is possible to use [parameters](https://redux-toolkit.js.org/api/configureStore#parameters) supported by the `configureStore` function. + +In case when custom serialization is needed, that should be done using middleware. The embeddable plugin's `createStore` function does not apply any middleware, so all the synchronization job is done outside the store. + ## API Please use automatically generated API reference or generated TypeDoc comments to find the complete documentation. diff --git a/src/plugins/embeddable/public/__stories__/embeddable_panel.stories.tsx b/src/plugins/embeddable/public/__stories__/embeddable_panel.stories.tsx index 1f15b942fb5899..97e8b83b9f7b15 100644 --- a/src/plugins/embeddable/public/__stories__/embeddable_panel.stories.tsx +++ b/src/plugins/embeddable/public/__stories__/embeddable_panel.stories.tsx @@ -25,6 +25,7 @@ import { CoreTheme } from '@kbn/core-theme-browser'; import type { Action } from '@kbn/ui-actions-plugin/public'; import { CONTEXT_MENU_TRIGGER, EmbeddablePanel, PANEL_BADGE_TRIGGER, ViewMode } from '..'; +import { actions } from '../store'; import { HelloWorldEmbeddable } from './hello_world_embeddable'; const layout: DecoratorFn = (story) => { @@ -93,20 +94,16 @@ const HelloWorldEmbeddablePanel = forwardRef< const theme = useContext(ThemeContext) as CoreTheme; useEffect(() => theme$.next(theme), [theme$, theme]); + useEffect(() => { + embeddable.store.dispatch(actions.input.setTitle(title)); + }, [embeddable.store, title]); + useEffect(() => { + embeddable.store.dispatch( + actions.input.setViewMode(viewMode ? ViewMode.VIEW : ViewMode.EDIT) + ); + }, [embeddable.store, viewMode]); useEffect( - () => - embeddable.updateInput({ - title, - viewMode: viewMode ? ViewMode.VIEW : ViewMode.EDIT, - lastReloadRequestTime: new Date().getMilliseconds(), - }), - [embeddable, title, viewMode] - ); - useEffect( - () => - embeddable.updateOutput({ - loading, - }), + () => void embeddable.store.dispatch(actions.output.setLoading(loading)), [embeddable, loading] ); useImperativeHandle(ref, () => ({ embeddable })); @@ -162,7 +159,9 @@ export function DefaultWithBadges({ badges, ...props }: DefaultWithBadgesProps) useEffect( () => - ref.current?.embeddable.updateInput({ lastReloadRequestTime: new Date().getMilliseconds() }), + void ref.current?.embeddable.store.dispatch( + actions.input.setLastReloadRequestTime(new Date().getMilliseconds()) + ), [getActions] ); @@ -207,7 +206,9 @@ export function DefaultWithContextMenu({ items, ...props }: DefaultWithContextMe useEffect( () => - ref.current?.embeddable.updateInput({ lastReloadRequestTime: new Date().getMilliseconds() }), + void ref.current?.embeddable.store.dispatch( + actions.input.setLastReloadRequestTime(new Date().getMilliseconds()) + ), [getActions] ); @@ -230,7 +231,10 @@ interface DefaultWithErrorProps extends HelloWorldEmbeddablePanelProps { export function DefaultWithError({ message, ...props }: DefaultWithErrorProps) { const ref = useRef>(null); - useEffect(() => ref.current?.embeddable.updateOutput({ error: new Error(message) }), [message]); + useEffect( + () => void ref.current?.embeddable.store.dispatch(actions.output.setError(new Error(message))), + [message] + ); return ; } @@ -256,7 +260,10 @@ export function DefaultWithCustomError({ message, ...props }: DefaultWithErrorPr }), [] ); - useEffect(() => ref.current?.embeddable.updateOutput({ error: new Error(message) }), [message]); + useEffect( + () => void ref.current?.embeddable.store.dispatch(actions.output.setError(new Error(message))), + [message] + ); return ; } diff --git a/src/plugins/embeddable/public/__stories__/hello_world_embeddable.tsx b/src/plugins/embeddable/public/__stories__/hello_world_embeddable.tsx index 2ea923704be77c..5cf2c5fdc46e8d 100644 --- a/src/plugins/embeddable/public/__stories__/hello_world_embeddable.tsx +++ b/src/plugins/embeddable/public/__stories__/hello_world_embeddable.tsx @@ -8,10 +8,15 @@ import React from 'react'; import { render } from 'react-dom'; +import { connect, Provider } from 'react-redux'; import { EuiEmptyPrompt } from '@elastic/eui'; import { Embeddable, IEmbeddable } from '..'; +import { createStore, State } from '../store'; export class HelloWorldEmbeddable extends Embeddable { + // eslint-disable-next-line @kbn/eslint/no_this_in_property_initializers + readonly store = createStore(this); + readonly type = 'hello-world'; renderError: IEmbeddable['renderError']; @@ -19,16 +24,17 @@ export class HelloWorldEmbeddable extends Embeddable { reload() {} render(node: HTMLElement) { - render(, node); - - this.reload = this.render.bind(this, node); + const App = connect((state: State) => ({ body: state.input.title }))(EuiEmptyPrompt); + + render( + + + , + node + ); } setErrorRenderer(renderer: IEmbeddable['renderError']) { this.renderError = renderer; } - - updateOutput(...args: Parameters): void { - return super.updateOutput(...args); - } } diff --git a/src/plugins/embeddable/public/lib/embeddables/embeddable.tsx b/src/plugins/embeddable/public/lib/embeddables/embeddable.tsx index 001cb98afa6c13..94025320ec86d7 100644 --- a/src/plugins/embeddable/public/lib/embeddables/embeddable.tsx +++ b/src/plugins/embeddable/public/lib/embeddables/embeddable.tsx @@ -41,8 +41,10 @@ export abstract class Embeddable< protected output: TEmbeddableOutput; protected input: TEmbeddableInput; - private readonly input$: Rx.BehaviorSubject; - private readonly output$: Rx.BehaviorSubject; + private readonly inputSubject = new Rx.ReplaySubject(1); + private readonly outputSubject = new Rx.ReplaySubject(1); + private readonly input$ = this.inputSubject.asObservable(); + private readonly output$ = this.outputSubject.asObservable(); protected renderComplete = new RenderCompleteDispatcher(); @@ -71,8 +73,8 @@ export abstract class Embeddable< }; this.parent = parent; - this.input$ = new Rx.BehaviorSubject(this.input); - this.output$ = new Rx.BehaviorSubject(this.output); + this.inputSubject.next(this.input); + this.outputSubject.next(this.output); if (parent) { this.parentSubscription = Rx.merge(parent.getInput$(), parent.getOutput$()).subscribe(() => { @@ -89,12 +91,7 @@ export abstract class Embeddable< map(({ title }) => title || ''), distinctUntilChanged() ) - .subscribe( - (title) => { - this.renderComplete.setTitle(title); - }, - () => {} - ); + .subscribe((title) => this.renderComplete.setTitle(title)); } public reportsEmbeddableLoad() { @@ -142,11 +139,11 @@ export abstract class Embeddable< } public getInput$(): Readonly> { - return this.input$.asObservable(); + return this.input$; } public getOutput$(): Readonly> { - return this.output$.asObservable(); + return this.output$; } public getOutput(): Readonly { @@ -238,8 +235,8 @@ export abstract class Embeddable< public destroy(): void { this.destroyed = true; - this.input$.complete(); - this.output$.complete(); + this.inputSubject.complete(); + this.outputSubject.complete(); if (this.parentSubscription) { this.parentSubscription.unsubscribe(); @@ -257,20 +254,20 @@ export abstract class Embeddable< } } - protected updateOutput(outputChanges: Partial): void { + public updateOutput(outputChanges: Partial): void { const newOutput = { ...this.output, ...outputChanges, }; if (!fastIsEqual(this.output, newOutput)) { this.output = newOutput; - this.output$.next(this.output); + this.outputSubject.next(this.output); } } protected onFatalError(e: Error) { this.fatalError = e; - this.output$.error(e); + this.outputSubject.error(e); // if the container is waiting for this embeddable to complete loading, // a fatal error counts as complete. if (this.deferEmbeddableLoad && this.parent?.isContainer) { @@ -282,7 +279,7 @@ export abstract class Embeddable< if (!fastIsEqual(this.input, newInput)) { const oldLastReloadRequestTime = this.input.lastReloadRequestTime; this.input = newInput; - this.input$.next(newInput); + this.inputSubject.next(newInput); this.updateOutput({ title: getPanelTitle(this.input, this.output), } as Partial); diff --git a/src/plugins/embeddable/public/lib/embeddables/i_embeddable.ts b/src/plugins/embeddable/public/lib/embeddables/i_embeddable.ts index 9037de1a100759..1c9bdebcefc9b7 100644 --- a/src/plugins/embeddable/public/lib/embeddables/i_embeddable.ts +++ b/src/plugins/embeddable/public/lib/embeddables/i_embeddable.ts @@ -142,6 +142,12 @@ export interface IEmbeddable< */ updateInput(changes: Partial): void; + /** + * Updates output state with the given changes. + * @param changes + */ + updateOutput(changes: Partial): void; + /** * Returns an observable which will be notified when input state changes. */ diff --git a/src/plugins/embeddable/public/store/create_store.test.ts b/src/plugins/embeddable/public/store/create_store.test.ts new file mode 100644 index 00000000000000..52ac1eb32c8dc6 --- /dev/null +++ b/src/plugins/embeddable/public/store/create_store.test.ts @@ -0,0 +1,245 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +// eslint-disable-next-line max-classes-per-file +import { createAction, createReducer, createSlice, PayloadAction } from '@reduxjs/toolkit'; +import type { Store } from 'redux'; +import { + defaultEmbeddableFactoryProvider, + Container, + ContainerInput, + Embeddable, + EmbeddableInput, + EmbeddableOutput, +} from '../lib'; +import { createStore, State } from './create_store'; +import { input } from './input_slice'; +import { output } from './output_slice'; + +interface TestEmbeddableInput extends EmbeddableInput { + custom?: string; +} + +interface TestEmbeddableOutput extends EmbeddableOutput { + custom?: string; +} + +interface TestContainerInput extends ContainerInput { + custom?: string; +} + +class TestEmbeddable extends Embeddable { + type = 'test'; + reload = jest.fn(); + render = jest.fn(); +} + +class TestContainer extends Container, TestContainerInput> { + type = 'test'; + + getInheritedInput() { + return { + custom: this.input.custom, + }; + } +} + +describe('createStore', () => { + let embeddable: TestEmbeddable; + let store: Store>; + + beforeEach(() => { + embeddable = new TestEmbeddable({ id: '12345' }, { title: 'Test' }); + store = createStore(embeddable); + }); + + it('should populate the state with the embeddable input', () => { + expect(store.getState()).toHaveProperty('input', expect.objectContaining({ id: '12345' })); + }); + + it('should populate the state with the embeddable output', () => { + expect(store.getState()).toHaveProperty('output', expect.objectContaining({ title: 'Test' })); + }); + + it('should update the embeddable input on action dispatch', () => { + store.dispatch(input.actions.setTitle('Something')); + + expect(store.getState()).toHaveProperty('input.title', 'Something'); + }); + + it('should update the embeddable output on action dispatch', () => { + store.dispatch(output.actions.setTitle('Something')); + + expect(store.getState()).toHaveProperty('output.title', 'Something'); + }); + + it('should group input updates on multiple dispatch calls', async () => { + jest.spyOn(embeddable, 'updateInput'); + store.dispatch(input.actions.setTitle('Something')); + store.dispatch(input.actions.setHidePanelTitles(true)); + await new Promise((resolve) => setTimeout(resolve)); + + expect(embeddable.updateInput).toHaveBeenCalledTimes(1); + expect(embeddable.updateInput).nthCalledWith( + 1, + expect.objectContaining({ title: 'Something', hidePanelTitles: true }) + ); + }); + + it('should group output updates on multiple dispatch calls', async () => { + jest.spyOn(embeddable, 'updateOutput'); + store.dispatch(output.actions.setTitle('Something')); + store.dispatch(output.actions.setLoading(true)); + await new Promise((resolve) => setTimeout(resolve)); + + expect(embeddable.updateOutput).toHaveBeenCalledTimes(1); + expect(embeddable.updateOutput).nthCalledWith( + 1, + expect.objectContaining({ title: 'Something', loading: true }) + ); + }); + + it('should not update input on output changes', async () => { + jest.spyOn(embeddable, 'updateInput'); + store.dispatch(output.actions.setTitle('Something')); + await new Promise((resolve) => setTimeout(resolve)); + + expect(embeddable.updateInput).not.toHaveBeenCalled(); + }); + + it('should sync input changes', () => { + jest.spyOn(embeddable, 'updateInput'); + embeddable.updateInput({ title: 'Something' }); + + expect(embeddable.updateInput).toHaveBeenCalledTimes(1); + expect(store.getState()).toHaveProperty('input.title', 'Something'); + }); + + it('should sync output changes', () => { + jest.spyOn(embeddable, 'updateOutput'); + embeddable.updateOutput({ title: 'Something' }); + + expect(embeddable.updateOutput).toHaveBeenCalledTimes(1); + expect(store.getState()).toHaveProperty('output.title', 'Something'); + }); + + it('should provide a way to use a custom reducer', async () => { + const setCustom = createAction('custom'); + const customStore = createStore(embeddable, { + reducer: { + input: createReducer({} as TestEmbeddableInput, (builder) => + builder.addCase(setCustom, (state, action) => ({ ...state, custom: action.payload })) + ), + }, + }); + + jest.spyOn(embeddable, 'updateInput'); + customStore.dispatch(input.actions.setTitle('Something')); + customStore.dispatch(setCustom('Something else')); + await new Promise((resolve) => setTimeout(resolve)); + + expect(embeddable.updateInput).toHaveBeenCalledWith( + expect.objectContaining({ custom: 'Something else', title: 'Something' }) + ); + }); + + it('should provide a way to use a custom slice', async () => { + const slice = createSlice({ + name: 'test', + initialState: {} as State, + reducers: { + setCustom(state, action: PayloadAction) { + state.input.custom = action.payload; + state.output.custom = action.payload; + }, + }, + }); + const customStore = createStore(embeddable, { reducer: slice.reducer }); + + jest.spyOn(embeddable, 'updateInput'); + jest.spyOn(embeddable, 'updateOutput'); + customStore.dispatch(input.actions.setTitle('Something')); + customStore.dispatch(slice.actions.setCustom('Something else')); + await new Promise((resolve) => setTimeout(resolve)); + + expect(embeddable.updateInput).toHaveBeenCalledWith( + expect.objectContaining({ custom: 'Something else', title: 'Something' }) + ); + expect(embeddable.updateOutput).toHaveBeenCalledWith( + expect.objectContaining({ custom: 'Something else' }) + ); + }); + + describe('of a nested embeddable', () => { + const factory = defaultEmbeddableFactoryProvider< + TestEmbeddableInput, + TestEmbeddableOutput, + TestEmbeddable + >({ + type: 'test', + getDisplayName: () => 'Test', + isEditable: async () => true, + create: async (data, parent) => new TestEmbeddable(data, {}, parent), + }); + const getFactory = jest.fn().mockReturnValue(factory); + + let container: TestContainer; + + beforeEach(async () => { + container = new TestContainer( + { custom: 'something', id: 'id', panels: {} }, + { embeddableLoaded: {} }, + getFactory + ); + embeddable = (await container.addNewEmbeddable('test', { id: '12345' })) as TestEmbeddable; + store = createStore(embeddable); + }); + + it('should populate inherited input', () => { + expect(store.getState()).toHaveProperty('input.custom', 'something'); + }); + + it('should override inherited input on dispatch', async () => { + store.dispatch( + input.actions.update({ custom: 'something else' } as Partial) + ); + await new Promise((resolve) => setTimeout(resolve)); + + expect(store.getState()).toHaveProperty('input.custom', 'something else'); + expect(container.getInput()).toHaveProperty( + 'input.custom', + expect.not.stringMatching('something else') + ); + }); + + it('should restore value from the inherited input', async () => { + store.dispatch( + input.actions.update({ custom: 'something else' } as Partial) + ); + await new Promise((resolve) => setTimeout(resolve)); + store.dispatch(input.actions.update({ custom: undefined } as Partial)); + await new Promise((resolve) => setTimeout(resolve)); + + expect(store.getState()).toHaveProperty('input.custom', 'something'); + }); + + it('should not override inherited input on dispatch', async () => { + store.dispatch(input.actions.setTitle('Something')); + await new Promise((resolve) => setTimeout(resolve)); + container.updateInput({ custom: 'something else' }); + + expect(store.getState()).toHaveProperty( + 'input', + expect.objectContaining({ + title: 'Something', + custom: 'something else', + }) + ); + }); + }); +}); diff --git a/src/plugins/embeddable/public/store/create_store.ts b/src/plugins/embeddable/public/store/create_store.ts new file mode 100644 index 00000000000000..135f793c079ddd --- /dev/null +++ b/src/plugins/embeddable/public/store/create_store.ts @@ -0,0 +1,132 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { chain, isEmpty, keys } from 'lodash'; +import { combineReducers, Reducer, Store, ReducersMapObject } from 'redux'; +import { configureStore, ConfigureStoreOptions } from '@reduxjs/toolkit'; +import { + debounceTime, + distinctUntilChanged, + filter, + last, + map, + pluck, + share, + takeUntil, + Observable, +} from 'rxjs'; +import reduceReducers from 'reduce-reducers'; +import type { Optional } from 'utility-types'; +import type { IEmbeddable } from '../lib'; +import { input } from './input_slice'; +import { output } from './output_slice'; + +export interface State { + input: E extends IEmbeddable ? I : never; + output: E extends IEmbeddable ? O : never; +} + +export interface CreateStoreOptions + extends Omit, 'reducer'> { + reducer?: Reducer | Optional, keyof State>; +} + +function createReducer( + reducer?: CreateStoreOptions['reducer'] +): Reducer | ReducersMapObject { + if (reducer instanceof Function) { + const generic = combineReducers>({ + input: input.reducer, + output: output.reducer, + }) as Reducer; + + return reduceReducers(generic, reducer) as Reducer; + } + + return { + ...(reducer ?? {}), + input: reducer?.input ? reduceReducers(input.reducer, reducer.input) : input.reducer, + output: reducer?.output ? reduceReducers(output.reducer, reducer.output) : output.reducer, + } as ReducersMapObject; +} + +function diff>(previous: T, current: T) { + return chain(current) + .keys() + .concat(keys(previous)) + .uniq() + .filter((key) => previous[key] !== current[key]) + .map((key) => [key, current[key]]) + .fromPairs() + .value() as Partial; +} + +/** + * Creates a Redux store for the given embeddable. + * @param embeddable The embeddable instance. + * @param options The custom options to pass to the `configureStore` call. + * @returns The Redux store. + */ +export function createStore = State>( + embeddable: E, + { preloadedState, reducer, ...options }: CreateStoreOptions = {} +): Store { + const store = configureStore({ + ...options, + preloadedState: { + input: embeddable.getInput(), + output: embeddable.getOutput(), + ...(preloadedState ?? {}), + } as NonNullable, + reducer: createReducer(reducer), + }); + + const state$ = new Observable((subscriber) => { + subscriber.add(store.subscribe(() => subscriber.next(store.getState()))); + }).pipe(share()); + const input$ = embeddable.getInput$(); + const output$ = embeddable.getOutput$(); + + state$ + .pipe( + takeUntil(input$.pipe(last())), + pluck('input'), + distinctUntilChanged(), + map((value) => diff(embeddable.getInput(), value)), + filter((patch) => !isEmpty(patch)), + debounceTime(0) + ) + .subscribe((patch) => embeddable.updateInput(patch)); + + state$ + .pipe( + takeUntil(output$.pipe(last())), + pluck('output'), + distinctUntilChanged(), + map((value) => diff(embeddable.getOutput(), value)), + filter((patch) => !isEmpty(patch)), + debounceTime(0) + ) + .subscribe((patch) => embeddable.updateOutput(patch)); + + input$ + .pipe( + map((value) => diff(store.getState().input, value)), + filter((patch) => !isEmpty(patch)) + ) + .subscribe((patch) => store.dispatch(input.actions.update(patch))); + + output$ + .pipe( + map((value) => diff(store.getState().output, value)), + filter((patch) => !isEmpty(patch)) + ) + .subscribe((patch) => store.dispatch(output.actions.update(patch))); + + return store; +} diff --git a/src/plugins/controls/public/control_types/range_slider/range_slider.component.tsx b/src/plugins/embeddable/public/store/index.ts similarity index 57% rename from src/plugins/controls/public/control_types/range_slider/range_slider.component.tsx rename to src/plugins/embeddable/public/store/index.ts index ca9c1e4b2dd0c3..05567e02155895 100644 --- a/src/plugins/controls/public/control_types/range_slider/range_slider.component.tsx +++ b/src/plugins/embeddable/public/store/index.ts @@ -6,12 +6,12 @@ * Side Public License, v 1. */ -import React from 'react'; +import { input } from './input_slice'; +import { output } from './output_slice'; -import { RangeSliderPopover } from './range_slider_popover'; - -import './range_slider.scss'; - -export const RangeSliderComponent = () => { - return ; +export type { CreateStoreOptions, State } from './create_store'; +export { createStore } from './create_store'; +export const actions = { + input: input.actions, + output: output.actions, }; diff --git a/src/plugins/embeddable/public/store/input_slice.ts b/src/plugins/embeddable/public/store/input_slice.ts new file mode 100644 index 00000000000000..da4bc6618ae111 --- /dev/null +++ b/src/plugins/embeddable/public/store/input_slice.ts @@ -0,0 +1,56 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { createSlice, PayloadAction } from '@reduxjs/toolkit'; +import type { EmbeddableInput } from '../lib'; + +export const input = createSlice({ + name: 'input', + initialState: {} as EmbeddableInput, + reducers: { + setDisabledActions(state, action: PayloadAction) { + state.disabledActions = action.payload; + }, + setDisableTriggers(state, action: PayloadAction) { + state.disableTriggers = action.payload; + }, + setEnhancements(state, action: PayloadAction) { + state.enhancements = action.payload; + }, + setExecutionContext(state, action: PayloadAction) { + state.executionContext = action.payload; + }, + setHidePanelTitles(state, action: PayloadAction) { + state.hidePanelTitles = action.payload; + }, + setLastReloadRequestTime( + state, + action: PayloadAction + ) { + state.lastReloadRequestTime = action.payload; + }, + setSearchSessionId(state, action: PayloadAction) { + state.searchSessionId = action.payload; + }, + setSyncColors(state, action: PayloadAction) { + state.syncColors = action.payload; + }, + setSyncTooltips(state, action: PayloadAction) { + state.syncTooltips = action.payload; + }, + setTitle(state, action: PayloadAction) { + state.title = action.payload; + }, + setViewMode(state, action: PayloadAction) { + state.viewMode = action.payload; + }, + update(state, action: PayloadAction>) { + return { ...state, ...action.payload }; + }, + }, +}); diff --git a/src/plugins/embeddable/public/store/output_slice.ts b/src/plugins/embeddable/public/store/output_slice.ts new file mode 100644 index 00000000000000..c3cbaf68758936 --- /dev/null +++ b/src/plugins/embeddable/public/store/output_slice.ts @@ -0,0 +1,50 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { createSlice, PayloadAction } from '@reduxjs/toolkit'; +import type { EmbeddableOutput } from '../lib'; + +export const output = createSlice({ + name: 'output', + initialState: {} as EmbeddableOutput, + reducers: { + setLoading(state, action: PayloadAction) { + state.loading = action.payload; + }, + setRendered(state, action: PayloadAction) { + state.rendered = action.payload; + }, + setError(state, action: PayloadAction) { + state.error = action.payload; + }, + setEditUrl(state, action: PayloadAction) { + state.editUrl = action.payload; + }, + setEditApp(state, action: PayloadAction) { + state.editApp = action.payload; + }, + setEditPath(state, action: PayloadAction) { + state.editPath = action.payload; + }, + setDefaultTitle(state, action: PayloadAction) { + state.defaultTitle = action.payload; + }, + setTitle(state, action: PayloadAction) { + state.title = action.payload; + }, + setEditable(state, action: PayloadAction) { + state.editable = action.payload; + }, + setSavedObjectId(state, action: PayloadAction) { + state.savedObjectId = action.payload; + }, + update(state, action: PayloadAction>) { + return { ...state, ...action.payload }; + }, + }, +}); diff --git a/src/plugins/es_ui_shared/static/forms/hook_form_lib/hooks/use_form.ts b/src/plugins/es_ui_shared/static/forms/hook_form_lib/hooks/use_form.ts index b6b45c76e7115f..95ed985bf1a2fc 100644 --- a/src/plugins/es_ui_shared/static/forms/hook_form_lib/hooks/use_form.ts +++ b/src/plugins/es_ui_shared/static/forms/hook_form_lib/hooks/use_form.ts @@ -8,7 +8,7 @@ import { useState, useRef, useEffect, useMemo, useCallback } from 'react'; import { get, mergeWith } from 'lodash'; -import { set } from '@elastic/safer-lodash-set'; +import { set } from '@kbn/safer-lodash-set'; import { FormHook, FieldHook, FormData, FieldsMap, FormConfig } from '../types'; import { diff --git a/src/plugins/es_ui_shared/static/forms/hook_form_lib/lib/utils.ts b/src/plugins/es_ui_shared/static/forms/hook_form_lib/lib/utils.ts index 54f6726abb1159..fe41de2947795d 100644 --- a/src/plugins/es_ui_shared/static/forms/hook_form_lib/lib/utils.ts +++ b/src/plugins/es_ui_shared/static/forms/hook_form_lib/lib/utils.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import { set } from '@elastic/safer-lodash-set'; +import { set } from '@kbn/safer-lodash-set'; import { FieldHook } from '../types'; interface GenericObject { diff --git a/src/plugins/home/public/application/components/guided_onboarding/getting_started.tsx b/src/plugins/home/public/application/components/guided_onboarding/getting_started.tsx index b5415064eea179..9f27a0194a3ca8 100644 --- a/src/plugins/home/public/application/components/guided_onboarding/getting_started.tsx +++ b/src/plugins/home/public/application/components/guided_onboarding/getting_started.tsx @@ -21,7 +21,7 @@ import { import { css } from '@emotion/react'; import { METRIC_TYPE } from '@kbn/analytics'; import { i18n } from '@kbn/i18n'; -import { KibanaPageTemplate } from '@kbn/shared-ux-components'; +import { KibanaPageTemplate } from '@kbn/shared-ux-page-kibana-template'; import { getServices } from '../../kibana_services'; import { KEY_ENABLE_WELCOME } from '../home'; diff --git a/src/plugins/interactive_setup/public/use_form.ts b/src/plugins/interactive_setup/public/use_form.ts index abd00edee6750b..47768400dd7755 100644 --- a/src/plugins/interactive_setup/public/use_form.ts +++ b/src/plugins/interactive_setup/public/use_form.ts @@ -6,12 +6,13 @@ * Side Public License, v 1. */ -import { set } from '@elastic/safer-lodash-set'; import { cloneDeep, cloneDeepWith, get } from 'lodash'; import type { ChangeEventHandler, FocusEventHandler, ReactEventHandler } from 'react'; import { useState } from 'react'; import useAsyncFn from 'react-use/lib/useAsyncFn'; +import { set } from '@kbn/safer-lodash-set'; + export type FormReturnTuple = [FormState, FormProps]; export interface FormProps { diff --git a/src/plugins/kibana_overview/public/components/overview/overview.test.tsx b/src/plugins/kibana_overview/public/components/overview/overview.test.tsx index 99d8b45cdf27b8..0fbedc5c3367e8 100644 --- a/src/plugins/kibana_overview/public/components/overview/overview.test.tsx +++ b/src/plugins/kibana_overview/public/components/overview/overview.test.tsx @@ -13,16 +13,16 @@ import { act } from 'react-dom/test-utils'; import { ReactWrapper } from 'enzyme'; import { EuiLoadingSpinner } from '@elastic/eui'; import { mountWithIntl } from '@kbn/test-jest-helpers'; -import { KibanaPageTemplate } from '@kbn/shared-ux-components'; +import { KibanaPageTemplate } from '@kbn/shared-ux-page-kibana-template'; import type { FeatureCatalogueCategory } from '@kbn/home-plugin/public'; import { AnalyticsNoDataPageKibanaProvider } from '@kbn/shared-ux-page-analytics-no-data'; import { hasESData, hasUserDataView } from './overview.test.mocks'; import { Overview } from './overview'; -jest.mock('@kbn/shared-ux-components', () => { +jest.mock('@kbn/shared-ux-page-kibana-template', () => { const MockedComponent: string = 'MockedKibanaPageTemplate'; const mockedModule = { - ...jest.requireActual('@kbn/shared-ux-components'), + ...jest.requireActual('@kbn/shared-ux-page-kibana-template'), KibanaPageTemplate: () => { return ; }, diff --git a/src/plugins/kibana_overview/public/components/overview/overview.tsx b/src/plugins/kibana_overview/public/components/overview/overview.tsx index 738b278b17b36b..245fcb12c7afdd 100644 --- a/src/plugins/kibana_overview/public/components/overview/overview.tsx +++ b/src/plugins/kibana_overview/public/components/overview/overview.tsx @@ -25,7 +25,7 @@ import { overviewPageActions, OverviewPageFooter, } from '@kbn/kibana-react-plugin/public'; -import { KibanaPageTemplate } from '@kbn/shared-ux-components'; +import { KibanaPageTemplate } from '@kbn/shared-ux-page-kibana-template'; import { KibanaSolutionAvatar } from '@kbn/shared-ux-avatar-solution'; import { AnalyticsNoDataPageKibanaProvider, diff --git a/src/plugins/kibana_react/public/app_links/index.ts b/src/plugins/kibana_react/public/app_links/index.ts index ca09b2a3bfe368..3bfd7baca0c024 100644 --- a/src/plugins/kibana_react/public/app_links/index.ts +++ b/src/plugins/kibana_react/public/app_links/index.ts @@ -5,5 +5,5 @@ * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ -/** @deprecated Use `RedirectAppLinks` from `@kbn/shared-ux-components */ +/** @deprecated Use `RedirectAppLinks` from `@kbn/shared-ux-link-redirect-app` */ export { RedirectAppLinks } from './redirect_app_link'; diff --git a/src/plugins/kibana_react/public/app_links/redirect_app_link.test.tsx b/src/plugins/kibana_react/public/app_links/redirect_app_link.test.tsx index 133cab06e6b6fc..f4ce0d3ff80d30 100644 --- a/src/plugins/kibana_react/public/app_links/redirect_app_link.test.tsx +++ b/src/plugins/kibana_react/public/app_links/redirect_app_link.test.tsx @@ -9,7 +9,7 @@ import React, { MouseEvent } from 'react'; import { mount } from 'enzyme'; import { applicationServiceMock } from '@kbn/core/public/mocks'; -/** @deprecated Use `RedirectAppLinks` from `@kbn/shared-ux-components */ +/** @deprecated Use `RedirectAppLinks` from `@kbn/shared-ux-link-redirect-app` */ import { RedirectAppLinks } from './redirect_app_link'; import { BehaviorSubject } from 'rxjs'; diff --git a/src/plugins/kibana_react/public/app_links/redirect_app_link.tsx b/src/plugins/kibana_react/public/app_links/redirect_app_link.tsx index 339055c3e1da51..6df1c43dbc5c6a 100644 --- a/src/plugins/kibana_react/public/app_links/redirect_app_link.tsx +++ b/src/plugins/kibana_react/public/app_links/redirect_app_link.tsx @@ -35,7 +35,7 @@ interface RedirectCrossAppLinksProps extends React.HTMLAttributes = ({ diff --git a/src/plugins/kibana_react/public/code_editor/__snapshots__/code_editor.test.tsx.snap b/src/plugins/kibana_react/public/code_editor/__snapshots__/code_editor.test.tsx.snap index 9a4511f8b03f5f..6d077e6e174e54 100644 --- a/src/plugins/kibana_react/public/code_editor/__snapshots__/code_editor.test.tsx.snap +++ b/src/plugins/kibana_react/public/code_editor/__snapshots__/code_editor.test.tsx.snap @@ -226,21 +226,6 @@ exports[` is rendered 1`] = `
- - -
- -
`; diff --git a/src/plugins/kibana_react/public/code_editor/code_editor.test.tsx b/src/plugins/kibana_react/public/code_editor/code_editor.test.tsx index b66d136c507100..97a8d8a8490837 100644 --- a/src/plugins/kibana_react/public/code_editor/code_editor.test.tsx +++ b/src/plugins/kibana_react/public/code_editor/code_editor.test.tsx @@ -43,7 +43,15 @@ const logs = ` [Sun Mar 7 21:16:17 2004] [error] [client xx.xx.xx.xx] File does not exist: /home/httpd/twiki/view/Main/WebHome `; +class ResizeObserver { + observe() {} + unobserve() {} + disconnect() {} +} + describe('', () => { + window.ResizeObserver = ResizeObserver; + test('is rendered', () => { const component = mountWithIntl( {}} /> diff --git a/src/plugins/kibana_react/public/code_editor/code_editor.tsx b/src/plugins/kibana_react/public/code_editor/code_editor.tsx index 239208e6752fce..93a2c6333f9cc7 100644 --- a/src/plugins/kibana_react/public/code_editor/code_editor.tsx +++ b/src/plugins/kibana_react/public/code_editor/code_editor.tsx @@ -7,7 +7,7 @@ */ import React, { useState, useRef, useCallback, useMemo, useEffect, KeyboardEvent } from 'react'; -import ReactResizeDetector from 'react-resize-detector'; +import { useResizeDetector } from 'react-resize-detector'; import ReactMonacoEditor from 'react-monaco-editor'; import { htmlIdGenerator, @@ -186,6 +186,13 @@ export const CodeEditor: React.FC = ({ _editor.current?.layout(); }, []); + useResizeDetector({ + handleWidth: true, + handleHeight: true, + onResize: _updateDimensions, + refreshMode: 'debounce', + }); + const startEditing = useCallback(() => { setIsHintActive(false); _editor.current?.focus(); @@ -469,12 +476,6 @@ export const CodeEditor: React.FC = ({ }} /> - ); }; diff --git a/src/plugins/kibana_react/public/exit_full_screen_button/exit_full_screen_button.tsx b/src/plugins/kibana_react/public/exit_full_screen_button/exit_full_screen_button.tsx index 33871742acbb31..f611c391a20a22 100644 --- a/src/plugins/kibana_react/public/exit_full_screen_button/exit_full_screen_button.tsx +++ b/src/plugins/kibana_react/public/exit_full_screen_button/exit_full_screen_button.tsx @@ -101,5 +101,5 @@ class ExitFullScreenButtonUi extends PureComponent { } } -/** @deprecated Use `ExitFullScreenButton` from `src/plugins/shared_ux/public`. */ +/** @deprecated Use `ExitFullScreenButton` from `@kbn/shared-ux-button-exit-full-screen`. */ export const ExitFullScreenButton = ExitFullScreenButtonUi; diff --git a/src/plugins/kibana_react/public/index.ts b/src/plugins/kibana_react/public/index.ts index 4b4c0b6e5ab203..2244d3d5503e04 100644 --- a/src/plugins/kibana_react/public/index.ts +++ b/src/plugins/kibana_react/public/index.ts @@ -82,7 +82,7 @@ export { reactToUiComponent, uiToReactComponent } from './adapters'; export { toMountPoint, MountPointPortal } from './util'; export type { ToMountPointOptions } from './util'; -/** @deprecated Use `RedirectAppLinks` from `@kbn/shared-ux-components */ +/** @deprecated Use `RedirectAppLinks` from `@kbn/shared-ux-link-redirect-app` */ export { RedirectAppLinks } from './app_links'; export { wrapWithTheme, KibanaThemeProvider } from './theme'; diff --git a/src/plugins/kibana_react/public/markdown/markdown_simple.tsx b/src/plugins/kibana_react/public/markdown/markdown_simple.tsx index 23a00fdec038b1..24b9eee7b1ca5d 100644 --- a/src/plugins/kibana_react/public/markdown/markdown_simple.tsx +++ b/src/plugins/kibana_react/public/markdown/markdown_simple.tsx @@ -6,20 +6,16 @@ * Side Public License, v 1. */ -import React, { Fragment } from 'react'; +import React from 'react'; import ReactMarkdown from 'react-markdown'; -const markdownRenderers = { - root: Fragment, -}; - export interface MarkdownSimpleProps { children: string; } // Render markdown string into JSX inside of a Fragment. export const MarkdownSimple = ({ children }: MarkdownSimpleProps) => ( - {children} + {children} ); // Needed for React.lazy diff --git a/src/plugins/kibana_react/public/page_template/page_template.tsx b/src/plugins/kibana_react/public/page_template/page_template.tsx index bd5213c9a26086..44edccd8ea49b1 100644 --- a/src/plugins/kibana_react/public/page_template/page_template.tsx +++ b/src/plugins/kibana_react/public/page_template/page_template.tsx @@ -21,7 +21,7 @@ import { KibanaPageTemplateInner, KibanaPageTemplateWithSolutionNav } from './pa /** * A thin wrapper around EuiPageTemplate with a few Kibana specific additions - * @deprecated Use `KibanaPageTemplateProps` from `kbn-shared-ux-components`. + * @deprecated Use `KibanaPageTemplateProps` from `@kbn/shared-ux-page-kibana-template-types`. */ export type KibanaPageTemplateProps = EuiPageTemplateProps & { /** @@ -42,7 +42,7 @@ export type KibanaPageTemplateProps = EuiPageTemplateProps & { noDataConfig?: NoDataPageProps; }; -/** @deprecated Use `KibanaPageTemplate` from `kbn-shared-ux-components`. */ +/** @deprecated Use `KibanaPageTemplate` from `@kbn/shared-ux-page-kibana-template`. */ export const KibanaPageTemplate: FunctionComponent = ({ template, className, diff --git a/src/plugins/kibana_usage_collection/server/collectors/management/schema.ts b/src/plugins/kibana_usage_collection/server/collectors/management/schema.ts index f1b230b72c3377..97431c638273da 100644 --- a/src/plugins/kibana_usage_collection/server/collectors/management/schema.ts +++ b/src/plugins/kibana_usage_collection/server/collectors/management/schema.ts @@ -430,10 +430,6 @@ export const stackManagementSchema: MakeSchemaFrom = { type: 'boolean', _meta: { description: 'Non-default value of setting.' }, }, - 'observability:enableInfrastructureView': { - type: 'boolean', - _meta: { description: 'Non-default value of setting.' }, - }, 'observability:enableServiceGroups': { type: 'boolean', _meta: { description: 'Non-default value of setting.' }, diff --git a/src/plugins/kibana_usage_collection/server/collectors/management/types.ts b/src/plugins/kibana_usage_collection/server/collectors/management/types.ts index 1a946e99f29bd0..1b7a64d0cc5902 100644 --- a/src/plugins/kibana_usage_collection/server/collectors/management/types.ts +++ b/src/plugins/kibana_usage_collection/server/collectors/management/types.ts @@ -41,7 +41,6 @@ export interface UsageStats { 'observability:enableNewSyntheticsView': boolean; 'observability:maxSuggestions': number; 'observability:enableComparisonByDefault': boolean; - 'observability:enableInfrastructureView': boolean; 'observability:enableServiceGroups': boolean; 'visualize:enableLabs': boolean; 'visualization:heatmap:maxBuckets': number; diff --git a/src/plugins/kibana_utils/public/history/redirect_when_missing.tsx b/src/plugins/kibana_utils/public/history/redirect_when_missing.tsx index b5e81707a7a798..452ef498815789 100644 --- a/src/plugins/kibana_utils/public/history/redirect_when_missing.tsx +++ b/src/plugins/kibana_utils/public/history/redirect_when_missing.tsx @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import React, { Fragment } from 'react'; +import React from 'react'; import { History } from 'history'; import { i18n } from '@kbn/i18n'; import { EuiLoadingSpinner } from '@elastic/eui'; @@ -20,7 +20,7 @@ import { KibanaThemeProvider } from '../theme'; const ReactMarkdown = React.lazy(() => import('react-markdown')); const ErrorRenderer = (props: { children: string }) => ( }> - + ); diff --git a/src/plugins/presentation_util/public/components/solution_toolbar/index.ts b/src/plugins/presentation_util/public/components/solution_toolbar/index.ts index 5828abda1107f3..ee60678af5d872 100644 --- a/src/plugins/presentation_util/public/components/solution_toolbar/index.ts +++ b/src/plugins/presentation_util/public/components/solution_toolbar/index.ts @@ -7,5 +7,5 @@ */ export { SolutionToolbar } from './solution_toolbar'; -/** @deprecated QuickButtonGroup - use `IconButtonGroup` from `@kbn/shared-ux-components */ +/** @deprecated QuickButtonGroup - use `IconButtonGroup` from `@kbn/shared-ux-button-toolbar` */ export * from './items'; diff --git a/src/plugins/saved_search/public/services/saved_searches/get_saved_searches.test.ts b/src/plugins/saved_search/public/services/saved_searches/get_saved_searches.test.ts index 8ff4f6c1e9428e..397f3c11990ebb 100644 --- a/src/plugins/saved_search/public/services/saved_searches/get_saved_searches.test.ts +++ b/src/plugins/saved_search/public/services/saved_searches/get_saved_searches.test.ts @@ -105,6 +105,7 @@ describe('getSavedSearch', () => { "hideChart": false, "id": "ccf1af80-2297-11ec-86e0-1155ffb9c7a7", "isTextBasedQuery": undefined, + "refreshInterval": undefined, "rowHeight": undefined, "rowsPerPage": undefined, "searchSource": Object { @@ -145,6 +146,8 @@ describe('getSavedSearch', () => { "desc", ], ], + "timeRange": undefined, + "timeRestore": undefined, "title": "test1", "viewMode": undefined, } @@ -198,6 +201,7 @@ describe('getSavedSearch', () => { "hideChart": true, "id": "ccf1af80-2297-11ec-86e0-1155ffb9c7a7", "isTextBasedQuery": true, + "refreshInterval": undefined, "rowHeight": undefined, "rowsPerPage": undefined, "searchSource": Object { @@ -238,6 +242,8 @@ describe('getSavedSearch', () => { "desc", ], ], + "timeRange": undefined, + "timeRestore": undefined, "title": "test2", "viewMode": undefined, } diff --git a/src/plugins/saved_search/public/services/saved_searches/save_saved_searches.test.ts b/src/plugins/saved_search/public/services/saved_searches/save_saved_searches.test.ts index 0c88b2bcea94af..56b988b20121ca 100644 --- a/src/plugins/saved_search/public/services/saved_searches/save_saved_searches.test.ts +++ b/src/plugins/saved_search/public/services/saved_searches/save_saved_searches.test.ts @@ -92,6 +92,7 @@ describe('saveSavedSearch', () => { kibanaSavedObjectMeta: { searchSourceJSON: '{}' }, sort: [], title: 'title', + timeRestore: false, }, { references: [] } ); @@ -112,6 +113,7 @@ describe('saveSavedSearch', () => { kibanaSavedObjectMeta: { searchSourceJSON: '{}' }, sort: [], title: 'title', + timeRestore: false, }, { references: [] } ); diff --git a/src/plugins/saved_search/public/services/saved_searches/saved_searches_utils.test.ts b/src/plugins/saved_search/public/services/saved_searches/saved_searches_utils.test.ts index 84a6c35de0c02d..a6926aef507968 100644 --- a/src/plugins/saved_search/public/services/saved_searches/saved_searches_utils.test.ts +++ b/src/plugins/saved_search/public/services/saved_searches/saved_searches_utils.test.ts @@ -43,6 +43,7 @@ describe('saved_searches_utils', () => { "hideChart": true, "id": "id", "isTextBasedQuery": false, + "refreshInterval": undefined, "rowHeight": undefined, "rowsPerPage": undefined, "searchSource": SearchSource { @@ -66,6 +67,8 @@ describe('saved_searches_utils', () => { }, "sharingSavedObjectProps": Object {}, "sort": Array [], + "timeRange": undefined, + "timeRestore": undefined, "title": "saved search", "viewMode": undefined, } @@ -123,6 +126,7 @@ describe('saved_searches_utils', () => { "kibanaSavedObjectMeta": Object { "searchSourceJSON": "{}", }, + "refreshInterval": undefined, "rowHeight": undefined, "rowsPerPage": undefined, "sort": Array [ @@ -131,6 +135,8 @@ describe('saved_searches_utils', () => { "asc", ], ], + "timeRange": undefined, + "timeRestore": false, "title": "title", "viewMode": undefined, } diff --git a/src/plugins/saved_search/public/services/saved_searches/saved_searches_utils.ts b/src/plugins/saved_search/public/services/saved_searches/saved_searches_utils.ts index cb20b242879430..52c25783c0e504 100644 --- a/src/plugins/saved_search/public/services/saved_searches/saved_searches_utils.ts +++ b/src/plugins/saved_search/public/services/saved_searches/saved_searches_utils.ts @@ -43,6 +43,9 @@ export const fromSavedSearchAttributes = ( hideAggregatedPreview: attributes.hideAggregatedPreview, rowHeight: attributes.rowHeight, isTextBasedQuery: attributes.isTextBasedQuery, + timeRestore: attributes.timeRestore, + timeRange: attributes.timeRange, + refreshInterval: attributes.refreshInterval, rowsPerPage: attributes.rowsPerPage, }); @@ -61,5 +64,8 @@ export const toSavedSearchAttributes = ( hideAggregatedPreview: savedSearch.hideAggregatedPreview, rowHeight: savedSearch.rowHeight, isTextBasedQuery: savedSearch.isTextBasedQuery ?? false, + timeRestore: savedSearch.timeRestore ?? false, + timeRange: savedSearch.timeRange, + refreshInterval: savedSearch.refreshInterval, rowsPerPage: savedSearch.rowsPerPage, }); diff --git a/src/plugins/saved_search/public/services/saved_searches/types.ts b/src/plugins/saved_search/public/services/saved_searches/types.ts index e0c1e8be4a3ed7..acd745374e265d 100644 --- a/src/plugins/saved_search/public/services/saved_searches/types.ts +++ b/src/plugins/saved_search/public/services/saved_searches/types.ts @@ -7,7 +7,7 @@ */ import type { ResolvedSimpleSavedObject } from '@kbn/core/public'; -import type { ISearchSource } from '@kbn/data-plugin/public'; +import type { ISearchSource, RefreshInterval, TimeRange } from '@kbn/data-plugin/common'; export enum VIEW_MODE { DOCUMENT_LEVEL = 'documents', @@ -39,6 +39,11 @@ export interface SavedSearchAttributes { viewMode?: VIEW_MODE; hideAggregatedPreview?: boolean; rowHeight?: number; + + timeRestore?: boolean; + timeRange?: TimeRange; + refreshInterval?: RefreshInterval; + rowsPerPage?: number; } @@ -67,5 +72,11 @@ export interface SavedSearch { hideAggregatedPreview?: boolean; rowHeight?: number; isTextBasedQuery?: boolean; + + // for restoring time range with a saved search + timeRestore?: boolean; + timeRange?: TimeRange; + refreshInterval?: RefreshInterval; + rowsPerPage?: number; } diff --git a/src/plugins/saved_search/server/saved_objects/search.ts b/src/plugins/saved_search/server/saved_objects/search.ts index 85f6542f6b07d8..dec1c852aee20f 100644 --- a/src/plugins/saved_search/server/saved_objects/search.ts +++ b/src/plugins/saved_search/server/saved_objects/search.ts @@ -51,6 +51,21 @@ export function getSavedSearchObjectType( grid: { type: 'object', enabled: false }, version: { type: 'integer' }, rowHeight: { type: 'text' }, + timeRestore: { type: 'boolean', index: false, doc_values: false }, + timeRange: { + dynamic: false, + properties: { + from: { type: 'keyword', index: false, doc_values: false }, + to: { type: 'keyword', index: false, doc_values: false }, + }, + }, + refreshInterval: { + dynamic: false, + properties: { + pause: { type: 'boolean', index: false, doc_values: false }, + value: { type: 'integer', index: false, doc_values: false }, + }, + }, rowsPerPage: { type: 'integer', index: false, doc_values: false }, }, }, diff --git a/src/plugins/shared_ux/.i18nrc.json b/src/plugins/shared_ux/.i18nrc.json deleted file mode 100755 index cd7ac5b866df2a..00000000000000 --- a/src/plugins/shared_ux/.i18nrc.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "prefix": "sharedUX", - "paths": { - "sharedUX": "." - }, - "translations": [ - "translations/ja-JP.json" - ] -} diff --git a/src/plugins/shared_ux/README.md b/src/plugins/shared_ux/README.md deleted file mode 100755 index 748414c356e9b0..00000000000000 --- a/src/plugins/shared_ux/README.md +++ /dev/null @@ -1,29 +0,0 @@ -# sharedUX - -Our mission is to make consistency in our user experience a product. - -## Areas of Focus - -### UX Infrastructure - -- Create and maintain a discoverable home for shared UX code. -- Encourage contribution and usage. - -### UX Patterns - -- Work with design specialists to understand and communicate new and existing designs. -- Foster adoption of design principles by codifying them in shared resources. - -### UX Solutions - -- Drive common projects. -- Build and support common plugins. -- Help teams to create consistent user experiences. - -## The sharedUX Plugin - -This plugin contains common code that is shared among other plugins. - -## Contribution - -Contributions are welcome and encouraged! \ No newline at end of file diff --git a/src/plugins/shared_ux/docs/about.mdx b/src/plugins/shared_ux/docs/about.mdx deleted file mode 100644 index 213ce774be217e..00000000000000 --- a/src/plugins/shared_ux/docs/about.mdx +++ /dev/null @@ -1,36 +0,0 @@ ---- -id: sharedUX/About -slug: /shared-ux/about -title: About Shared UX -description: . -date: 2021-01-05 -tags: ['shared-ux'] ---- - -Our mission is to make consistency in our user experience a product. - -## Areas of Focus - -### UX Infrastructure - -- Create and maintain a discoverable home for shared UX code. -- Encourage contribution and usage. - -### UX Patterns - -- Work with design specialists to understand and communicate new and existing designs. -- Foster adoption of design principles by codifying them in shared resources. - -### UX Solutions - -- Drive common projects. -- Build and support common plugins. -- Help teams to create consistent user experiences. - -## The sharedUX Plugin - -This plugin contains common code that is shared among other plugins. - -## Contribution - -Contributions are welcome and encouraged! diff --git a/src/plugins/shared_ux/kibana.json b/src/plugins/shared_ux/kibana.json deleted file mode 100755 index 308a252f70b549..00000000000000 --- a/src/plugins/shared_ux/kibana.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "id": "sharedUX", - "version": "1.0.0", - "kibanaVersion": "kibana", - "owner": { - "name": "Shared UX", - "githubTeam": "shared-ux" - }, - "description": "A plugin providing components and services for shared user experiences in Kibana.", - "server": true, - "ui": true, - "requiredPlugins": ["dataViewEditor", "dataViews"], - "optionalPlugins": [] -} diff --git a/src/plugins/shared_ux/nav_shared_ux.docnav.json b/src/plugins/shared_ux/nav_shared_ux.docnav.json deleted file mode 100644 index 8f6ad010a49cba..00000000000000 --- a/src/plugins/shared_ux/nav_shared_ux.docnav.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "mission": "Shared UX", - "id": "sharedUX", - "landingPageId": "sharedUX/About", - "icon": "globe", - "description": "Developer documentation for Shared UX.", - "items": [ - { - "label": "About", - "items": [ - { - "id": "sharedUX/About" - } - ] - } - ] -} diff --git a/src/plugins/shared_ux/public/mocks.ts b/src/plugins/shared_ux/public/mocks.ts deleted file mode 100644 index c77236d503ca98..00000000000000 --- a/src/plugins/shared_ux/public/mocks.ts +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { SharedUXPlugin } from './plugin'; - -export type Setup = jest.Mocked>; -export type Start = jest.Mocked>; - -const createStartContract = (): jest.Mocked => { - const startContract = { - getContextServices: jest.fn(), - }; - return startContract; -}; - -export const sharedUXPluginMock = { - createStartContract, -}; diff --git a/src/plugins/shared_ux/public/plugin.ts b/src/plugins/shared_ux/public/plugin.ts deleted file mode 100755 index 8806de85b93049..00000000000000 --- a/src/plugins/shared_ux/public/plugin.ts +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { CoreSetup, CoreStart, Plugin } from '@kbn/core/public'; -import { - SharedUXPluginSetup, - SharedUXPluginStart, - SharedUXPluginStartDeps, - SharedUXPluginSetupDeps, -} from './types'; - -import { servicesFactory } from './services'; - -/** - * The Kibana plugin for Shared User Experience (Shared UX). - */ -export class SharedUXPlugin implements Plugin { - public setup( - _coreSetup: CoreSetup, - _setupPlugins: SharedUXPluginSetupDeps - ): SharedUXPluginSetup { - return {}; - } - - public start(coreStart: CoreStart, startPlugins: SharedUXPluginStartDeps): SharedUXPluginStart { - const services = servicesFactory({ coreStart, startPlugins }); - - return { - getContextServices: () => services, - }; - } - - public stop() {} -} diff --git a/src/plugins/shared_ux/public/services/application.ts b/src/plugins/shared_ux/public/services/application.ts deleted file mode 100644 index 95d6d4b4d72d99..00000000000000 --- a/src/plugins/shared_ux/public/services/application.ts +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { SharedUxApplicationService } from '@kbn/shared-ux-services'; - -import { KibanaPluginServiceFactory } from './types'; -import { SharedUXPluginStartDeps } from '../types'; - -export type ApplicationServiceFactory = KibanaPluginServiceFactory< - SharedUxApplicationService, - SharedUXPluginStartDeps ->; - -/** - * A factory function for creating a Kibana-based implementation of `SharedUXEditorsService`. - */ -export const applicationServiceFactory: ApplicationServiceFactory = ({ coreStart }) => ({ - navigateToUrl: coreStart.application.navigateToUrl, - currentAppId$: coreStart.application.currentAppId$, -}); diff --git a/src/plugins/shared_ux/public/services/data.ts b/src/plugins/shared_ux/public/services/data.ts deleted file mode 100644 index d68d35848e8129..00000000000000 --- a/src/plugins/shared_ux/public/services/data.ts +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { SharedUxDataService } from '@kbn/shared-ux-services'; -import { KibanaPluginServiceFactory } from './types'; -import { SharedUXPluginStartDeps } from '../types'; - -export type DataServiceFactory = KibanaPluginServiceFactory< - SharedUxDataService, - SharedUXPluginStartDeps ->; - -/** - * A factory function for creating a Kibana-based implementation of `SharedUXDataService`. - */ -export const dataServiceFactory: DataServiceFactory = ({ coreStart, startPlugins }) => ({ - hasDataView: startPlugins.dataViews.hasData.hasDataView, - hasESData: startPlugins.dataViews.hasData.hasESData, - hasUserDataView: startPlugins.dataViews.hasData.hasUserDataView, -}); diff --git a/src/plugins/shared_ux/public/services/doc_links.ts b/src/plugins/shared_ux/public/services/doc_links.ts deleted file mode 100644 index b457cddb7c3bc7..00000000000000 --- a/src/plugins/shared_ux/public/services/doc_links.ts +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { SharedUxDocLinksService } from '@kbn/shared-ux-services'; - -import { KibanaPluginServiceFactory } from './types'; -import { SharedUXPluginStartDeps } from '../types'; - -export type DocLinksServiceFactory = KibanaPluginServiceFactory< - SharedUxDocLinksService, - SharedUXPluginStartDeps ->; - -/** - * A factory function for creating a Kibana-based implementation of `SharedUXEditorsService`. - */ -export const docLinksServiceFactory: DocLinksServiceFactory = ({ coreStart }) => ({ - dataViewsDocLink: coreStart.docLinks.links.indexPatterns?.introduction, -}); diff --git a/src/plugins/shared_ux/public/services/editors.ts b/src/plugins/shared_ux/public/services/editors.ts deleted file mode 100644 index 498b42954091c6..00000000000000 --- a/src/plugins/shared_ux/public/services/editors.ts +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { SharedUxEditorsService } from '@kbn/shared-ux-services'; - -import { KibanaPluginServiceFactory } from './types'; -import { SharedUXPluginStartDeps } from '../types'; - -export type EditorsServiceFactory = KibanaPluginServiceFactory< - SharedUxEditorsService, - SharedUXPluginStartDeps ->; - -/** - * A factory function for creating a Kibana-based implementation of `SharedUXEditorsService`. - */ -export const editorsServiceFactory: EditorsServiceFactory = ({ startPlugins }) => ({ - openDataViewEditor: startPlugins.dataViewEditor.openEditor, -}); diff --git a/src/plugins/shared_ux/public/services/http.ts b/src/plugins/shared_ux/public/services/http.ts deleted file mode 100644 index afc2f00713988b..00000000000000 --- a/src/plugins/shared_ux/public/services/http.ts +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { SharedUxHttpService } from '@kbn/shared-ux-services'; - -import { KibanaPluginServiceFactory } from './types'; -import { SharedUXPluginStartDeps } from '../types'; - -export type HttpServiceFactory = KibanaPluginServiceFactory< - SharedUxHttpService, - SharedUXPluginStartDeps ->; - -/** - * A factory function for creating a Kibana-based implementation of `SharedUXEditorsService`. - */ -export const httpServiceFactory: HttpServiceFactory = ({ coreStart }) => ({ - addBasePath: coreStart.http.basePath.prepend, -}); diff --git a/src/plugins/shared_ux/public/services/index.ts b/src/plugins/shared_ux/public/services/index.ts deleted file mode 100644 index c8a572c262518c..00000000000000 --- a/src/plugins/shared_ux/public/services/index.ts +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { SharedUxServices } from '@kbn/shared-ux-services'; - -import type { SharedUXPluginStartDeps } from '../types'; -import type { KibanaPluginServiceFactory } from './types'; - -import { platformServiceFactory } from './platform'; -import { userPermissionsServiceFactory } from './permissions'; -import { editorsServiceFactory } from './editors'; -import { docLinksServiceFactory } from './doc_links'; -import { httpServiceFactory } from './http'; -import { applicationServiceFactory } from './application'; -import { dataServiceFactory } from './data'; - -/** - * A factory function for creating a Kibana-based implementation of `SharedUXServices`. - */ -export const servicesFactory: KibanaPluginServiceFactory< - SharedUxServices, - SharedUXPluginStartDeps -> = (params) => ({ - platform: platformServiceFactory(params), - permissions: userPermissionsServiceFactory(params), - editors: editorsServiceFactory(params), - docLinks: docLinksServiceFactory(params), - http: httpServiceFactory(params), - application: applicationServiceFactory(params), - data: dataServiceFactory(params), -}); diff --git a/src/plugins/shared_ux/public/services/permissions.ts b/src/plugins/shared_ux/public/services/permissions.ts deleted file mode 100644 index 694405b5c66104..00000000000000 --- a/src/plugins/shared_ux/public/services/permissions.ts +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { SharedUxUserPermissionsService } from '@kbn/shared-ux-services'; -import { KibanaPluginServiceFactory } from './types'; -import { SharedUXPluginStartDeps } from '../types'; - -export type UserPermissionsServiceFactory = KibanaPluginServiceFactory< - SharedUxUserPermissionsService, - SharedUXPluginStartDeps ->; - -/** - * A factory function for creating a Kibana-based implementation of `SharedUXPermissionsService`. - */ -export const userPermissionsServiceFactory: UserPermissionsServiceFactory = ({ - coreStart, - startPlugins, -}) => ({ - canCreateNewDataView: startPlugins.dataViewEditor.userPermissions.editDataView(), - canAccessFleet: coreStart.application.capabilities.navLinks.integrations, -}); diff --git a/src/plugins/shared_ux/public/services/platform.ts b/src/plugins/shared_ux/public/services/platform.ts deleted file mode 100644 index b0ee61583dd8de..00000000000000 --- a/src/plugins/shared_ux/public/services/platform.ts +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { SharedUxPlatformService } from '@kbn/shared-ux-services'; -import { SharedUXPluginStartDeps } from '../types'; -import { KibanaPluginServiceFactory } from './types'; - -/** - * A factory function for creating a Kibana-based implementation of `SharedUXPlatformService`. - */ -export type PlatformServiceFactory = KibanaPluginServiceFactory< - SharedUxPlatformService, - SharedUXPluginStartDeps ->; - -/** - * A factory function for creating a Kibana-based implementation of `SharedUXPlatformService`. - */ -export const platformServiceFactory: PlatformServiceFactory = ({ coreStart }) => ({ - setIsFullscreen: (isVisible: boolean) => coreStart.chrome.setIsVisible(isVisible), -}); diff --git a/src/plugins/shared_ux/public/services/types.ts b/src/plugins/shared_ux/public/services/types.ts deleted file mode 100644 index 895b2fb231a370..00000000000000 --- a/src/plugins/shared_ux/public/services/types.ts +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { BehaviorSubject } from 'rxjs'; -import { CoreStart, AppUpdater, PluginInitializerContext } from '@kbn/core/public'; - -/** - * Parameters necessary to create a Kibana-based service, (e.g. during Plugin - * startup or setup). - * - * The `Start` generic refers to the specific Plugin `TPluginsStart`. - */ -export interface KibanaPluginServiceParams { - coreStart: CoreStart; - startPlugins: Start; - appUpdater?: BehaviorSubject; - initContext?: PluginInitializerContext; -} - -/** - * A factory function for creating a Kibana-based service. - * - * The `Service` generic determines the shape of the Service being produced. - * The `Start` generic refers to the specific Plugin `TPluginsStart`. - */ -export type KibanaPluginServiceFactory = ( - params: KibanaPluginServiceParams -) => Service; diff --git a/src/plugins/shared_ux/public/types/index.ts b/src/plugins/shared_ux/public/types/index.ts deleted file mode 100644 index e3e7cb760268f8..00000000000000 --- a/src/plugins/shared_ux/public/types/index.ts +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -/* eslint-disable @typescript-eslint/no-empty-interface */ - -import { SharedUxServices } from '@kbn/shared-ux-services'; -import { DataViewEditorStart } from '@kbn/data-view-editor-plugin/public'; -import { DataViewsPublicPluginStart } from '@kbn/data-views-plugin/public'; - -/** @internal */ -export interface SharedUXPluginSetup {} - -/** - * The Shared UX plugin public contract, containing prewired components, services, and - * other constructs useful to consumers. - */ -export interface SharedUXPluginStart { - /** - * A set of pre-wired services for use with `SharedUxServicesProvider`. - * - * ``` - * import { SharedUxServicesProvider } from '@kbn/shared-ux-services'; - * - * public start(coreStart: CoreStart, startPlugins: MyPluginStartDeps): MyPluginStart { - * const services = startPlugins.sharedUX.getContextServices(); - * return { - * ServicesContext: ({ children }) => {children}, - * }; - * } - * ``` - * - * or - * - * ``` - * import { SharedUxServicesProvider } from '@kbn/shared-ux-services'; - * - * public setup(coreSetup: CoreSetup, setupPlugins: MyPluginSetupDeps): MyPluginSetup { - * const [coreStart, startPlugins] = await coreSetup.getStartServices(); - * coreSetup.application.register({ - * mount: async (params: AppMountParameters) => { - * ReactDOM.render( - * - * - * , - * params.element - * ); - * } - * ); - * } - * ``` - */ - getContextServices: () => SharedUxServices; -} - -/** @internal */ -export interface SharedUXPluginSetupDeps {} - -/** @internal */ -export interface SharedUXPluginStartDeps { - dataViewEditor: DataViewEditorStart; - dataViews: DataViewsPublicPluginStart; -} diff --git a/src/plugins/shared_ux/tsconfig.json b/src/plugins/shared_ux/tsconfig.json deleted file mode 100644 index 3a287353a5341f..00000000000000 --- a/src/plugins/shared_ux/tsconfig.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "extends": "../../../tsconfig.base.json", - "compilerOptions": { - "outDir": "./target/types", - "emitDeclarationOnly": true, - "declaration": true, - "declarationMap": true - }, - "include": [ - "common/**/*", - "public/**/*", - "server/**/*", - "../../../typings/**/*" - ], - "references": [ - { - "path": "../../core/tsconfig.json" - }, - { - "path": "../data_view_editor/tsconfig.json" - }, - { - "path": "../data_views/tsconfig.json" - } - ] -} diff --git a/src/plugins/telemetry/schema/oss_plugins.json b/src/plugins/telemetry/schema/oss_plugins.json index cacd8067e4e03f..e59b192442133a 100644 --- a/src/plugins/telemetry/schema/oss_plugins.json +++ b/src/plugins/telemetry/schema/oss_plugins.json @@ -8282,12 +8282,6 @@ "description": "Non-default value of setting." } }, - "observability:enableInfrastructureView": { - "type": "boolean", - "_meta": { - "description": "Non-default value of setting." - } - }, "observability:enableServiceGroups": { "type": "boolean", "_meta": { diff --git a/src/plugins/unified_field_list/README.md b/src/plugins/unified_field_list/README.md new file mode 100755 index 00000000000000..657523aad9c1b9 --- /dev/null +++ b/src/plugins/unified_field_list/README.md @@ -0,0 +1,21 @@ +# unifiedFieldList + +This Kibana plugin contains components and services for field list UI (as in fields sidebar on Discover and Lens pages). + +--- + +## Components + +* `` - loads and renders stats (Top values, Histogram) for a data view field. + +## Public Services + +* `loadStats(...)` - returns the loaded field stats (can also work with Ad-hoc data views) + +## Server APIs + +* `/api/unified_field_list/field_stats` - returns the loaded field stats (except for Ad-hoc data views) + +## Development + +See the [kibana contributing guide](https://github.com/elastic/kibana/blob/main/CONTRIBUTING.md) for instructions setting up your development environment. diff --git a/packages/kbn-shared-ux-services/src/services/http.ts b/src/plugins/unified_field_list/common/constants.ts similarity index 74% rename from packages/kbn-shared-ux-services/src/services/http.ts rename to src/plugins/unified_field_list/common/constants.ts index 024222092b7b10..ef8a01b2705ff9 100644 --- a/packages/kbn-shared-ux-services/src/services/http.ts +++ b/src/plugins/unified_field_list/common/constants.ts @@ -6,6 +6,5 @@ * Side Public License, v 1. */ -export interface SharedUxHttpService { - addBasePath: (url: string) => string; -} +export const BASE_API_PATH = '/api/unified_field_list'; +export const FIELD_STATS_API_PATH = `${BASE_API_PATH}/field_stats`; diff --git a/src/plugins/controls/public/control_types/index.ts b/src/plugins/unified_field_list/common/index.ts old mode 100644 new mode 100755 similarity index 88% rename from src/plugins/controls/public/control_types/index.ts rename to src/plugins/unified_field_list/common/index.ts index 8dfa50ee5cbdae..747db7a56bbae5 --- a/src/plugins/controls/public/control_types/index.ts +++ b/src/plugins/unified_field_list/common/index.ts @@ -6,4 +6,4 @@ * Side Public License, v 1. */ -export * from './range_slider'; +export const PLUGIN_ID = 'unifiedFieldList'; diff --git a/src/plugins/vis_types/xy/public/config/index.ts b/src/plugins/unified_field_list/common/types/index.ts old mode 100644 new mode 100755 similarity index 75% rename from src/plugins/vis_types/xy/public/config/index.ts rename to src/plugins/unified_field_list/common/types/index.ts index b00d6aea3d356b..78dbc548406c0b --- a/src/plugins/vis_types/xy/public/config/index.ts +++ b/src/plugins/unified_field_list/common/types/index.ts @@ -6,5 +6,9 @@ * Side Public License, v 1. */ -export { getConfig } from './get_config'; -export { getAggId } from './get_agg_id'; +export type { + FieldStatsResponse, + NumberStatsResult, + TopValuesResult, + BucketedAggregation, +} from './stats'; diff --git a/x-pack/plugins/lens/common/api.ts b/src/plugins/unified_field_list/common/types/stats.ts similarity index 84% rename from x-pack/plugins/lens/common/api.ts rename to src/plugins/unified_field_list/common/types/stats.ts index 026f540cdb67b5..71d75db1aaaa3c 100644 --- a/x-pack/plugins/lens/common/api.ts +++ b/src/plugins/unified_field_list/common/types/stats.ts @@ -1,8 +1,9 @@ /* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. */ export interface BucketedAggregation { diff --git a/x-pack/plugins/lens/server/routes/field_stats.ts b/src/plugins/unified_field_list/common/utils/field_stats_utils.ts similarity index 52% rename from x-pack/plugins/lens/server/routes/field_stats.ts rename to src/plugins/unified_field_list/common/utils/field_stats_utils.ts index 35a15ea44be67d..9cf33961d76b61 100644 --- a/x-pack/plugins/lens/server/routes/field_stats.ts +++ b/src/plugins/unified_field_list/common/utils/field_stats_utils.ts @@ -1,149 +1,119 @@ /* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. */ -import { errors } from '@elastic/elasticsearch'; + import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import DateMath from '@kbn/datemath'; -import { schema } from '@kbn/config-schema'; -import { CoreSetup } from '@kbn/core/server'; -import type { DataViewField } from '@kbn/data-views-plugin/common'; -import { SavedObjectNotFound } from '@kbn/kibana-utils-plugin/common'; import { ESSearchResponse } from '@kbn/core/types/elasticsearch'; -import { FieldStatsResponse, BASE_API_URL } from '../../common'; -import { PluginStartContract } from '../plugin'; +import type { DataViewFieldBase } from '@kbn/es-query'; +import type { FieldStatsResponse } from '../types'; -const SHARD_SIZE = 5000; +export type SearchHandler = ( + aggs: Record +) => Promise>; -export async function initFieldsRoute(setup: CoreSetup) { - const router = setup.http.createRouter(); - router.post( - { - path: `${BASE_API_URL}/index_stats/{indexPatternId}/field`, - validate: { - params: schema.object({ - indexPatternId: schema.string(), - }), - body: schema.object( - { - dslQuery: schema.object({}, { unknowns: 'allow' }), - fromDate: schema.string(), - toDate: schema.string(), - fieldName: schema.string(), - size: schema.maybe(schema.number()), +const SHARD_SIZE = 5000; +const DEFAULT_TOP_VALUES_SIZE = 10; + +export function buildSearchParams({ + dataViewPattern, + timeFieldName, + fromDate, + toDate, + dslQuery, + runtimeMappings, + aggs, +}: { + dataViewPattern: string; + timeFieldName?: string; + fromDate: string; + toDate: string; + dslQuery: object; + runtimeMappings: estypes.MappingRuntimeFields; + aggs: Record; +}) { + const filter = timeFieldName + ? [ + { + range: { + [timeFieldName]: { + gte: fromDate, + lte: toDate, + }, }, - { unknowns: 'allow' } - ), - }, + }, + dslQuery, + ] + : [dslQuery]; + + const query = { + bool: { + filter, }, - async (context, req, res) => { - const requestClient = (await context.core).elasticsearch.client.asCurrentUser; - const { fromDate, toDate, fieldName, dslQuery, size } = req.body; - - const [{ savedObjects, elasticsearch }, { dataViews }] = await setup.getStartServices(); - const savedObjectsClient = savedObjects.getScopedClient(req); - const esClient = elasticsearch.client.asScoped(req).asCurrentUser; - const indexPatternsService = await dataViews.dataViewsServiceFactory( - savedObjectsClient, - esClient - ); - - try { - const indexPattern = await indexPatternsService.get(req.params.indexPatternId); - - const timeFieldName = indexPattern.timeFieldName; - const field = indexPattern.fields.find((f) => f.name === fieldName); - - if (!field) { - throw new Error(`Field {fieldName} not found in data view ${indexPattern.title}`); - } - - const filter = timeFieldName - ? [ - { - range: { - [timeFieldName]: { - gte: fromDate, - lte: toDate, - }, - }, - }, - dslQuery, - ] - : [dslQuery]; - - const query = { - bool: { - filter, - }, - }; + }; - const runtimeMappings = indexPattern.getRuntimeMappings(); + return { + index: dataViewPattern, + body: { + query, + aggs, + runtime_mappings: runtimeMappings, + }, + track_total_hits: true, + size: 0, + }; +} - const search = async (aggs: Record) => { - const result = await requestClient.search({ - index: indexPattern.title, - track_total_hits: true, - body: { - query, - aggs, - runtime_mappings: runtimeMappings, - }, - size: 0, - }); - return result; - }; +export async function fetchAndCalculateFieldStats({ + searchHandler, + field, + fromDate, + toDate, + size, +}: { + searchHandler: SearchHandler; + field: DataViewFieldBase; + fromDate: string; + toDate: string; + size?: number; +}) { + if (!canProvideStatsForField(field)) { + return {}; + } - if (field.type.includes('range')) { - return res.ok({ body: {} }); - } - - if (field.type === 'histogram') { - return res.ok({ - body: await getNumberHistogram(search, field, false), - }); - } else if (field.type === 'number') { - return res.ok({ - body: await getNumberHistogram(search, field), - }); - } else if (field.type === 'date') { - return res.ok({ - body: await getDateHistogram(search, field, { fromDate, toDate }), - }); - } - - return res.ok({ - body: await getStringSamples(search, field, size), - }); - } catch (e) { - if (e instanceof SavedObjectNotFound) { - return res.notFound(); - } - if (e instanceof errors.ResponseError && e.statusCode === 404) { - return res.notFound(); - } - if (e.isBoom) { - if (e.output.statusCode === 404) { - return res.notFound(); - } - throw new Error(e.output.message); - } else { - throw e; - } - } - } + if (field.type === 'histogram') { + return await getNumberHistogram(searchHandler, field, false); + } + + if (field.type === 'number') { + return await getNumberHistogram(searchHandler, field); + } + + if (field.type === 'date') { + return await getDateHistogram(searchHandler, field, { fromDate, toDate }); + } + + return await getStringSamples(searchHandler, field, size); +} + +export function canProvideStatsForField(field: DataViewFieldBase): boolean { + return !( + field.type === 'document' || + field.type.includes('range') || + field.type === 'geo_point' || + field.type === 'geo_shape' ); } export async function getNumberHistogram( - aggSearchWithBody: ( - aggs: Record - ) => Promise, - field: DataViewField, + aggSearchWithBody: SearchHandler, + field: DataViewFieldBase, useTopHits = true -): Promise { +): Promise> { const fieldRef = getFieldRef(field); const baseAggs = { @@ -167,7 +137,7 @@ export async function getNumberHistogram( aggs: { ...baseAggs, top_values: { - terms: { ...fieldRef, size: 10 }, + terms: { ...fieldRef, size: DEFAULT_TOP_VALUES_SIZE }, }, }, }, @@ -203,7 +173,7 @@ export async function getNumberHistogram( if (histogramInterval === 0) { return { - totalDocuments: minMaxResult.hits.total.value, + totalDocuments: getHitsTotal(minMaxResult), sampledValues: minMaxResult.aggregations!.sample.sample_count.value!, sampledDocuments: minMaxResult.aggregations!.sample.doc_count, topValues: topValuesBuckets, @@ -211,7 +181,7 @@ export async function getNumberHistogram( ? { buckets: [] } : { // Insert a fake bucket for a single-value histogram - buckets: [{ count: minMaxResult.aggregations!.sample.doc_count, key: minValue }], + buckets: [{ count: minMaxResult.aggregations!.sample.doc_count, key: minValue! }], }, }; } @@ -235,7 +205,7 @@ export async function getNumberHistogram( >; return { - totalDocuments: minMaxResult.hits.total.value, + totalDocuments: getHitsTotal(minMaxResult), sampledDocuments: minMaxResult.aggregations!.sample.doc_count, sampledValues: minMaxResult.aggregations!.sample.sample_count.value!, histogram: { @@ -249,10 +219,10 @@ export async function getNumberHistogram( } export async function getStringSamples( - aggSearchWithBody: (aggs: Record) => unknown, - field: DataViewField, - size = 10 -): Promise { + aggSearchWithBody: SearchHandler, + field: DataViewFieldBase, + size = DEFAULT_TOP_VALUES_SIZE +): Promise> { const fieldRef = getFieldRef(field); const topValuesBody = { @@ -275,7 +245,7 @@ export async function getStringSamples( >; return { - totalDocuments: topValuesResult.hits.total.value, + totalDocuments: getHitsTotal(topValuesResult), sampledDocuments: topValuesResult.aggregations!.sample.doc_count, sampledValues: topValuesResult.aggregations!.sample.sample_count.value!, topValues: { @@ -289,10 +259,10 @@ export async function getStringSamples( // This one is not sampled so that it returns the full date range export async function getDateHistogram( - aggSearchWithBody: (aggs: Record) => unknown, - field: DataViewField, + aggSearchWithBody: SearchHandler, + field: DataViewFieldBase, range: { fromDate: string; toDate: string } -): Promise { +): Promise> { const fromDate = DateMath.parse(range.fromDate); const toDate = DateMath.parse(range.toDate); if (!fromDate) { @@ -322,7 +292,7 @@ export async function getDateHistogram( >; return { - totalDocuments: results.hits.total.value, + totalDocuments: getHitsTotal(results), histogram: { buckets: results.aggregations!.histo.buckets.map((bucket) => ({ count: bucket.doc_count, @@ -332,7 +302,7 @@ export async function getDateHistogram( }; } -function getFieldRef(field: DataViewField) { +function getFieldRef(field: DataViewFieldBase) { return field.scripted ? { script: { @@ -342,3 +312,7 @@ function getFieldRef(field: DataViewField) { } : { field: field.name }; } + +const getHitsTotal = (body: estypes.SearchResponse): number => { + return (body.hits.total as estypes.SearchTotalHits).value ?? body.hits.total ?? 0; +}; diff --git a/src/plugins/unified_field_list/jest.config.js b/src/plugins/unified_field_list/jest.config.js new file mode 100644 index 00000000000000..a1782360c93b99 --- /dev/null +++ b/src/plugins/unified_field_list/jest.config.js @@ -0,0 +1,16 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +module.exports = { + preset: '@kbn/test', + rootDir: '../../..', + roots: ['/src/plugins/unified_field_list'], + coverageDirectory: '/target/kibana-coverage/jest/src/plugins/unified_field_list', + coverageReporters: ['text', 'html'], + collectCoverageFrom: ['/src/plugins/unified_field_list/public/**/*.{ts,tsx}'], +}; diff --git a/src/plugins/unified_field_list/kibana.json b/src/plugins/unified_field_list/kibana.json new file mode 100755 index 00000000000000..6785d55989cc51 --- /dev/null +++ b/src/plugins/unified_field_list/kibana.json @@ -0,0 +1,15 @@ +{ + "id": "unifiedFieldList", + "version": "1.0.0", + "kibanaVersion": "kibana", + "owner": { + "name": "Data Discovery", + "githubTeam": "kibana-data-discovery" + }, + "description": "Contains functionality for the field list which can be integrated into apps", + "server": true, + "ui": true, + "requiredPlugins": ["dataViews", "data", "fieldFormats", "charts"], + "optionalPlugins": [], + "requiredBundles": [] +} diff --git a/src/plugins/unified_field_list/public/components/field_stats/field_stats.test.tsx b/src/plugins/unified_field_list/public/components/field_stats/field_stats.test.tsx new file mode 100644 index 00000000000000..87b8b7530c8397 --- /dev/null +++ b/src/plugins/unified_field_list/public/components/field_stats/field_stats.test.tsx @@ -0,0 +1,543 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import React from 'react'; +import { act } from 'react-dom/test-utils'; +import { EuiLoadingSpinner, EuiProgress } from '@elastic/eui'; +import { coreMock } from '@kbn/core/public/mocks'; +import { mountWithIntl } from '@kbn/test-jest-helpers'; +import { fieldFormatsServiceMock } from '@kbn/field-formats-plugin/public/mocks'; +import { chartPluginMock } from '@kbn/charts-plugin/public/mocks'; +import { dataPluginMock } from '@kbn/data-plugin/public/mocks'; +import { dataViewPluginMocks } from '@kbn/data-views-plugin/public/mocks'; +import type { DataView } from '@kbn/data-views-plugin/common'; +import type { DataViewField } from '@kbn/data-views-plugin/common'; +import { loadFieldStats } from '../../services/field_stats'; +import FieldStats from './field_stats'; +import type { FieldStatsProps } from './field_stats'; + +jest.mock('../../services/field_stats', () => ({ + loadFieldStats: jest.fn().mockResolvedValue({}), +})); + +const mockedServices = { + data: dataPluginMock.createStartContract(), + dataViews: dataViewPluginMocks.createStartContract(), + fieldFormats: fieldFormatsServiceMock.createStartContract(), + charts: chartPluginMock.createSetupContract(), + uiSettings: coreMock.createStart().uiSettings, +}; + +describe('UnifiedFieldList ', () => { + let defaultProps: FieldStatsProps; + let dataView: DataView; + + beforeEach(() => { + dataView = { + id: '1', + title: 'my-fake-index-pattern', + timeFieldName: 'timestamp', + fields: [ + { + name: 'timestamp', + displayName: 'timestampLabel', + type: 'date', + aggregatable: true, + searchable: true, + }, + { + name: 'bytes', + displayName: 'bytesLabel', + type: 'number', + aggregatable: true, + searchable: true, + }, + { + name: 'memory', + displayName: 'memory', + type: 'number', + aggregatable: true, + searchable: true, + }, + { + name: 'unsupported', + displayName: 'unsupported', + type: 'geo', + aggregatable: true, + searchable: true, + }, + { + name: 'source', + displayName: 'source', + type: 'string', + aggregatable: true, + searchable: true, + }, + { + name: 'ip_range', + displayName: 'ip_range', + type: 'ip_range', + aggregatable: true, + searchable: true, + }, + { + name: 'machine.ram', + displayName: 'machine.ram', + type: 'number', + aggregatable: true, + searchable: true, + }, + ], + getFormatterForField: jest.fn(() => ({ + convert: jest.fn((s: unknown) => JSON.stringify(s)), + })), + } as unknown as DataView; + + defaultProps = { + services: mockedServices, + dataViewOrDataViewId: dataView, + field: { + name: 'bytes', + type: 'number', + } as unknown as DataViewField, + fromDate: 'now-7d', + toDate: 'now', + query: { query: '', language: 'lucene' }, + filters: [], + 'data-test-subj': 'testing', + }; + + (mockedServices.dataViews.get as jest.Mock).mockImplementation(() => { + return Promise.resolve(dataView); + }); + }); + + beforeEach(() => { + (loadFieldStats as jest.Mock).mockReset(); + (loadFieldStats as jest.Mock).mockImplementation(() => Promise.resolve({})); + }); + + it('should request field stats with correct params', async () => { + let resolveFunction: (arg: unknown) => void; + + (loadFieldStats as jest.Mock).mockImplementation(() => { + return new Promise((resolve) => { + resolveFunction = resolve; + }); + }); + + const wrapper = mountWithIntl( + + ); + + await wrapper.update(); + + expect(loadFieldStats).toHaveBeenCalledWith({ + abortController: new AbortController(), + services: { data: mockedServices.data }, + dataView, + dslQuery: { + bool: { + must: [], + filter: [ + { + bool: { + should: [{ match_phrase: { 'geo.src': 'US' } }], + minimum_should_match: 1, + }, + }, + { + match: { phrase: { 'geo.dest': 'US' } }, + }, + ], + should: [], + must_not: [], + }, + }, + fromDate: 'now-14d', + toDate: 'now-7d', + field: defaultProps.field, + }); + + expect(wrapper.find(EuiLoadingSpinner)).toHaveLength(1); + + await act(async () => { + resolveFunction!({ + totalDocuments: 4633, + sampledDocuments: 4633, + sampledValues: 4633, + histogram: { + buckets: [{ count: 705, key: 0 }], + }, + topValues: { + buckets: [{ count: 147, key: 0 }], + }, + }); + }); + + await wrapper.update(); + + expect(wrapper.find(EuiLoadingSpinner)).toHaveLength(0); + + expect(loadFieldStats).toHaveBeenCalledTimes(1); + }); + + it('should not request field stats for range fields', async () => { + const wrapper = await mountWithIntl( + + ); + + await wrapper.update(); + + expect(loadFieldStats).not.toHaveBeenCalled(); + }); + + it('should not request field stats for geo fields', async () => { + const wrapper = await mountWithIntl( + + ); + + await wrapper.update(); + + expect(loadFieldStats).not.toHaveBeenCalled(); + }); + + it('should render nothing if no data is found', async () => { + const wrapper = mountWithIntl(); + + await wrapper.update(); + + expect(loadFieldStats).toHaveBeenCalled(); + + expect(wrapper.text()).toBe(''); + }); + + it('should render Top Values field stats correctly for a keyword field', async () => { + let resolveFunction: (arg: unknown) => void; + + (loadFieldStats as jest.Mock).mockImplementation(() => { + return new Promise((resolve) => { + resolveFunction = resolve; + }); + }); + + const wrapper = mountWithIntl( + + ); + + await wrapper.update(); + + expect(loadFieldStats).toHaveBeenCalledWith({ + abortController: new AbortController(), + services: { data: mockedServices.data }, + dataView, + fromDate: 'now-7d', + toDate: 'now', + dslQuery: { + bool: { + must: [], + filter: [], + should: [], + must_not: [], + }, + }, + field: defaultProps.field, + }); + + expect(wrapper.find(EuiLoadingSpinner)).toHaveLength(1); + + await act(async () => { + resolveFunction!({ + totalDocuments: 1624, + sampledDocuments: 1624, + sampledValues: 3248, + topValues: { + buckets: [ + { + count: 1349, + key: 'success', + }, + { + count: 1206, + key: 'info', + }, + { + count: 329, + key: 'security', + }, + { + count: 164, + key: 'warning', + }, + { + count: 111, + key: 'error', + }, + { + count: 89, + key: 'login', + }, + ], + }, + }); + }); + + await wrapper.update(); + + expect(wrapper.find(EuiLoadingSpinner)).toHaveLength(0); + expect(wrapper.find(EuiProgress)).toHaveLength(6); + + expect(loadFieldStats).toHaveBeenCalledTimes(1); + + const stats = wrapper.find('[data-test-subj="testing-topValues"]'); + const firstValue = stats.childAt(0); + + expect(stats).toHaveLength(1); + expect(firstValue.find('[data-test-subj="testing-topValues-value"]').first().text()).toBe( + '"success"' + ); + expect(firstValue.find('[data-test-subj="testing-topValues-valueCount"]').first().text()).toBe( + '41.5%' + ); + + expect(wrapper.find('[data-test-subj="testing-statsFooter"]').first().text()).toBe( + '100% of 1624 documents' + ); + + expect(wrapper.text()).toBe( + 'Top values"success"41.5%"info"37.1%"security"10.1%"warning"5.0%"error"3.4%"login"2.7%100% of 1624 documents' + ); + }); + + it('should render Histogram field stats correctly for a date field', async () => { + let resolveFunction: (arg: unknown) => void; + + (loadFieldStats as jest.Mock).mockImplementation(() => { + return new Promise((resolve) => { + resolveFunction = resolve; + }); + }); + + const wrapper = mountWithIntl( + + ); + + await wrapper.update(); + + expect(loadFieldStats).toHaveBeenCalledWith({ + abortController: new AbortController(), + services: { data: mockedServices.data }, + dataView, + fromDate: 'now-1h', + toDate: 'now', + dslQuery: { + bool: { + must: [], + filter: [], + should: [], + must_not: [], + }, + }, + field: dataView.fields[0], + }); + + expect(wrapper.find(EuiLoadingSpinner)).toHaveLength(1); + + await act(async () => { + resolveFunction!({ + totalDocuments: 13, + histogram: { + buckets: [ + { + count: 1, + key: 1660564080000, + }, + { + count: 2, + key: 1660564440000, + }, + { + count: 3, + key: 1660564800000, + }, + { + count: 1, + key: 1660565160000, + }, + { + count: 2, + key: 1660565520000, + }, + { + count: 0, + key: 1660565880000, + }, + { + count: 1, + key: 1660566240000, + }, + { + count: 1, + key: 1660566600000, + }, + { + count: 1, + key: 1660566960000, + }, + { + count: 1, + key: 1660567320000, + }, + ], + }, + }); + }); + + await wrapper.update(); + + expect(wrapper.find(EuiLoadingSpinner)).toHaveLength(0); + + expect(loadFieldStats).toHaveBeenCalledTimes(1); + + expect(wrapper.find('[data-test-subj="testing-topValues"]')).toHaveLength(0); + expect(wrapper.find('[data-test-subj="testing-histogram"]')).toHaveLength(1); + expect(wrapper.find('[data-test-subj="testing-statsFooter"]').first().text()).toBe( + '13 documents' + ); + + expect(wrapper.text()).toBe('Time distribution13 documents'); + }); + + it('should render Top Values & Distribution field stats correctly for a number field', async () => { + let resolveFunction: (arg: unknown) => void; + + (loadFieldStats as jest.Mock).mockImplementation(() => { + return new Promise((resolve) => { + resolveFunction = resolve; + }); + }); + + const field = dataView.fields.find((f) => f.name === 'machine.ram')!; + + const wrapper = mountWithIntl( + + ); + + await wrapper.update(); + + expect(loadFieldStats).toHaveBeenCalledWith({ + abortController: new AbortController(), + services: { data: mockedServices.data }, + dataView, + fromDate: 'now-1h', + toDate: 'now', + dslQuery: { + bool: { + must: [], + filter: [], + should: [], + must_not: [], + }, + }, + field, + }); + + expect(wrapper.find(EuiLoadingSpinner)).toHaveLength(1); + + await act(async () => { + resolveFunction!({ + totalDocuments: 23, + sampledDocuments: 23, + sampledValues: 23, + histogram: { + buckets: [ + { + count: 17, + key: 12, + }, + { + count: 6, + key: 13, + }, + ], + }, + topValues: { + buckets: [ + { + count: 17, + key: 12, + }, + { + count: 6, + key: 13, + }, + ], + }, + }); + }); + + await wrapper.update(); + + expect(wrapper.find(EuiLoadingSpinner)).toHaveLength(0); + + expect(loadFieldStats).toHaveBeenCalledTimes(1); + + expect(wrapper.text()).toBe( + 'Toggle either theTop valuesDistribution1273.9%1326.1%100% of 23 documents' + ); + }); +}); diff --git a/src/plugins/unified_field_list/public/components/field_stats/field_stats.tsx b/src/plugins/unified_field_list/public/components/field_stats/field_stats.tsx new file mode 100755 index 00000000000000..590451a2558948 --- /dev/null +++ b/src/plugins/unified_field_list/public/components/field_stats/field_stats.tsx @@ -0,0 +1,595 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'; +import { + DataView, + DataViewField, + ES_FIELD_TYPES, + getEsQueryConfig, + KBN_FIELD_TYPES, +} from '@kbn/data-plugin/common'; +import type { IUiSettingsClient } from '@kbn/core/public'; +import type { DataViewsContract } from '@kbn/data-views-plugin/public'; +import type { DataPublicPluginStart } from '@kbn/data-plugin/public'; +import type { FieldFormatsStart } from '@kbn/field-formats-plugin/public'; +import type { ChartsPluginSetup } from '@kbn/charts-plugin/public'; +import DateMath from '@kbn/datemath'; +import { + EuiButtonGroup, + EuiFlexGroup, + EuiFlexItem, + EuiLoadingSpinner, + EuiProgress, + EuiSpacer, + EuiText, + EuiTitle, + EuiToolTip, + useEuiTheme, +} from '@elastic/eui'; +import { css } from '@emotion/react'; +import { + Axis, + Chart, + HistogramBarSeries, + niceTimeFormatter, + Position, + ScaleType, + Settings, + TooltipType, +} from '@elastic/charts'; +import { i18n } from '@kbn/i18n'; +import { buildEsQuery, Query, Filter, AggregateQuery } from '@kbn/es-query'; +import type { BucketedAggregation } from '../../../common/types'; +import { canProvideStatsForField } from '../../../common/utils/field_stats_utils'; +import { loadFieldStats } from '../../services/field_stats'; + +interface State { + isLoading: boolean; + totalDocuments?: number; + sampledDocuments?: number; + sampledValues?: number; + histogram?: BucketedAggregation; + topValues?: BucketedAggregation; +} + +export interface FieldStatsServices { + uiSettings: IUiSettingsClient; + dataViews: DataViewsContract; + data: DataPublicPluginStart; + fieldFormats: FieldFormatsStart; + charts: ChartsPluginSetup; +} + +export interface FieldStatsProps { + services: FieldStatsServices; + query: Query | AggregateQuery; + filters: Filter[]; + fromDate: string; + toDate: string; + dataViewOrDataViewId: DataView | string; + field: DataViewField; + 'data-test-subj'?: string; + overrideMissingContent?: (params?: { noDataFound?: boolean }) => JSX.Element | null; + overrideFooter?: (params: { + element: JSX.Element; + totalDocuments?: number; + sampledDocuments?: number; + }) => JSX.Element; +} + +const FieldStatsComponent: React.FC = ({ + services, + query, + filters, + fromDate, + toDate, + dataViewOrDataViewId, + field, + 'data-test-subj': dataTestSubject = 'fieldStats', + overrideMissingContent, + overrideFooter, +}) => { + const { euiTheme } = useEuiTheme(); + const { fieldFormats, uiSettings, charts, dataViews, data } = services; + const [state, changeState] = useState({ + isLoading: false, + }); + const [dataView, changeDataView] = useState(null); + const abortControllerRef = useRef(null); + const isCanceledRef = useRef(false); + + const topValueStyles = useMemo( + () => css` + margin-bottom: ${euiTheme.size.s}; + + &:last-of-type { + margin-bottom: 0; + } + `, + [euiTheme] + ); + + const topValueProgressStyles = useMemo( + () => css` + background-color: ${euiTheme.colors.lightestShade}; + + &::-webkit-progress-bar { + background-color: ${euiTheme.colors.lightestShade}; + } + `, + [euiTheme] + ); + + const setState: typeof changeState = useCallback( + (nextState) => { + if (!isCanceledRef.current) { + changeState(nextState); + } + }, + [changeState, isCanceledRef] + ); + + const setDataView: typeof changeDataView = useCallback( + (nextDataView) => { + if (!isCanceledRef.current) { + changeDataView(nextDataView); + } + }, + [changeDataView, isCanceledRef] + ); + + async function fetchData() { + if (isCanceledRef.current) { + return; + } + + try { + const loadedDataView = + typeof dataViewOrDataViewId === 'string' + ? await dataViews.get(dataViewOrDataViewId) + : dataViewOrDataViewId; + + setDataView(loadedDataView); + + if (state.isLoading || !canProvideStatsForField(field)) { + return; + } + + setState((s) => ({ ...s, isLoading: true })); + + abortControllerRef.current?.abort(); + abortControllerRef.current = new AbortController(); + + const results = await loadFieldStats({ + services: { data }, + dataView: loadedDataView, + field, + fromDate, + toDate, + dslQuery: buildEsQuery(loadedDataView, query, filters, getEsQueryConfig(uiSettings)), + abortController: abortControllerRef.current, + }); + + abortControllerRef.current = null; + + setState((s) => ({ + ...s, + isLoading: false, + totalDocuments: results.totalDocuments, + sampledDocuments: results.sampledDocuments, + sampledValues: results.sampledValues, + histogram: results.histogram, + topValues: results.topValues, + })); + } catch (e) { + // console.error(e); + setState((s) => ({ ...s, isLoading: false })); + } + } + + useEffect(() => { + fetchData(); + + return () => { + isCanceledRef.current = true; + abortControllerRef.current?.abort(); + }; + }, []); // eslint-disable-line react-hooks/exhaustive-deps + + const chartTheme = charts.theme.useChartsTheme(); + const chartBaseTheme = charts.theme.useChartsBaseTheme(); + + const { isLoading, histogram, topValues, sampledValues, sampledDocuments, totalDocuments } = + state; + + let histogramDefault = !!state.histogram; + const fromDateParsed = DateMath.parse(fromDate); + const toDateParsed = DateMath.parse(toDate); + + const totalValuesCount = + topValues && topValues.buckets.reduce((prev, bucket) => bucket.count + prev, 0); + const otherCount = sampledValues && totalValuesCount ? sampledValues - totalValuesCount : 0; + + if ( + totalValuesCount && + histogram && + histogram.buckets.length && + topValues && + topValues.buckets.length + ) { + // Default to histogram when top values are less than 10% of total + histogramDefault = otherCount / totalValuesCount > 0.9; + } + + const [showingHistogram, setShowingHistogram] = useState(histogramDefault); + + if (isLoading) { + return ; + } + + if (!dataView) { + return null; + } + + const formatter = dataView.getFormatterForField(field); + let title = <>; + + if (field.type.includes('range')) { + return ( + <> + + {i18n.translate('unifiedFieldList.fieldStats.notAvailableForRangeFieldDescription', { + defaultMessage: `Summary information is not available for range type fields.`, + })} + + + ); + } + + if (field.type === 'murmur3') { + return ( + <> + + {i18n.translate('unifiedFieldList.fieldStats.notAvailableForMurmur3FieldDescription', { + defaultMessage: `Summary information is not available for murmur3 fields.`, + })} + + + ); + } + + if (field.type === 'geo_point' || field.type === 'geo_shape') { + return overrideMissingContent ? overrideMissingContent() : null; + } + + if ( + (!histogram || histogram.buckets.length === 0) && + (!topValues || topValues.buckets.length === 0) + ) { + return overrideMissingContent ? overrideMissingContent({ noDataFound: true }) : null; + } + + if (histogram && histogram.buckets.length && topValues && topValues.buckets.length) { + title = ( + { + setShowingHistogram(optionId === 'histogram'); + }} + idSelected={showingHistogram ? 'histogram' : 'topValues'} + /> + ); + } else if (field.type === 'date') { + title = ( + +
+ {i18n.translate('unifiedFieldList.fieldStats.fieldTimeDistributionLabel', { + defaultMessage: 'Time distribution', + })} +
+
+ ); + } else if (topValues && topValues.buckets.length) { + title = ( + +
+ {i18n.translate('unifiedFieldList.fieldStats.topValuesLabel', { + defaultMessage: 'Top values', + })} +
+
+ ); + } + + function combineWithTitleAndFooter(el: React.ReactElement) { + const countsElement = totalDocuments ? ( + + {sampledDocuments && ( + <> + {i18n.translate('unifiedFieldList.fieldStats.percentageOfLabel', { + defaultMessage: '{percentage}% of', + values: { + percentage: Math.round((sampledDocuments / totalDocuments) * 100), + }, + })}{' '} + + )} + + {fieldFormats + .getDefaultInstance(KBN_FIELD_TYPES.NUMBER, [ES_FIELD_TYPES.INTEGER]) + .convert(totalDocuments)} + {' '} + {i18n.translate('unifiedFieldList.fieldStats.ofDocumentsLabel', { + defaultMessage: 'documents', + })} + + ) : ( + <> + ); + + return ( + <> + {title ? title : <>} + + + + {el} + + {overrideFooter ? ( + overrideFooter?.({ element: countsElement, totalDocuments, sampledDocuments }) + ) : ( + <> + + {countsElement} + + )} + + ); + } + + if (histogram && histogram.buckets.length) { + const specId = i18n.translate('unifiedFieldList.fieldStats.countLabel', { + defaultMessage: 'Count', + }); + + if (field.type === 'date') { + return combineWithTitleAndFooter( + + + + + + + + ); + } + + if (showingHistogram || !topValues || !topValues.buckets.length) { + return combineWithTitleAndFooter( + + + + formatter.convert(d)} + /> + + + + ); + } + } + + if (topValues && topValues.buckets.length) { + const digitsRequired = topValues.buckets.some( + (topValue) => !Number.isInteger(topValue.count / sampledValues!) + ); + return combineWithTitleAndFooter( +
+ {topValues.buckets.map((topValue) => { + const formatted = formatter.convert(topValue.key); + return ( +
+ + + {formatted === '' ? ( + + + {i18n.translate('unifiedFieldList.fieldStats.emptyStringValueLabel', { + defaultMessage: 'Empty string', + })} + + + ) : ( + + + {formatted} + + + )} + + + + {(Math.round((topValue.count / sampledValues!) * 1000) / 10).toFixed( + digitsRequired ? 1 : 0 + )} + % + + + + +
+ ); + })} + {otherCount ? ( + <> + + + + {i18n.translate('unifiedFieldList.fieldStats.otherDocsLabel', { + defaultMessage: 'Other', + })} + + + + + + {(Math.round((otherCount / sampledValues!) * 1000) / 10).toFixed( + digitsRequired ? 1 : 0 + )} + % + + + + + + + ) : ( + <> + )} +
+ ); + } + + return null; +}; + +class ErrorBoundary extends React.Component<{}, { hasError: boolean }> { + constructor(props: FieldStatsProps) { + super(props); + this.state = { hasError: false }; + } + + static getDerivedStateFromError() { + return { hasError: true }; + } + + // componentDidCatch(error, errorInfo) { + // console.log(error, errorInfo); + // } + + render() { + if (this.state.hasError) { + return null; + } + + return this.props.children; + } +} + +/** + * Component which fetches and renders stats for a data view field + * @param props + * @constructor + */ +const FieldStats: React.FC = (props) => { + return ( + + + + ); +}; + +// Necessary for React.lazy +// eslint-disable-next-line import/no-default-export +export default FieldStats; diff --git a/src/plugins/unified_field_list/public/components/field_stats/index.tsx b/src/plugins/unified_field_list/public/components/field_stats/index.tsx new file mode 100755 index 00000000000000..0cfb29d4abd5fa --- /dev/null +++ b/src/plugins/unified_field_list/public/components/field_stats/index.tsx @@ -0,0 +1,22 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import React, { Fragment } from 'react'; +import type { FieldStatsProps, FieldStatsServices } from './field_stats'; + +const Fallback = () => ; + +const LazyFieldStats = React.lazy(() => import('./field_stats')); +const WrappedFieldStats: React.FC = (props) => ( + }> + + +); + +export const FieldStats = WrappedFieldStats; +export type { FieldStatsProps, FieldStatsServices }; diff --git a/src/plugins/unified_field_list/public/index.ts b/src/plugins/unified_field_list/public/index.ts new file mode 100755 index 00000000000000..f2f666dd474814 --- /dev/null +++ b/src/plugins/unified_field_list/public/index.ts @@ -0,0 +1,26 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { UnifiedFieldListPlugin } from './plugin'; + +export type { + FieldStatsResponse, + BucketedAggregation, + NumberStatsResult, + TopValuesResult, +} from '../common/types'; +export type { FieldStatsProps, FieldStatsServices } from './components/field_stats'; +export { FieldStats } from './components/field_stats'; +export { loadFieldStats } from './services/field_stats'; + +// This exports static code and TypeScript types, +// as well as, Kibana Platform `plugin()` initializer. +export function plugin() { + return new UnifiedFieldListPlugin(); +} +export type { UnifiedFieldListPluginSetup, UnifiedFieldListPluginStart } from './types'; diff --git a/src/plugins/unified_field_list/public/plugin.ts b/src/plugins/unified_field_list/public/plugin.ts new file mode 100755 index 00000000000000..009b73dd1c5759 --- /dev/null +++ b/src/plugins/unified_field_list/public/plugin.ts @@ -0,0 +1,25 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { CoreSetup, CoreStart, Plugin } from '@kbn/core/public'; +import { UnifiedFieldListPluginSetup, UnifiedFieldListPluginStart } from './types'; + +export class UnifiedFieldListPlugin + implements Plugin +{ + public setup(core: CoreSetup): UnifiedFieldListPluginSetup { + // Return methods that should be available to other plugins + return {}; + } + + public start(core: CoreStart): UnifiedFieldListPluginStart { + return {}; + } + + public stop() {} +} diff --git a/packages/shared-ux/button/exit_full_screen/mocks/jest.config.js b/src/plugins/unified_field_list/public/services/field_stats/index.tsx old mode 100644 new mode 100755 similarity index 56% rename from packages/shared-ux/button/exit_full_screen/mocks/jest.config.js rename to src/plugins/unified_field_list/public/services/field_stats/index.tsx index 3485a061a38ee0..644bca5a054d41 --- a/packages/shared-ux/button/exit_full_screen/mocks/jest.config.js +++ b/src/plugins/unified_field_list/public/services/field_stats/index.tsx @@ -6,8 +6,9 @@ * Side Public License, v 1. */ -module.exports = { - preset: '@kbn/test/jest_node', - rootDir: '../../../../..', - roots: ['/packages/shared-ux/button/exit_full_screen/mocks'], +import type { LoadFieldStatsHandler } from './load_field_stats'; + +export const loadFieldStats: LoadFieldStatsHandler = async (params) => { + const { loadFieldStats: loadFieldStatsHandler } = await import('./load_field_stats'); + return await loadFieldStatsHandler(params); }; diff --git a/src/plugins/unified_field_list/public/services/field_stats/load_field_stats.ts b/src/plugins/unified_field_list/public/services/field_stats/load_field_stats.ts new file mode 100644 index 00000000000000..fd38cd0bfca640 --- /dev/null +++ b/src/plugins/unified_field_list/public/services/field_stats/load_field_stats.ts @@ -0,0 +1,98 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { lastValueFrom } from 'rxjs'; +import type { DataView } from '@kbn/data-views-plugin/common'; +import type { DataPublicPluginStart } from '@kbn/data-plugin/public'; +import type { DataViewFieldBase } from '@kbn/es-query'; +import type { FieldStatsResponse } from '../../../common/types'; +import { + fetchAndCalculateFieldStats, + SearchHandler, + buildSearchParams, +} from '../../../common/utils/field_stats_utils'; + +interface FetchFieldStatsParams { + services: { + data: DataPublicPluginStart; + }; + dataView: DataView; + field: DataViewFieldBase; + fromDate: string; + toDate: string; + dslQuery: object; + size?: number; + abortController?: AbortController; +} + +export type LoadFieldStatsHandler = ( + params: FetchFieldStatsParams +) => Promise>; + +/** + * Loads and aggregates stats data for a data view field + * @param services + * @param dataView + * @param field + * @param fromDate + * @param toDate + * @param dslQuery + * @param size + * @param abortController + */ +export const loadFieldStats: LoadFieldStatsHandler = async ({ + services, + dataView, + field, + fromDate, + toDate, + dslQuery, + size, + abortController, +}) => { + const { data } = services; + + try { + if (!dataView?.id || !field?.type) { + return {}; + } + + const searchHandler: SearchHandler = async (aggs) => { + const result = await lastValueFrom( + data.search.search( + { + params: buildSearchParams({ + dataViewPattern: dataView.title, + timeFieldName: dataView.timeFieldName, + fromDate, + toDate, + dslQuery, + runtimeMappings: dataView.getRuntimeMappings(), + aggs, + }), + }, + { + abortSignal: abortController?.signal, + } + ) + ); + return result.rawResponse; + }; + + return await fetchAndCalculateFieldStats({ + searchHandler, + field, + fromDate, + toDate, + size, + }); + } catch (error) { + // console.error(error); + throw new Error('Could not provide field stats', { cause: error }); + } +}; diff --git a/src/plugins/shared_ux/server/types.ts b/src/plugins/unified_field_list/public/types.ts similarity index 60% rename from src/plugins/shared_ux/server/types.ts rename to src/plugins/unified_field_list/public/types.ts index b16a18467d3098..feb24509cdee59 100755 --- a/src/plugins/shared_ux/server/types.ts +++ b/src/plugins/unified_field_list/public/types.ts @@ -6,10 +6,8 @@ * Side Public License, v 1. */ -/* eslint-disable @typescript-eslint/no-empty-interface */ +// eslint-disable-next-line @typescript-eslint/no-empty-interface +export interface UnifiedFieldListPluginSetup {} -/** @internal */ -export interface SharedUXPluginSetup {} - -/** @internal */ -export interface SharedUXPluginStart {} +// eslint-disable-next-line @typescript-eslint/no-empty-interface +export interface UnifiedFieldListPluginStart {} diff --git a/src/plugins/shared_ux/server/index.ts b/src/plugins/unified_field_list/server/index.ts old mode 100755 new mode 100644 similarity index 58% rename from src/plugins/shared_ux/server/index.ts rename to src/plugins/unified_field_list/server/index.ts index 44c72b244aaf92..039ea0488b533d --- a/src/plugins/shared_ux/server/index.ts +++ b/src/plugins/unified_field_list/server/index.ts @@ -7,10 +7,18 @@ */ import { PluginInitializerContext } from '@kbn/core/server'; -import { SharedUXPlugin } from './plugin'; +import { UnifiedFieldListPlugin } from './plugin'; + +// This exports static code and TypeScript types, +// as well as, Kibana Platform `plugin()` initializer. export function plugin(initializerContext: PluginInitializerContext) { - return new SharedUXPlugin(initializerContext); + return new UnifiedFieldListPlugin(initializerContext); } -export type { SharedUXPluginSetup, SharedUXPluginStart } from './types'; +export type { + UnifiedFieldListServerPluginSetup, + UnifiedFieldListServerPluginStart, + PluginSetup, + PluginStart, +} from './types'; diff --git a/src/plugins/shared_ux/server/plugin.ts b/src/plugins/unified_field_list/server/plugin.ts old mode 100755 new mode 100644 similarity index 54% rename from src/plugins/shared_ux/server/plugin.ts rename to src/plugins/unified_field_list/server/plugin.ts index f0ea504884610f..2853afcf3d6fdc --- a/src/plugins/shared_ux/server/plugin.ts +++ b/src/plugins/unified_field_list/server/plugin.ts @@ -7,23 +7,33 @@ */ import { PluginInitializerContext, CoreSetup, CoreStart, Plugin, Logger } from '@kbn/core/server'; +import { + UnifiedFieldListServerPluginSetup, + UnifiedFieldListServerPluginStart, + PluginStart, + PluginSetup, +} from './types'; +import { defineRoutes } from './routes'; -import { SharedUXPluginSetup, SharedUXPluginStart } from './types'; - -export class SharedUXPlugin implements Plugin { +export class UnifiedFieldListPlugin + implements Plugin +{ private readonly logger: Logger; constructor(initializerContext: PluginInitializerContext) { this.logger = initializerContext.logger.get(); } - public setup(_core: CoreSetup) { - this.logger.debug('sharedUX: Setup'); + public setup(core: CoreSetup, plugins: PluginSetup) { + this.logger.debug('unifiedFieldList: Setup'); + + defineRoutes(core); + return {}; } - public start(_core: CoreStart) { - this.logger.debug('sharedUX: Started'); + public start(core: CoreStart, plugins: PluginStart) { + this.logger.debug('unifiedFieldList: Started'); return {}; } diff --git a/src/plugins/unified_field_list/server/routes/field_stats.ts b/src/plugins/unified_field_list/server/routes/field_stats.ts new file mode 100644 index 00000000000000..4fc654f8922101 --- /dev/null +++ b/src/plugins/unified_field_list/server/routes/field_stats.ts @@ -0,0 +1,104 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { errors } from '@elastic/elasticsearch'; +import { schema } from '@kbn/config-schema'; +import { CoreSetup } from '@kbn/core/server'; +import { SavedObjectNotFound } from '@kbn/kibana-utils-plugin/common'; +import { FIELD_STATS_API_PATH } from '../../common/constants'; +import type { PluginStart } from '../types'; +import { + fetchAndCalculateFieldStats, + SearchHandler, + buildSearchParams, +} from '../../common/utils/field_stats_utils'; + +export async function initFieldStatsRoute(setup: CoreSetup) { + const router = setup.http.createRouter(); + router.post( + { + path: FIELD_STATS_API_PATH, + validate: { + body: schema.object( + { + dslQuery: schema.object({}, { unknowns: 'allow' }), + fromDate: schema.string(), + toDate: schema.string(), + dataViewId: schema.string(), + fieldName: schema.string(), + size: schema.maybe(schema.number()), + }, + { unknowns: 'allow' } + ), + }, + }, + async (context, req, res) => { + const requestClient = (await context.core).elasticsearch.client.asCurrentUser; + const { fromDate, toDate, fieldName, dslQuery, size, dataViewId } = req.body; + + const [{ savedObjects, elasticsearch }, { dataViews }] = await setup.getStartServices(); + const savedObjectsClient = savedObjects.getScopedClient(req); + const esClient = elasticsearch.client.asScoped(req).asCurrentUser; + const indexPatternsService = await dataViews.dataViewsServiceFactory( + savedObjectsClient, + esClient + ); + + try { + const dataView = await indexPatternsService.get(dataViewId); + const field = dataView.fields.find((f) => f.name === fieldName); + + if (!field) { + throw new Error(`Field {fieldName} not found in data view ${dataView.title}`); + } + + const searchHandler: SearchHandler = async (aggs) => { + const result = await requestClient.search( + buildSearchParams({ + dataViewPattern: dataView.title, + timeFieldName: dataView.timeFieldName, + fromDate, + toDate, + dslQuery, + runtimeMappings: dataView.getRuntimeMappings(), + aggs, + }) + ); + return result; + }; + + const stats = await fetchAndCalculateFieldStats({ + searchHandler, + field, + fromDate, + toDate, + size, + }); + + return res.ok({ + body: stats, + }); + } catch (e) { + if (e instanceof SavedObjectNotFound) { + return res.notFound(); + } + if (e instanceof errors.ResponseError && e.statusCode === 404) { + return res.notFound(); + } + if (e.isBoom) { + if (e.output.statusCode === 404) { + return res.notFound(); + } + throw new Error(e.output.message); + } else { + throw e; + } + } + } + ); +} diff --git a/packages/kbn-shared-ux-services/src/services/application.ts b/src/plugins/unified_field_list/server/routes/index.ts similarity index 60% rename from packages/kbn-shared-ux-services/src/services/application.ts rename to src/plugins/unified_field_list/server/routes/index.ts index 89a7fa91fadc56..3558e93e4a7809 100644 --- a/packages/kbn-shared-ux-services/src/services/application.ts +++ b/src/plugins/unified_field_list/server/routes/index.ts @@ -6,9 +6,10 @@ * Side Public License, v 1. */ -import { Observable } from 'rxjs'; +import { CoreSetup } from '@kbn/core/server'; +import { PluginStart } from '../types'; +import { initFieldStatsRoute } from './field_stats'; -export interface SharedUxApplicationService { - navigateToUrl: (url: string) => Promise | void; - currentAppId$: Observable; +export function defineRoutes(setup: CoreSetup) { + initFieldStatsRoute(setup); } diff --git a/src/plugins/unified_field_list/server/types.ts b/src/plugins/unified_field_list/server/types.ts new file mode 100644 index 00000000000000..56cd69a01881ec --- /dev/null +++ b/src/plugins/unified_field_list/server/types.ts @@ -0,0 +1,22 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { PluginStart as DataViewsServerPluginStart } from '@kbn/data-views-plugin/server'; + +// eslint-disable-next-line @typescript-eslint/no-empty-interface +export interface UnifiedFieldListServerPluginSetup {} + +// eslint-disable-next-line @typescript-eslint/no-empty-interface +export interface UnifiedFieldListServerPluginStart {} + +// eslint-disable-next-line @typescript-eslint/no-empty-interface +export interface PluginSetup {} + +export interface PluginStart { + dataViews: DataViewsServerPluginStart; +} diff --git a/src/plugins/unified_field_list/tsconfig.json b/src/plugins/unified_field_list/tsconfig.json new file mode 100644 index 00000000000000..221729fbd2b719 --- /dev/null +++ b/src/plugins/unified_field_list/tsconfig.json @@ -0,0 +1,23 @@ +{ + "extends": "../../../tsconfig.base.json", + "compilerOptions": { + "outDir": "./target/types", + "emitDeclarationOnly": true, + "declaration": true, + "declarationMap": true + }, + "include": [ + "../../typings/**/*", + "common/**/*", + "public/**/*", + "server/**/*", + ], + "references": [ + { "path": "../../core/tsconfig.json" }, + { "path": "../kibana_utils/tsconfig.json" }, + { "path": "../kibana_react/tsconfig.json" }, + { "path": "../data_views/tsconfig.json" }, + { "path": "../data/tsconfig.json" }, + { "path": "../charts/tsconfig.json" } + ] +} diff --git a/src/plugins/unified_search/public/actions/apply_filter_action.ts b/src/plugins/unified_search/public/actions/apply_filter_action.ts index e890cd94375c30..4f2900944f827f 100644 --- a/src/plugins/unified_search/public/actions/apply_filter_action.ts +++ b/src/plugins/unified_search/public/actions/apply_filter_action.ts @@ -8,6 +8,7 @@ import { i18n } from '@kbn/i18n'; import { ThemeServiceSetup } from '@kbn/core/public'; +import type { IEmbeddable } from '@kbn/embeddable-plugin/public'; import { toMountPoint } from '@kbn/kibana-react-plugin/public'; import { Action, createAction, IncompatibleActionError } from '@kbn/ui-actions-plugin/public'; // for cleanup esFilters need to fix the issue https://github.com/elastic/kibana/issues/131292 @@ -21,9 +22,7 @@ export const ACTION_GLOBAL_APPLY_FILTER = 'ACTION_GLOBAL_APPLY_FILTER'; export interface ApplyGlobalFilterActionContext { filters: Filter[]; timeFieldName?: string; - // Need to make this unknown to prevent circular dependencies. - // Apps using this property will need to cast to `IEmbeddable`. - embeddable?: unknown; + embeddable?: IEmbeddable; // controlledBy is an optional key in filter.meta that identifies the owner of a filter // Pass controlledBy to cleanup an existing filter(s) owned by embeddable prior to adding new filters controlledBy?: string; diff --git a/src/plugins/unified_search/public/index_pattern_select/index_pattern_select.tsx b/src/plugins/unified_search/public/index_pattern_select/index_pattern_select.tsx index 81534575d10b18..7cd8b9d0251d85 100644 --- a/src/plugins/unified_search/public/index_pattern_select/index_pattern_select.tsx +++ b/src/plugins/unified_search/public/index_pattern_select/index_pattern_select.tsx @@ -78,10 +78,10 @@ export default class IndexPatternSelect extends Component { - const idsAndTitles = await this.props.indexPatternService.getIdsWithTitle(); + const dataViews = await this.props.indexPatternService.getIdsWithTitle(); if (!this.isMounted || searchValue !== this.state.searchValue) { return; } const options = []; - for (let i = 0; i < idsAndTitles.length; i++) { - if (idsAndTitles[i].title.toLowerCase().includes(searchValue.toLowerCase())) { + for (let i = 0; i < dataViews.length; i++) { + const label = dataViews[i].name ? dataViews[i].name : dataViews[i].title; + if (label && label.toLowerCase().includes(searchValue.toLowerCase())) { options.push({ - label: idsAndTitles[i].title, - value: idsAndTitles[i].id, + label, + value: dataViews[i].id, }); } } diff --git a/src/plugins/unified_search/tsconfig.json b/src/plugins/unified_search/tsconfig.json index 41dc76f1305be0..61b1f830588213 100644 --- a/src/plugins/unified_search/tsconfig.json +++ b/src/plugins/unified_search/tsconfig.json @@ -17,6 +17,7 @@ { "path": "../../core/tsconfig.json" }, { "path": "../data/tsconfig.json" }, { "path": "../data_views/tsconfig.json" }, + { "path": "../embeddable/tsconfig.json" }, { "path": "../usage_collection/tsconfig.json" }, { "path": "../kibana_utils/tsconfig.json" }, { "path": "../kibana_react/tsconfig.json" }, diff --git a/src/plugins/vis_types/table/public/components/table_vis_cell.tsx b/src/plugins/vis_types/table/public/components/table_vis_cell.tsx index e11700330b3343..586a534ef16e75 100644 --- a/src/plugins/vis_types/table/public/components/table_vis_cell.tsx +++ b/src/plugins/vis_types/table/public/components/table_vis_cell.tsx @@ -15,9 +15,10 @@ import { FormattedColumns } from '../types'; export const createTableVisCell = (rows: DatatableRow[], formattedColumns: FormattedColumns, autoFitRowToContent?: boolean) => ({ rowIndex, columnId }: EuiDataGridCellValueElementProps) => { - const rowValue = rows[rowIndex][columnId]; + // incoming data might change and put the current page out of bounds - check whether row actually exists + const rowValue = rows[rowIndex]?.[columnId]; const column = formattedColumns[columnId]; - const content = column.formatter.convert(rowValue, 'html'); + const content = column?.formatter.convert(rowValue, 'html'); const cellContent = (
{ - const rowValue = rows[rowIndex][columnId]; + // incoming data might change and put the current page out of bounds - check whether row actually exists + const rowValue = rows[rowIndex]?.[columnId]; if (rowValue == null) return null; const cellContent = formattedColumn.formatter.convert(rowValue); @@ -96,7 +97,8 @@ export const createGridColumns = ( ); }, ({ rowIndex, columnId, Component }: EuiDataGridColumnCellActionProps) => { - const rowValue = rows[rowIndex][columnId]; + // incoming data might change and put the current page out of bounds - check whether row actually exists + const rowValue = rows[rowIndex]?.[columnId]; if (rowValue == null) return null; const cellContent = formattedColumn.formatter.convert(rowValue); diff --git a/src/plugins/vis_types/timeseries/public/application/components/lib/convert_series_to_vars.js b/src/plugins/vis_types/timeseries/public/application/components/lib/convert_series_to_vars.js index 4ac63bd8704bcc..cccc21e7cbdb1e 100644 --- a/src/plugins/vis_types/timeseries/public/application/components/lib/convert_series_to_vars.js +++ b/src/plugins/vis_types/timeseries/public/application/components/lib/convert_series_to_vars.js @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import { set } from '@elastic/safer-lodash-set'; +import { set } from '@kbn/safer-lodash-set'; import { startsWith, snakeCase } from 'lodash'; import { BUCKET_TYPES, DATA_FORMATTERS } from '../../../../common/enums'; import { getLastValue } from '../../../../common/last_value_utils'; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/index.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/index.test.ts index c0ce9d5f8804e1..435335fe9dd25e 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/index.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/index.test.ts @@ -5,33 +5,9 @@ * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ -import type { DataView } from '@kbn/data-plugin/common'; -import type { Panel, Series } from '../../common/types'; -import { convertTSVBtoLensConfiguration } from '.'; - -const dataViewsMap: Record = { - test1: { id: 'test1', title: 'test1', timeFieldName: 'timeField1' } as DataView, - test2: { - id: 'test2', - title: 'test2', - timeFieldName: 'timeField2', - } as DataView, - test3: { id: 'test3', title: 'test3', timeFieldName: 'timeField3' } as DataView, -}; -const getDataview = (id: string): DataView | undefined => dataViewsMap[id]; -jest.mock('../services', () => { - return { - getDataViewsStart: jest.fn(() => { - return { - getDefault: jest.fn(() => { - return { id: '12345', title: 'default', timeFieldName: '@timestamp' }; - }), - get: getDataview, - }; - }), - }; -}); +import type { Panel } from '../../common/types'; +import { convertTSVBtoLensConfiguration } from '.'; const model = { axis_position: 'left', @@ -61,7 +37,7 @@ const model = { } as Panel; describe('convertTSVBtoLensConfiguration', () => { - test('should return null for a non timeseries chart', async () => { + test('should return null for a not supported chart', async () => { const metricModel = { ...model, type: 'metric', @@ -78,279 +54,4 @@ describe('convertTSVBtoLensConfiguration', () => { const triggerOptions = await convertTSVBtoLensConfiguration(stringIndexPatternModel); expect(triggerOptions).toBeNull(); }); - - test('should return null for a non supported aggregation', async () => { - const nonSupportedAggModel = { - ...model, - series: [ - { - ...model.series[0], - metrics: [ - { - type: 'std_deviation', - }, - ] as Series['metrics'], - }, - ], - }; - const triggerOptions = await convertTSVBtoLensConfiguration(nonSupportedAggModel); - expect(triggerOptions).toBeNull(); - }); - - test('should return options for a supported aggregation', async () => { - const triggerOptions = await convertTSVBtoLensConfiguration(model); - expect(triggerOptions).toStrictEqual({ - configuration: { - extents: { yLeftExtent: { mode: 'full' }, yRightExtent: { mode: 'full' } }, - fill: '0', - gridLinesVisibility: { x: false, yLeft: false, yRight: false }, - legend: { - isVisible: false, - maxLines: 1, - position: 'right', - shouldTruncate: false, - showSingleSeries: false, - }, - }, - type: 'lnsXY', - layers: { - '0': { - axisPosition: 'left', - chartType: 'line', - collapseFn: undefined, - indexPatternId: 'test2', - metrics: [ - { - agg: 'count', - color: '#000000', - fieldName: 'document', - isFullReference: false, - params: {}, - }, - ], - palette: { - name: 'default', - type: 'palette', - }, - splitWithDateHistogram: false, - timeFieldName: 'timeField2', - timeInterval: 'auto', - dropPartialBuckets: false, - }, - }, - }); - }); - - test('should return area for timeseries line chart with fill > 0', async () => { - const modelWithFill = { - ...model, - series: [ - { - ...model.series[0], - fill: '0.3', - stacked: 'none', - }, - ], - }; - const triggerOptions = await convertTSVBtoLensConfiguration(modelWithFill); - expect(triggerOptions?.layers[0].chartType).toBe('area'); - }); - - test('should return timeShift in the params if it is provided', async () => { - const modelWithFill = { - ...model, - series: [ - { - ...model.series[0], - offset_time: '1h', - }, - ], - }; - const triggerOptions = await convertTSVBtoLensConfiguration(modelWithFill); - expect(triggerOptions?.layers[0]?.metrics?.[0]?.params?.shift).toBe('1h'); - }); - - test('should return filter in the params if it is provided', async () => { - const modelWithFill = { - ...model, - series: [ - { - ...model.series[0], - filter: { - language: 'kuery', - query: 'test', - }, - }, - ], - }; - const triggerOptions = await convertTSVBtoLensConfiguration(modelWithFill); - expect(triggerOptions?.layers[0]?.metrics?.[0]?.params?.kql).toBe('test'); - }); - - test('should return splitFilters information if the chart is broken down by filters', async () => { - const modelWithSplitFilters = { - ...model, - series: [ - { - ...model.series[0], - split_mode: 'filters', - split_filters: [ - { - color: 'rgba(188,0,85,1)', - filter: { - language: 'kuery', - query: '', - }, - id: '89afac60-7d2b-11ec-917c-c18cd38d60b5', - }, - ], - }, - ], - }; - const triggerOptions = await convertTSVBtoLensConfiguration(modelWithSplitFilters); - expect(triggerOptions?.layers[0]?.splitFilters).toStrictEqual([ - { - color: 'rgba(188,0,85,1)', - filter: { - language: 'kuery', - query: '', - }, - id: '89afac60-7d2b-11ec-917c-c18cd38d60b5', - }, - ]); - }); - - test('should return termsParams information if the chart is broken down by terms including series agg collapse fn', async () => { - const modelWithTerms = { - ...model, - series: [ - { - ...model.series[0], - metrics: [ - ...model.series[0].metrics, - { - type: 'series_agg', - function: 'sum', - }, - ], - split_mode: 'terms', - terms_size: 6, - terms_direction: 'desc', - terms_order_by: '_key', - }, - ] as unknown as Series[], - }; - const triggerOptions = await convertTSVBtoLensConfiguration(modelWithTerms); - expect(triggerOptions?.layers[0]?.collapseFn).toStrictEqual('sum'); - expect(triggerOptions?.layers[0]?.termsParams).toStrictEqual({ - size: 6, - otherBucket: false, - orderDirection: 'desc', - orderBy: { type: 'alphabetical' }, - includeIsRegex: false, - excludeIsRegex: false, - parentFormat: { - id: 'terms', - }, - }); - }); - - test('should return include exclude information if the chart is broken down by terms', async () => { - const modelWithTerms = { - ...model, - series: [ - { - ...model.series[0], - split_mode: 'terms', - terms_size: 6, - terms_direction: 'desc', - terms_order_by: '_key', - terms_include: 't.*', - }, - ] as unknown as Series[], - }; - const triggerOptions = await convertTSVBtoLensConfiguration(modelWithTerms); - expect(triggerOptions?.layers[0]?.termsParams).toStrictEqual({ - size: 6, - otherBucket: false, - orderDirection: 'desc', - orderBy: { type: 'alphabetical' }, - includeIsRegex: true, - include: ['t.*'], - excludeIsRegex: false, - parentFormat: { - id: 'terms', - }, - }); - }); - - test('should return custom time interval if it is given', async () => { - const modelWithTerms = { - ...model, - interval: '1h', - }; - const triggerOptions = await convertTSVBtoLensConfiguration(modelWithTerms); - expect(triggerOptions?.layers[0]?.timeInterval).toBe('1h'); - }); - - test('should return dropPartialbuckets if enabled', async () => { - const modelWithDropBuckets = { - ...model, - drop_last_bucket: 1, - }; - const triggerOptions = await convertTSVBtoLensConfiguration(modelWithDropBuckets); - expect(triggerOptions?.layers[0]?.dropPartialBuckets).toBe(true); - }); - - test('should return the correct chart configuration', async () => { - const modelWithConfig = { - ...model, - show_legend: 1, - legend_position: 'bottom', - truncate_legend: 0, - show_grid: 1, - series: [{ ...model.series[0], fill: '0.3', separate_axis: 1, axis_position: 'right' }], - }; - const triggerOptions = await convertTSVBtoLensConfiguration(modelWithConfig); - expect(triggerOptions).toStrictEqual({ - configuration: { - extents: { yLeftExtent: { mode: 'full' }, yRightExtent: { mode: 'full' } }, - fill: '0.3', - gridLinesVisibility: { x: true, yLeft: true, yRight: true }, - legend: { - isVisible: true, - maxLines: 1, - position: 'bottom', - shouldTruncate: false, - showSingleSeries: true, - }, - }, - type: 'lnsXY', - layers: { - '0': { - axisPosition: 'right', - chartType: 'area_stacked', - collapseFn: undefined, - indexPatternId: 'test2', - metrics: [ - { - agg: 'count', - color: '#000000', - fieldName: 'document', - isFullReference: false, - params: {}, - }, - ], - palette: { - name: 'default', - type: 'palette', - }, - splitWithDateHistogram: false, - timeFieldName: 'timeField2', - timeInterval: 'auto', - dropPartialBuckets: false, - }, - }, - }); - }); }); diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/index.ts index 071001381f0f16..08806f42e19763 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/index.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/index.ts @@ -6,6 +6,7 @@ * Side Public License, v 1. */ +import { TimeRange } from '@kbn/data-plugin/common'; import type { Panel } from '../../common/types'; import { PANEL_TYPES } from '../../common/enums'; import { ConvertTsvbToLensVisualization } from './types'; @@ -18,6 +19,10 @@ const getConvertFnByType = ( const { convertToLens } = await import('./timeseries'); return convertToLens; }, + [PANEL_TYPES.TOP_N]: async () => { + const { convertToLens } = await import('./top_n'); + return convertToLens; + }, }; return convertionFns[type]?.(); @@ -28,12 +33,17 @@ const getConvertFnByType = ( * Returns the Lens model, only if it is supported. If not, it returns null. * In case of null, the menu item is disabled and the user can't navigate to Lens. */ -export const convertTSVBtoLensConfiguration = async (model: Panel) => { - // Disables the option for not timeseries charts, for the string mode and for series with annotations +export const convertTSVBtoLensConfiguration = async (model: Panel, timeRange?: TimeRange) => { + // Disables the option for not supported charts, for the string mode and for series with annotations if (!model.use_kibana_indexes || (model.annotations && model.annotations.length > 0)) { return null; } + // Disables if model is invalid + if (model.isModelInvalid) { + return null; + } + const convertFn = await getConvertFnByType(model.type); - return (await convertFn?.(model)) ?? null; + return (await convertFn?.(model, timeRange)) ?? null; }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/layers/get_layer.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/layers/get_layer.ts index 8483c6f2c31918..de4c61e54837ef 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/layers/get_layer.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/layers/get_layer.ts @@ -41,18 +41,21 @@ export const getLayerConfiguration = ( model: Panel, series: VisSeries, splitFields: string[], - timeField?: string, - splitWithDateHistogram?: boolean + xFieldName?: string, + xMode?: string, + splitWithDateHistogram?: boolean, + window?: string ): VisualizeEditorLayersContext => { const layer = model.series[layerIdx]; const palette = layer.palette as PaletteOutput; const splitFilters = convertSplitFilters(layer); const { metrics: metricsArray, seriesAgg } = series; const filter = convertFilter(layer); - const metrics = convertMetrics(layer, metricsArray, filter); + const metrics = convertMetrics(layer, metricsArray, filter, window); return { indexPatternId, - timeFieldName: timeField, + xFieldName, + xMode, chartType, axisPosition: layer.separate_axis ? layer.axis_position : model.axis_position, ...(layer.terms_field && { splitFields }), diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/filter_ratio_formula.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/filter_ratio_formula.ts index a132b861889fa8..c341351c664182 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/filter_ratio_formula.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/filter_ratio_formula.ts @@ -7,6 +7,7 @@ */ import type { Query } from '@kbn/es-query'; +import { addTimeRangeToFormula } from '.'; import type { Metric } from '../../../../common/types'; import { SUPPORTED_METRICS } from './supported_metrics'; @@ -14,15 +15,15 @@ const escapeQuotes = (str: string) => { return str?.replace(/'/g, "\\'"); }; -const constructFilterRationFormula = (operation: string, metric?: Query) => { +const constructFilterRationFormula = (operation: string, metric?: Query, window?: string) => { return `${operation}${metric?.language === 'lucene' ? 'lucene' : 'kql'}='${ metric?.query && typeof metric?.query === 'string' ? escapeQuotes(metric?.query) : metric?.query ?? '*' - }')`; + }'${addTimeRangeToFormula(window)})`; }; -export const getFilterRatioFormula = (currentMetric: Metric) => { +export const getFilterRatioFormula = (currentMetric: Metric, window?: string) => { // eslint-disable-next-line @typescript-eslint/naming-convention const { numerator, denominator, metric_agg, field } = currentMetric; let aggregation = SUPPORTED_METRICS.count; @@ -38,16 +39,18 @@ export const getFilterRatioFormula = (currentMetric: Metric) => { if (aggregation.name === 'counter_rate') { const numeratorFormula = constructFilterRationFormula( `${aggregation.name}(max('${field}',`, - numerator + numerator, + window ); const denominatorFormula = constructFilterRationFormula( `${aggregation.name}(max('${field}',`, - denominator + denominator, + window ); return `${numeratorFormula}) / ${denominatorFormula})`; } else { - const numeratorFormula = constructFilterRationFormula(operation, numerator); - const denominatorFormula = constructFilterRationFormula(operation, denominator); + const numeratorFormula = constructFilterRationFormula(operation, numerator, window); + const denominatorFormula = constructFilterRationFormula(operation, denominator, window); return `${numeratorFormula} / ${denominatorFormula}`; } }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/index.ts index 9a79fb804e3ba5..08a7599ba3f8df 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/index.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/index.ts @@ -13,3 +13,4 @@ export * from './parent_pipeline_formula'; export * from './sibling_pipeline_formula'; export * from './filter_ratio_formula'; export * from './parent_pipeline_series'; +export * from './validate_metrics'; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_converter.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_converter.ts index 65427bfa2a2689..6ea305fdface3c 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_converter.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_converter.ts @@ -27,7 +27,8 @@ export const convertFilter = (series: Series): Filter | void => { const convertMetric = ( series: Series, metric: VisualizeEditorLayersContext['metrics'][number], - filter: Filter | void + filter: Filter | void, + interval?: string ) => ({ ...metric, color: metric.color ?? series.color, @@ -35,11 +36,13 @@ const convertMetric = ( ...metric.params, ...(series.offset_time && { shift: series.offset_time }), ...(filter && filter), + ...(interval && { window: interval }), }, }); export const convertMetrics = ( series: Series, metrics: VisualizeEditorLayersContext['metrics'], - filter: Filter | void -) => metrics.map((metric) => convertMetric(series, metric, filter)); + filter: Filter | void, + interval?: string +) => metrics.map((metric) => convertMetric(series, metric, filter, interval)); diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.test.ts index 83922a54aa1113..b07bcecb7f7901 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.test.ts @@ -44,7 +44,7 @@ describe('getPercentilesSeries', () => { value: '90', }, ] as Metric['percentiles']; - const config = getPercentilesSeries(percentiles, 'bytes'); + const config = getPercentilesSeries(percentiles, 'everything', '', 'bytes'); expect(config).toStrictEqual([ { agg: 'percentile', @@ -82,7 +82,7 @@ describe('getPercentileRankSeries', () => { test('should return correct config for multiple percentile ranks', () => { const values = ['1', '5', '7'] as Metric['values']; const colors = ['#68BC00', 'rgba(0,63,188,1)', 'rgba(188,38,0,1)'] as Metric['colors']; - const config = getPercentileRankSeries(values, colors, 'day_of_week_i'); + const config = getPercentileRankSeries(values, colors, 'everything', '', 'day_of_week_i'); expect(config).toStrictEqual([ { agg: 'percentile_rank', diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.ts index fdc7f4ca2f6d01..400adb4571fb7c 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.ts @@ -6,18 +6,28 @@ * Side Public License, v 1. */ +import { utc } from 'moment'; +import { search } from '@kbn/data-plugin/public'; +import dateMath from '@kbn/datemath'; +import { TimeRange, UI_SETTINGS } from '@kbn/data-plugin/common'; +import { getUISettings } from '../../../services'; import type { Metric } from '../../../../common/types'; import { SUPPORTED_METRICS } from './supported_metrics'; import { getFilterRatioFormula } from './filter_ratio_formula'; import { getParentPipelineSeriesFormula } from './parent_pipeline_formula'; import { getSiblingPipelineSeriesFormula } from './sibling_pipeline_formula'; -export const getPercentilesSeries = (percentiles: Metric['percentiles'], fieldName?: string) => { +export const getPercentilesSeries = ( + percentiles: Metric['percentiles'], + splitMode: string, + layerColor: string, + fieldName?: string +) => { return percentiles?.map((percentile) => { return { agg: 'percentile', isFullReference: false, - color: percentile.color, + color: splitMode === 'everything' ? percentile.color : layerColor, fieldName: fieldName ?? 'document', params: { percentile: percentile.value }, }; @@ -27,19 +37,42 @@ export const getPercentilesSeries = (percentiles: Metric['percentiles'], fieldNa export const getPercentileRankSeries = ( values: Metric['values'], colors: Metric['colors'], + splitMode: string, + layerColor: string, fieldName?: string ) => { return values?.map((value, index) => { return { agg: 'percentile_rank', isFullReference: false, - color: colors?.[index], + color: splitMode === 'everything' ? colors?.[index] : layerColor, fieldName: fieldName ?? 'document', params: { value }, }; }); }; +export const getWindow = (interval?: string, timeRange?: TimeRange) => { + let window = interval || '1h'; + + if (timeRange && !interval) { + const { from, to } = timeRange; + const timerange = utc(to).valueOf() - utc(from).valueOf(); + const maxBars = getUISettings().get(UI_SETTINGS.HISTOGRAM_BAR_TARGET); + + const duration = search.aggs.calcAutoIntervalLessThan(maxBars, timerange); + const unit = + dateMath.units.find((u) => { + const value = duration.as(u); + return Number.isInteger(value); + }) || 'ms'; + + window = `${duration.as(unit)}${unit}`; + } + + return window; +}; + export const getTimeScale = (metric: Metric) => { const supportedTimeScales = ['1s', '1m', '1h', '1d']; let timeScale; @@ -60,6 +93,10 @@ export const getFormulaSeries = (script: string) => { ]; }; +export const addTimeRangeToFormula = (window?: string) => { + return window ? `, timeRange='${window}'` : ''; +}; + export const getPipelineAgg = (subFunctionMetric: Metric) => { const pipelineAggMap = SUPPORTED_METRICS[subFunctionMetric.type]; if (!pipelineAggMap) { @@ -71,7 +108,8 @@ export const getPipelineAgg = (subFunctionMetric: Metric) => { export const getFormulaEquivalent = ( currentMetric: Metric, metrics: Metric[], - metaValue?: number + metaValue?: number, + window?: string ) => { const aggregation = SUPPORTED_METRICS[currentMetric.type]?.name; switch (currentMetric.type) { @@ -80,7 +118,7 @@ export const getFormulaEquivalent = ( case 'min_bucket': case 'sum_bucket': case 'positive_only': { - return getSiblingPipelineSeriesFormula(currentMetric.type, currentMetric, metrics); + return getSiblingPipelineSeriesFormula(currentMetric.type, currentMetric, metrics, window); } case 'count': { return `${aggregation}()`; @@ -88,10 +126,12 @@ export const getFormulaEquivalent = ( case 'percentile': { return `${aggregation}(${currentMetric.field}${ metaValue ? `, percentile=${metaValue}` : '' - })`; + }${addTimeRangeToFormula(window)})`; } case 'percentile_rank': { - return `${aggregation}(${currentMetric.field}${metaValue ? `, value=${metaValue}` : ''})`; + return `${aggregation}(${currentMetric.field}${ + metaValue ? `, value=${metaValue}` : '' + }${addTimeRangeToFormula(window)})`; } case 'cumulative_sum': case 'derivative': @@ -110,20 +150,34 @@ export const getFormulaEquivalent = ( subFunctionMetric, pipelineAgg, currentMetric.type, - metaValue + metaValue, + window ); } case 'positive_rate': { - return `${aggregation}(max(${currentMetric.field}))`; + return `${aggregation}(max(${currentMetric.field}${addTimeRangeToFormula(window)}))`; } case 'filter_ratio': { - return getFilterRatioFormula(currentMetric); + return getFilterRatioFormula(currentMetric, window); } case 'static': { return `${currentMetric.value}`; } - default: { + case 'std_deviation': { + if (currentMetric.mode === 'lower') { + return `average(${currentMetric.field}${addTimeRangeToFormula(window)}) - ${ + currentMetric.sigma || 1.5 + } * ${aggregation}(${currentMetric.field}${addTimeRangeToFormula(window)})`; + } + if (currentMetric.mode === 'upper') { + return `average(${currentMetric.field}${addTimeRangeToFormula(window)}) + ${ + currentMetric.sigma || 1.5 + } * ${aggregation}(${currentMetric.field}${addTimeRangeToFormula(window)})`; + } return `${aggregation}(${currentMetric.field})`; } + default: { + return `${aggregation}(${currentMetric.field}${addTimeRangeToFormula(window)})`; + } } }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_formula.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_formula.ts index e00fe505df1fdf..7d12e77fdb8bc6 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_formula.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_formula.ts @@ -8,14 +8,15 @@ import type { Metric, MetricType } from '../../../../common/types'; import { SUPPORTED_METRICS } from './supported_metrics'; -import { getFilterRatioFormula } from './filter_ratio_formula'; +import { getFormulaEquivalent } from './metrics_helpers'; export const getParentPipelineSeriesFormula = ( metrics: Metric[], subFunctionMetric: Metric, pipelineAgg: string, aggregation: MetricType, - percentileValue?: number + percentileValue?: number, + window?: string ) => { let formula = ''; const aggregationMap = SUPPORTED_METRICS[aggregation]; @@ -42,28 +43,13 @@ export const getParentPipelineSeriesFormula = ( additionalSubFunction.field ?? '' }${additionalFunctionArgs ?? ''})))`; } else { - let additionalFunctionArgs; - if (pipelineAgg === 'percentile' && percentileValue) { - additionalFunctionArgs = `, percentile=${percentileValue}`; - } - if (pipelineAgg === 'percentile_rank' && percentileValue) { - additionalFunctionArgs = `, value=${percentileValue}`; - } - if (pipelineAgg === 'filter_ratio') { - const script = getFilterRatioFormula(subFunctionMetric); - if (!script) { - return null; - } - formula = `${aggregationMap.name}(${script}${additionalFunctionArgs ?? ''})`; - } else if (pipelineAgg === 'counter_rate') { - formula = `${aggregationMap.name}(${pipelineAgg}(max(${subFunctionMetric.field}${ - additionalFunctionArgs ? `${additionalFunctionArgs}` : '' - })))`; - } else { - formula = `${aggregationMap.name}(${pipelineAgg}(${subFunctionMetric.field}${ - additionalFunctionArgs ? `${additionalFunctionArgs}` : '' - }))`; + const subFormula = getFormulaEquivalent(subFunctionMetric, metrics, percentileValue, window); + + if (!subFormula) { + return null; } + + formula = `${aggregationMap.name}(${subFormula})`; } return formula; }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_series.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_series.test.ts index 40264b89491b77..db8faccf5976f7 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_series.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_series.test.ts @@ -91,7 +91,7 @@ describe('getParentPipelineSeries', () => { { field: 'AvgTicketPrice', id: '04558549-f19f-4a87-9923-27df8b81af3e', - type: 'std_deviation', + type: 'sum_of_squares_bucket', }, { field: '04558549-f19f-4a87-9923-27df8b81af3e', diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_series.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_series.ts index 6a263ca8bb44de..6f0caf3837b5ca 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_series.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_series.ts @@ -17,11 +17,12 @@ export const computeParentSeries = ( currentMetric: Metric, subFunctionMetric: Metric, pipelineAgg: string, - meta?: number + meta?: number, + window?: string ) => { const aggregationMap = SUPPORTED_METRICS[aggregation]; if (subFunctionMetric.type === 'filter_ratio') { - const script = getFilterRatioFormula(subFunctionMetric); + const script = getFilterRatioFormula(subFunctionMetric, window); if (!script) { return null; } @@ -49,7 +50,8 @@ export const computeParentSeries = ( export const getParentPipelineSeries = ( aggregation: MetricType, currentMetricIdx: number, - metrics: Metric[] + metrics: Metric[], + window?: string ) => { const currentMetric = metrics[currentMetricIdx]; // percentile value is derived from the field Id. It has the format xxx-xxx-xxx-xxx[percentile] @@ -73,7 +75,8 @@ export const getParentPipelineSeries = ( subFunctionMetric, pipelineAgg, aggregation, - metaValue + metaValue, + window ); if (!formula) { return null; @@ -85,7 +88,8 @@ export const getParentPipelineSeries = ( currentMetric, subFunctionMetric, pipelineAgg, - metaValue + metaValue, + window ); } }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/sibling_pipeline_formula.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/sibling_pipeline_formula.ts index b3e141b11e598e..4243d6c0dd27cf 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/sibling_pipeline_formula.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/sibling_pipeline_formula.ts @@ -7,12 +7,14 @@ */ import type { Metric, MetricType } from '../../../../common/types'; +import { getFormulaEquivalent } from './metrics_helpers'; import { SUPPORTED_METRICS } from './supported_metrics'; export const getSiblingPipelineSeriesFormula = ( aggregation: MetricType, currentMetric: Metric, - metrics: Metric[] + metrics: Metric[], + window?: string ) => { const [nestedFieldId, nestedMeta] = currentMetric.field?.split('[') ?? []; const subFunctionMetric = metrics.find((metric) => metric.id === nestedFieldId); @@ -43,18 +45,15 @@ export const getSiblingPipelineSeriesFormula = ( additionalSubFunctionField ?? '' }))${minimumValue})`; } else { - let additionalFunctionArgs; - // handle percentile and percentile_rank const nestedMetaValue = Number(nestedMeta?.replace(']', '')); - if (pipelineAggMap.name === 'percentile' && nestedMetaValue) { - additionalFunctionArgs = `, percentile=${nestedMetaValue}`; - } - if (pipelineAggMap.name === 'percentile_rank' && nestedMetaValue) { - additionalFunctionArgs = `, value=${nestedMetaValue}`; + + const subFormula = getFormulaEquivalent(subFunctionMetric, metrics, nestedMetaValue, window); + + if (!subFormula) { + return null; } - formula += `${pipelineAggMap.name}(${subMetricField ?? ''}${ - additionalFunctionArgs ? `${additionalFunctionArgs}` : '' - })${minimumValue})`; + + formula += `${subFormula}${minimumValue})`; } return formula; }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/supported_metrics.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/supported_metrics.ts index 29bf2008e208d2..a5a50f5f032cf8 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/supported_metrics.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/supported_metrics.ts @@ -6,9 +6,13 @@ * Side Public License, v 1. */ +import { PANEL_TYPES, TIME_RANGE_DATA_MODES } from '../../../../common/enums'; interface AggOptions { name: string; isFullReference: boolean; + isFieldRequired: boolean; + supportedPanelTypes: string[]; + supportedTimeRangeModes: string[]; } // list of supported TSVB aggregation types in Lens @@ -19,85 +23,207 @@ export const SUPPORTED_METRICS: { [key: string]: AggOptions } = { avg: { name: 'average', isFullReference: false, + isFieldRequired: true, + supportedPanelTypes: [PANEL_TYPES.TIMESERIES, PANEL_TYPES.TOP_N], + supportedTimeRangeModes: [ + TIME_RANGE_DATA_MODES.ENTIRE_TIME_RANGE, + TIME_RANGE_DATA_MODES.LAST_VALUE, + ], }, cardinality: { name: 'unique_count', isFullReference: false, + isFieldRequired: true, + supportedPanelTypes: [PANEL_TYPES.TIMESERIES, PANEL_TYPES.TOP_N], + supportedTimeRangeModes: [ + TIME_RANGE_DATA_MODES.ENTIRE_TIME_RANGE, + TIME_RANGE_DATA_MODES.LAST_VALUE, + ], }, count: { name: 'count', isFullReference: false, + isFieldRequired: false, + supportedPanelTypes: [PANEL_TYPES.TIMESERIES, PANEL_TYPES.TOP_N], + supportedTimeRangeModes: [ + TIME_RANGE_DATA_MODES.ENTIRE_TIME_RANGE, + TIME_RANGE_DATA_MODES.LAST_VALUE, + ], }, positive_rate: { name: 'counter_rate', isFullReference: true, + isFieldRequired: true, + supportedPanelTypes: [PANEL_TYPES.TIMESERIES], + supportedTimeRangeModes: [ + TIME_RANGE_DATA_MODES.ENTIRE_TIME_RANGE, + TIME_RANGE_DATA_MODES.LAST_VALUE, + ], }, moving_average: { name: 'moving_average', isFullReference: true, + isFieldRequired: true, + supportedPanelTypes: [PANEL_TYPES.TIMESERIES], + supportedTimeRangeModes: [TIME_RANGE_DATA_MODES.ENTIRE_TIME_RANGE], }, derivative: { name: 'differences', isFullReference: true, + isFieldRequired: true, + supportedPanelTypes: [PANEL_TYPES.TIMESERIES], + supportedTimeRangeModes: [TIME_RANGE_DATA_MODES.ENTIRE_TIME_RANGE], }, cumulative_sum: { name: 'cumulative_sum', isFullReference: true, + isFieldRequired: true, + supportedPanelTypes: [PANEL_TYPES.TIMESERIES], + supportedTimeRangeModes: [TIME_RANGE_DATA_MODES.ENTIRE_TIME_RANGE], }, avg_bucket: { name: 'overall_average', isFullReference: true, + isFieldRequired: true, + supportedPanelTypes: [PANEL_TYPES.TIMESERIES], + supportedTimeRangeModes: [TIME_RANGE_DATA_MODES.ENTIRE_TIME_RANGE], }, max_bucket: { name: 'overall_max', isFullReference: true, + isFieldRequired: true, + supportedPanelTypes: [PANEL_TYPES.TIMESERIES], + supportedTimeRangeModes: [TIME_RANGE_DATA_MODES.ENTIRE_TIME_RANGE], }, min_bucket: { name: 'overall_min', isFullReference: true, + isFieldRequired: true, + supportedPanelTypes: [PANEL_TYPES.TIMESERIES], + supportedTimeRangeModes: [TIME_RANGE_DATA_MODES.ENTIRE_TIME_RANGE], }, sum_bucket: { name: 'overall_sum', isFullReference: true, + isFieldRequired: true, + supportedPanelTypes: [PANEL_TYPES.TIMESERIES], + supportedTimeRangeModes: [TIME_RANGE_DATA_MODES.ENTIRE_TIME_RANGE], }, max: { name: 'max', isFullReference: false, + isFieldRequired: true, + supportedPanelTypes: [PANEL_TYPES.TIMESERIES, PANEL_TYPES.TOP_N], + supportedTimeRangeModes: [ + TIME_RANGE_DATA_MODES.ENTIRE_TIME_RANGE, + TIME_RANGE_DATA_MODES.LAST_VALUE, + ], }, min: { name: 'min', isFullReference: false, + isFieldRequired: true, + supportedPanelTypes: [PANEL_TYPES.TIMESERIES, PANEL_TYPES.TOP_N], + supportedTimeRangeModes: [ + TIME_RANGE_DATA_MODES.ENTIRE_TIME_RANGE, + TIME_RANGE_DATA_MODES.LAST_VALUE, + ], }, percentile: { name: 'percentile', isFullReference: false, + isFieldRequired: true, + supportedPanelTypes: [PANEL_TYPES.TIMESERIES, PANEL_TYPES.TOP_N], + supportedTimeRangeModes: [ + TIME_RANGE_DATA_MODES.ENTIRE_TIME_RANGE, + TIME_RANGE_DATA_MODES.LAST_VALUE, + ], }, percentile_rank: { name: 'percentile_rank', isFullReference: false, + isFieldRequired: true, + supportedPanelTypes: [PANEL_TYPES.TIMESERIES, PANEL_TYPES.TOP_N], + supportedTimeRangeModes: [ + TIME_RANGE_DATA_MODES.ENTIRE_TIME_RANGE, + TIME_RANGE_DATA_MODES.LAST_VALUE, + ], }, sum: { name: 'sum', isFullReference: false, + isFieldRequired: true, + supportedPanelTypes: [PANEL_TYPES.TIMESERIES, PANEL_TYPES.TOP_N], + supportedTimeRangeModes: [ + TIME_RANGE_DATA_MODES.ENTIRE_TIME_RANGE, + TIME_RANGE_DATA_MODES.LAST_VALUE, + ], }, filter_ratio: { name: 'filter_ratio', isFullReference: false, + isFieldRequired: false, + supportedPanelTypes: [PANEL_TYPES.TIMESERIES, PANEL_TYPES.TOP_N], + supportedTimeRangeModes: [ + TIME_RANGE_DATA_MODES.ENTIRE_TIME_RANGE, + TIME_RANGE_DATA_MODES.LAST_VALUE, + ], }, top_hit: { name: 'last_value', isFullReference: false, + isFieldRequired: true, + supportedPanelTypes: [PANEL_TYPES.TIMESERIES, PANEL_TYPES.TOP_N], + supportedTimeRangeModes: [ + TIME_RANGE_DATA_MODES.ENTIRE_TIME_RANGE, + TIME_RANGE_DATA_MODES.LAST_VALUE, + ], }, math: { name: 'formula', isFullReference: true, + isFieldRequired: false, + supportedPanelTypes: [PANEL_TYPES.TIMESERIES, PANEL_TYPES.TOP_N], + supportedTimeRangeModes: [ + TIME_RANGE_DATA_MODES.ENTIRE_TIME_RANGE, + TIME_RANGE_DATA_MODES.LAST_VALUE, + ], }, positive_only: { name: 'pick_max', isFullReference: true, + isFieldRequired: true, + supportedPanelTypes: [PANEL_TYPES.TIMESERIES], + supportedTimeRangeModes: [TIME_RANGE_DATA_MODES.ENTIRE_TIME_RANGE], }, static: { name: 'static_value', isFullReference: true, + isFieldRequired: false, + supportedPanelTypes: [PANEL_TYPES.TIMESERIES, PANEL_TYPES.TOP_N], + supportedTimeRangeModes: [ + TIME_RANGE_DATA_MODES.ENTIRE_TIME_RANGE, + TIME_RANGE_DATA_MODES.LAST_VALUE, + ], + }, + value_count: { + name: 'count', + isFullReference: false, + isFieldRequired: true, + supportedPanelTypes: [PANEL_TYPES.TIMESERIES, PANEL_TYPES.TOP_N], + supportedTimeRangeModes: [ + TIME_RANGE_DATA_MODES.ENTIRE_TIME_RANGE, + TIME_RANGE_DATA_MODES.LAST_VALUE, + ], + }, + std_deviation: { + name: 'standard_deviation', + isFullReference: false, + isFieldRequired: true, + supportedPanelTypes: [PANEL_TYPES.TIMESERIES, PANEL_TYPES.TOP_N], + supportedTimeRangeModes: [ + TIME_RANGE_DATA_MODES.ENTIRE_TIME_RANGE, + TIME_RANGE_DATA_MODES.LAST_VALUE, + ], }, }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/validate_metrics.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/validate_metrics.ts new file mode 100644 index 00000000000000..adcc2e9a94664c --- /dev/null +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/validate_metrics.ts @@ -0,0 +1,43 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { Metric } from '../../../../common/types'; +import { SUPPORTED_METRICS } from '.'; + +const isMetricValid = ( + metricType: string, + panelType: string, + field?: string, + timeRangeMode?: string +) => { + const isMetricSupported = SUPPORTED_METRICS[metricType]; + if (!isMetricSupported) { + return false; + } + const isPanelTypeSupported = + SUPPORTED_METRICS[metricType].supportedPanelTypes.includes(panelType); + const isTimeRangeModeSupported = + !timeRangeMode || SUPPORTED_METRICS[metricType].supportedTimeRangeModes.includes(timeRangeMode); + return ( + isPanelTypeSupported && + isTimeRangeModeSupported && + (!SUPPORTED_METRICS[metricType].isFieldRequired || field) + ); +}; + +export const isValidMetrics = (metrics: Metric[], panelType: string, timeRangeMode?: string) => { + return metrics.every((metric) => { + const isMetricAggValid = + metric.type !== 'filter_ratio' || + isMetricValid(metric.metric_agg || 'count', panelType, metric.field, timeRangeMode); + return ( + metric.type === 'series_agg' || + (isMetricValid(metric.type, panelType, metric.field, timeRangeMode) && isMetricAggValid) + ); + }); +}; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/get_series.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/get_series.test.ts index aeb401e86dd012..80b7ba29b24c7b 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/get_series.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/get_series.test.ts @@ -5,6 +5,7 @@ * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ + import type { Metric } from '../../../../common/types'; import { getSeries } from './get_series'; @@ -17,7 +18,7 @@ describe('getSeries', () => { field: 'day_of_week_i', }, ] as Metric[]; - const config = getSeries(metric, 1)!.metrics; + const config = getSeries(metric, 1, 'everything', '')!.metrics; expect(config).toStrictEqual([ { agg: 'average', @@ -44,7 +45,7 @@ describe('getSeries', () => { }, }, ] as Metric[]; - const config = getSeries(metric, 1)!.metrics; + const config = getSeries(metric, 1, 'everything', '')!.metrics; expect(config).toStrictEqual([ { agg: 'formula', @@ -71,7 +72,7 @@ describe('getSeries', () => { field: '123456', }, ] as Metric[]; - const config = getSeries(metric, 1)!.metrics; + const config = getSeries(metric, 1, 'everything', '')!.metrics; expect(config).toStrictEqual([ { agg: 'formula', @@ -97,7 +98,7 @@ describe('getSeries', () => { field: '123456', }, ] as Metric[]; - const config = getSeries(metric, 1)!.metrics; + const config = getSeries(metric, 1, 'everything', '')!.metrics; expect(config).toStrictEqual([ { agg: 'formula', @@ -122,7 +123,7 @@ describe('getSeries', () => { field: '123456', }, ] as Metric[]; - const config = getSeries(metric, 1)!.metrics; + const config = getSeries(metric, 1, 'everything', '')!.metrics; expect(config).toStrictEqual([ { agg: 'cumulative_sum', @@ -147,7 +148,7 @@ describe('getSeries', () => { field: '123456', }, ] as Metric[]; - const config = getSeries(metric, 1)!.metrics; + const config = getSeries(metric, 1, 'everything', '')!.metrics; expect(config).toStrictEqual([ { agg: 'formula', @@ -174,7 +175,7 @@ describe('getSeries', () => { unit: '1m', }, ] as Metric[]; - const config = getSeries(metric, 1)!.metrics; + const config = getSeries(metric, 1, 'everything', '')!.metrics; expect(config).toStrictEqual([ { agg: 'differences', @@ -202,7 +203,7 @@ describe('getSeries', () => { window: 6, }, ] as Metric[]; - const config = getSeries(metric, 1)!.metrics; + const config = getSeries(metric, 1, 'everything', '')!.metrics; expect(config).toStrictEqual([ { agg: 'moving_average', @@ -246,7 +247,7 @@ describe('getSeries', () => { window: 6, }, ] as Metric[]; - const config = getSeries(metric, 1)!.metrics; + const config = getSeries(metric, 1, 'everything', '')!.metrics; expect(config).toStrictEqual([ { agg: 'formula', @@ -293,7 +294,7 @@ describe('getSeries', () => { ], }, ] as Metric[]; - const config = getSeries(metric, 1)!.metrics; + const config = getSeries(metric, 1, 'everything', '')!.metrics; expect(config).toStrictEqual([ { agg: 'percentile', @@ -335,7 +336,7 @@ describe('getSeries', () => { colors: ['rgba(211,96,134,1)', 'rgba(155,33,230,1)', '#68BC00'], }, ] as Metric[]; - const config = getSeries(metric, 1)!.metrics; + const config = getSeries(metric, 1, 'everything', '')!.metrics; expect(config).toStrictEqual([ { agg: 'percentile_rank', @@ -377,7 +378,7 @@ describe('getSeries', () => { order_by: 'timestamp', }, ] as Metric[]; - const config = getSeries(metric, 1)!.metrics; + const config = getSeries(metric, 1, 'everything', '')!.metrics; expect(config).toStrictEqual([ { agg: 'last_value', @@ -405,7 +406,7 @@ describe('getSeries', () => { function: 'mean', }, ] as Metric[]; - const config = getSeries(metric, 1)!; + const config = getSeries(metric, 1, 'everything', '')!; expect(config).toStrictEqual({ metrics: [ { @@ -430,7 +431,7 @@ describe('getSeries', () => { size: 2, }, ] as Metric[]; - const config = getSeries(metric, 1); + const config = getSeries(metric, 1, 'everything', ''); expect(config).toBeNull(); }); @@ -442,7 +443,7 @@ describe('getSeries', () => { value: '10', }, ] as Metric[]; - const config = getSeries(metric, 1); + const config = getSeries(metric, 1, 'everything', ''); expect(config).toBeNull(); }); @@ -454,7 +455,7 @@ describe('getSeries', () => { value: '10', }, ] as Metric[]; - const config = getSeries(metric, 2)!.metrics; + const config = getSeries(metric, 2, 'everything', '')!.metrics; expect(config).toStrictEqual([ { agg: 'static_value', @@ -521,7 +522,7 @@ describe('getSeries', () => { ], }, ] as Metric[]; - const config = getSeries(metric, 1)!.metrics; + const config = getSeries(metric, 1, 'everything', '')!.metrics; expect(config).toStrictEqual([ { agg: 'formula', @@ -572,7 +573,7 @@ describe('getSeries', () => { ], }, ] as Metric[]; - const config = getSeries(metric, 1)!.metrics; + const config = getSeries(metric, 1, 'everything', '')!.metrics; expect(config).toStrictEqual([ { agg: 'formula', diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/get_series.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/get_series.ts index 0db270b465719a..a5c4bbfbc548d5 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/get_series.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/get_series.ts @@ -28,7 +28,13 @@ export interface VisSeries { seriesAgg?: string; } -export const getSeries = (initialMetrics: Metric[], totalSeriesNum: number): VisSeries | null => { +export const getSeries = ( + initialMetrics: Metric[], + totalSeriesNum: number, + splitMode: string, + layerColor: string, + window?: string +): VisSeries | null => { const { metrics, seriesAgg } = getSeriesAgg(initialMetrics); const metricIdx = metrics.length - 1; const aggregation = metrics[metricIdx].type; @@ -44,6 +50,8 @@ export const getSeries = (initialMetrics: Metric[], totalSeriesNum: number): Vis if (percentiles?.length) { const percentilesSeries = getPercentilesSeries( percentiles, + splitMode, + layerColor, fieldName ) as VisualizeEditorLayersContext['metrics']; metricsArray = [...metricsArray, ...percentilesSeries]; @@ -57,6 +65,8 @@ export const getSeries = (initialMetrics: Metric[], totalSeriesNum: number): Vis const percentileRanksSeries = getPercentileRankSeries( values, colors, + splitMode, + layerColor, fieldName ) as VisualizeEditorLayersContext['metrics']; metricsArray = [...metricsArray, ...percentileRanksSeries]; @@ -92,12 +102,17 @@ export const getSeries = (initialMetrics: Metric[], totalSeriesNum: number): Vis const [_, meta] = variable?.field?.split('[') ?? []; const metaValue = Number(meta?.replace(']', '')); if (!metaValue) return; - const script = getFormulaEquivalent(currentMetric, layerMetricsArray, metaValue); + const script = getFormulaEquivalent( + currentMetric, + layerMetricsArray, + metaValue, + window + ); if (!script) return; finalScript = finalScript?.replace(`params.${variable.name}`, script); }); } else { - const script = getFormulaEquivalent(currentMetric, layerMetricsArray); + const script = getFormulaEquivalent(currentMetric, layerMetricsArray, undefined, window); if (!script) return null; const variable = variables.find((v) => v.field === currentMetric.id); finalScript = finalScript?.replaceAll(`params.${variable?.name}`, script); @@ -113,7 +128,8 @@ export const getSeries = (initialMetrics: Metric[], totalSeriesNum: number): Vis metricsArray = getParentPipelineSeries( aggregation, metricIdx, - metrics + metrics, + window ) as VisualizeEditorLayersContext['metrics']; break; } @@ -137,7 +153,8 @@ export const getSeries = (initialMetrics: Metric[], totalSeriesNum: number): Vis subFunctionMetric, pipelineAgg, aggregation, - metaValue + metaValue, + window ); if (!formula) return null; metricsArray = getFormulaSeries(formula); @@ -146,7 +163,9 @@ export const getSeries = (initialMetrics: Metric[], totalSeriesNum: number): Vis aggregation, metrics[metricIdx], subFunctionMetric, - pipelineAgg + pipelineAgg, + undefined, + window ); if (!series) return null; metricsArray = series; @@ -154,7 +173,12 @@ export const getSeries = (initialMetrics: Metric[], totalSeriesNum: number): Vis break; } case 'positive_only': { - const formula = getSiblingPipelineSeriesFormula(aggregation, metrics[metricIdx], metrics); + const formula = getSiblingPipelineSeriesFormula( + aggregation, + metrics[metricIdx], + metrics, + window + ); if (!formula) { return null; } @@ -165,7 +189,12 @@ export const getSeries = (initialMetrics: Metric[], totalSeriesNum: number): Vis case 'max_bucket': case 'min_bucket': case 'sum_bucket': { - const formula = getSiblingPipelineSeriesFormula(aggregation, metrics[metricIdx], metrics); + const formula = getSiblingPipelineSeriesFormula( + aggregation, + metrics[metricIdx], + metrics, + window + ); if (!formula) { return null; } @@ -173,7 +202,7 @@ export const getSeries = (initialMetrics: Metric[], totalSeriesNum: number): Vis break; } case 'filter_ratio': { - const formula = getFilterRatioFormula(metrics[metricIdx]); + const formula = getFilterRatioFormula(metrics[metricIdx], window); if (!formula) { return null; } @@ -221,6 +250,25 @@ export const getSeries = (initialMetrics: Metric[], totalSeriesNum: number): Vis ]; break; } + case 'std_deviation': { + const currentMetric = metrics[metricIdx]; + if (currentMetric.mode === 'upper' || currentMetric.mode === 'lower') { + const script = getFormulaEquivalent(currentMetric, metrics, undefined, window); + if (!script) return null; + metricsArray = getFormulaSeries(script); + break; + } else if (currentMetric.mode === 'band') { + [ + { ...currentMetric, mode: 'upper' }, + { ...currentMetric, mode: 'lower' }, + ].forEach((metric) => { + const script = getFormulaEquivalent(metric, metrics, undefined, window); + if (!script) return null; + metricsArray.push(...getFormulaSeries(script)); + }); + break; + } + } default: { const timeScale = getTimeScale(metrics[metricIdx]); metricsArray = [ diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/index.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/index.test.ts new file mode 100644 index 00000000000000..7593018a22593c --- /dev/null +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/index.test.ts @@ -0,0 +1,340 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ +import type { DataView } from '@kbn/data-plugin/common'; +import type { Panel, Series } from '../../../common/types'; +import { convertToLens } from '.'; + +const dataViewsMap: Record = { + test1: { id: 'test1', title: 'test1', timeFieldName: 'timeField1' } as DataView, + test2: { + id: 'test2', + title: 'test2', + timeFieldName: 'timeField2', + } as DataView, + test3: { id: 'test3', title: 'test3', timeFieldName: 'timeField3' } as DataView, +}; + +const getDataview = (id: string): DataView | undefined => dataViewsMap[id]; +jest.mock('../../services', () => { + return { + getDataViewsStart: jest.fn(() => { + return { + getDefault: jest.fn(() => { + return { id: '12345', title: 'default', timeFieldName: '@timestamp' }; + }), + get: getDataview, + }; + }), + }; +}); + +const model = { + axis_position: 'left', + type: 'timeseries', + index_pattern: { id: 'test2' }, + use_kibana_indexes: true, + series: [ + { + color: '#000000', + chart_type: 'line', + fill: '0', + id: '85147356-c185-4636-9182-d55f3ab2b6fa', + palette: { + name: 'default', + type: 'palette', + }, + split_mode: 'everything', + metrics: [ + { + id: '3fa8b32f-5c38-4813-9361-1f2817ae5b18', + type: 'count', + }, + ], + override_index_pattern: 0, + }, + ], +} as Panel; + +describe('convertToLens for TimeSeries', () => { + test('should return null for a non supported aggregation', async () => { + const nonSupportedAggModel = { + ...model, + series: [ + { + ...model.series[0], + metrics: [ + { + type: 'sum_of_squares_bucket', + }, + ] as Series['metrics'], + }, + ], + }; + const triggerOptions = await convertToLens(nonSupportedAggModel); + expect(triggerOptions).toBeNull(); + }); + + test('should return options for a supported aggregation', async () => { + const triggerOptions = await convertToLens(model); + expect(triggerOptions).toStrictEqual({ + configuration: { + extents: { yLeftExtent: { mode: 'full' }, yRightExtent: { mode: 'full' } }, + fill: '0', + gridLinesVisibility: { x: false, yLeft: false, yRight: false }, + legend: { + isVisible: false, + maxLines: 1, + position: 'right', + shouldTruncate: false, + showSingleSeries: false, + }, + }, + type: 'lnsXY', + layers: { + '0': { + axisPosition: 'left', + chartType: 'line', + collapseFn: undefined, + indexPatternId: 'test2', + metrics: [ + { + agg: 'count', + color: '#000000', + fieldName: 'document', + isFullReference: false, + params: {}, + }, + ], + palette: { + name: 'default', + type: 'palette', + }, + splitWithDateHistogram: false, + xFieldName: 'timeField2', + xMode: 'date_histogram', + timeInterval: 'auto', + dropPartialBuckets: false, + }, + }, + }); + }); + + test('should return area for timeseries line chart with fill > 0', async () => { + const modelWithFill = { + ...model, + series: [ + { + ...model.series[0], + fill: '0.3', + stacked: 'none', + }, + ], + }; + const triggerOptions = await convertToLens(modelWithFill); + expect(triggerOptions?.layers[0].chartType).toBe('area'); + }); + + test('should return timeShift in the params if it is provided', async () => { + const modelWithFill = { + ...model, + series: [ + { + ...model.series[0], + offset_time: '1h', + }, + ], + }; + const triggerOptions = await convertToLens(modelWithFill); + expect(triggerOptions?.layers[0]?.metrics?.[0]?.params?.shift).toBe('1h'); + }); + + test('should return filter in the params if it is provided', async () => { + const modelWithFill = { + ...model, + series: [ + { + ...model.series[0], + filter: { + language: 'kuery', + query: 'test', + }, + }, + ], + }; + const triggerOptions = await convertToLens(modelWithFill); + expect(triggerOptions?.layers[0]?.metrics?.[0]?.params?.kql).toBe('test'); + }); + + test('should return splitFilters information if the chart is broken down by filters', async () => { + const modelWithSplitFilters = { + ...model, + series: [ + { + ...model.series[0], + split_mode: 'filters', + split_filters: [ + { + color: 'rgba(188,0,85,1)', + filter: { + language: 'kuery', + query: '', + }, + id: '89afac60-7d2b-11ec-917c-c18cd38d60b5', + }, + ], + }, + ], + }; + const triggerOptions = await convertToLens(modelWithSplitFilters); + expect(triggerOptions?.layers[0]?.splitFilters).toStrictEqual([ + { + color: 'rgba(188,0,85,1)', + filter: { + language: 'kuery', + query: '', + }, + id: '89afac60-7d2b-11ec-917c-c18cd38d60b5', + }, + ]); + }); + + test('should return termsParams information if the chart is broken down by terms including series agg collapse fn', async () => { + const modelWithTerms = { + ...model, + series: [ + { + ...model.series[0], + metrics: [ + ...model.series[0].metrics, + { + type: 'series_agg', + function: 'sum', + }, + ], + split_mode: 'terms', + terms_size: 6, + terms_direction: 'desc', + terms_order_by: '_key', + }, + ] as unknown as Series[], + }; + const triggerOptions = await convertToLens(modelWithTerms); + expect(triggerOptions?.layers[0]?.collapseFn).toStrictEqual('sum'); + expect(triggerOptions?.layers[0]?.termsParams).toStrictEqual({ + size: 6, + otherBucket: false, + orderDirection: 'desc', + orderBy: { type: 'alphabetical' }, + includeIsRegex: false, + excludeIsRegex: false, + parentFormat: { + id: 'terms', + }, + }); + }); + + test('should return include exclude information if the chart is broken down by terms', async () => { + const modelWithTerms = { + ...model, + series: [ + { + ...model.series[0], + split_mode: 'terms', + terms_size: 6, + terms_direction: 'desc', + terms_order_by: '_key', + terms_include: 't.*', + }, + ] as unknown as Series[], + }; + const triggerOptions = await convertToLens(modelWithTerms); + expect(triggerOptions?.layers[0]?.termsParams).toStrictEqual({ + size: 6, + otherBucket: false, + orderDirection: 'desc', + orderBy: { type: 'alphabetical' }, + includeIsRegex: true, + include: ['t.*'], + excludeIsRegex: false, + parentFormat: { + id: 'terms', + }, + }); + }); + + test('should return custom time interval if it is given', async () => { + const modelWithTerms = { + ...model, + interval: '1h', + }; + const triggerOptions = await convertToLens(modelWithTerms); + expect(triggerOptions?.layers[0]?.timeInterval).toBe('1h'); + }); + + test('should return dropPartialbuckets if enabled', async () => { + const modelWithDropBuckets = { + ...model, + drop_last_bucket: 1, + }; + const triggerOptions = await convertToLens(modelWithDropBuckets); + expect(triggerOptions?.layers[0]?.dropPartialBuckets).toBe(true); + }); + + test('should return the correct chart configuration', async () => { + const modelWithConfig = { + ...model, + show_legend: 1, + legend_position: 'bottom', + truncate_legend: 0, + show_grid: 1, + series: [{ ...model.series[0], fill: '0.3', separate_axis: 1, axis_position: 'right' }], + }; + const triggerOptions = await convertToLens(modelWithConfig); + expect(triggerOptions).toStrictEqual({ + configuration: { + extents: { yLeftExtent: { mode: 'full' }, yRightExtent: { mode: 'full' } }, + fill: '0.3', + gridLinesVisibility: { x: true, yLeft: true, yRight: true }, + legend: { + isVisible: true, + maxLines: 1, + position: 'bottom', + shouldTruncate: false, + showSingleSeries: true, + }, + }, + type: 'lnsXY', + layers: { + '0': { + axisPosition: 'right', + chartType: 'area_stacked', + collapseFn: undefined, + indexPatternId: 'test2', + metrics: [ + { + agg: 'count', + color: '#000000', + fieldName: 'document', + isFullReference: false, + params: {}, + }, + ], + palette: { + name: 'default', + type: 'palette', + }, + splitWithDateHistogram: false, + xFieldName: 'timeField2', + xMode: 'date_histogram', + timeInterval: 'auto', + dropPartialBuckets: false, + }, + }, + }); + }); +}); diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/index.ts index 2996ad19c42d92..1aa81b950a28ca 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/index.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/index.ts @@ -7,6 +7,7 @@ */ import { VisualizeEditorLayersContext } from '@kbn/visualizations-plugin/public'; +import { PANEL_TYPES } from '../../../common/enums'; import { getDataViewsStart } from '../../services'; import { getDataSourceInfo } from '../lib/datasource'; import { getSeries } from '../lib/series'; @@ -15,6 +16,7 @@ import { ConvertTsvbToLensVisualization } from '../types'; import { convertChartType, getYExtents } from '../lib/xy'; import { getLayerConfiguration } from '../lib/layers'; import { isSplitWithDateHistogram } from '../lib/split_chart'; +import { isValidMetrics } from '../lib/metrics'; export const convertToLens: ConvertTsvbToLensVisualization = async (model) => { const layersConfiguration: { [key: string]: VisualizeEditorLayersContext } = {}; @@ -30,6 +32,10 @@ export const convertToLens: ConvertTsvbToLensVisualization = async (model) => { continue; } + if (!isValidMetrics(layer.metrics, PANEL_TYPES.TIMESERIES)) { + return null; + } + const { indexPatternId, timeField } = await getDataSourceInfo( model.index_pattern, model.time_field, @@ -39,7 +45,7 @@ export const convertToLens: ConvertTsvbToLensVisualization = async (model) => { ); // handle multiple metrics - const series = getSeries(layer.metrics, seriesNum); + const series = getSeries(layer.metrics, seriesNum, layer.split_mode, layer.color); if (!series || !series.metrics) { return null; } @@ -68,6 +74,7 @@ export const convertToLens: ConvertTsvbToLensVisualization = async (model) => { series, splitFields, timeField, + 'date_histogram', splitWithDateHistogram ); } diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/top_n/index.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/top_n/index.test.ts new file mode 100644 index 00000000000000..1f408bf3dfa891 --- /dev/null +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/top_n/index.test.ts @@ -0,0 +1,329 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ +import type { DataView } from '@kbn/data-plugin/common'; +import type { Panel, Series } from '../../../common/types'; +import { convertToLens } from '.'; + +const dataViewsMap: Record = { + test1: { id: 'test1', title: 'test1', timeFieldName: 'timeField1' } as DataView, + test2: { + id: 'test2', + title: 'test2', + timeFieldName: 'timeField2', + } as DataView, + test3: { id: 'test3', title: 'test3', timeFieldName: 'timeField3' } as DataView, +}; + +const getDataview = (id: string): DataView | undefined => dataViewsMap[id]; +jest.mock('../../services', () => { + return { + getDataViewsStart: jest.fn(() => { + return { + getDefault: jest.fn(() => { + return { id: '12345', title: 'default', timeFieldName: '@timestamp' }; + }), + get: getDataview, + }; + }), + }; +}); + +const model = { + axis_position: 'left', + type: 'timeseries', + index_pattern: { id: 'test2' }, + use_kibana_indexes: true, + series: [ + { + color: '#000000', + chart_type: 'line', + fill: '0', + id: '85147356-c185-4636-9182-d55f3ab2b6fa', + palette: { + name: 'default', + type: 'palette', + }, + split_mode: 'everything', + metrics: [ + { + id: '3fa8b32f-5c38-4813-9361-1f2817ae5b18', + type: 'count', + }, + ], + override_index_pattern: 0, + }, + ], +} as Panel; + +describe('convertToLens for Top N', () => { + test('should return null for a non supported aggregation', async () => { + const nonSupportedAggModel = { + ...model, + series: [ + { + ...model.series[0], + metrics: [ + { + type: 'sum_of_squares_bucket', + }, + ] as Series['metrics'], + }, + ], + }; + const triggerOptions = await convertToLens(nonSupportedAggModel); + expect(triggerOptions).toBeNull(); + }); + + test('should return options for a supported aggregation', async () => { + const triggerOptions = await convertToLens(model); + expect(triggerOptions).toStrictEqual({ + configuration: { + fill: '0', + gridLinesVisibility: { x: false, yLeft: false, yRight: false }, + legend: { + isVisible: false, + maxLines: 1, + position: 'right', + shouldTruncate: false, + showSingleSeries: false, + }, + valueLabels: true, + tickLabelsVisibility: { x: true, yLeft: false, yRight: false }, + axisTitlesVisibility: { x: false, yLeft: false, yRight: false }, + }, + type: 'lnsXY', + layers: { + '0': { + axisPosition: 'left', + chartType: 'bar_horizontal', + collapseFn: undefined, + indexPatternId: 'test2', + metrics: [ + { + agg: 'count', + color: '#000000', + fieldName: 'document', + isFullReference: false, + params: {}, + }, + ], + palette: { + name: 'default', + type: 'palette', + }, + splitWithDateHistogram: false, + xFieldName: undefined, + xMode: undefined, + timeInterval: 'auto', + dropPartialBuckets: false, + }, + }, + }); + }); + + test('should return timeShift in the params if it is provided', async () => { + const modelWithFill = { + ...model, + series: [ + { + ...model.series[0], + offset_time: '1h', + }, + ], + }; + const triggerOptions = await convertToLens(modelWithFill); + expect(triggerOptions?.layers[0]?.metrics?.[0]?.params?.shift).toBe('1h'); + }); + + test('should return filter in the params if it is provided', async () => { + const modelWithFill = { + ...model, + series: [ + { + ...model.series[0], + filter: { + language: 'kuery', + query: 'test', + }, + }, + ], + }; + const triggerOptions = await convertToLens(modelWithFill); + expect(triggerOptions?.layers[0]?.metrics?.[0]?.params?.kql).toBe('test'); + }); + + test('should return splitFilters information if the chart is broken down by filters', async () => { + const modelWithSplitFilters = { + ...model, + series: [ + { + ...model.series[0], + split_mode: 'filters', + split_filters: [ + { + color: 'rgba(188,0,85,1)', + filter: { + language: 'kuery', + query: '', + }, + id: '89afac60-7d2b-11ec-917c-c18cd38d60b5', + }, + ], + }, + ], + }; + const triggerOptions = await convertToLens(modelWithSplitFilters); + expect(triggerOptions?.layers[0]?.splitFilters).toStrictEqual([ + { + color: 'rgba(188,0,85,1)', + filter: { + language: 'kuery', + query: '', + }, + id: '89afac60-7d2b-11ec-917c-c18cd38d60b5', + }, + ]); + }); + + test('should return termsParams information if the chart is broken down by terms including series agg collapse fn', async () => { + const modelWithTerms = { + ...model, + series: [ + { + ...model.series[0], + metrics: [ + ...model.series[0].metrics, + { + type: 'series_agg', + function: 'sum', + }, + ], + split_mode: 'terms', + terms_size: 6, + terms_direction: 'desc', + terms_order_by: '_key', + }, + ] as unknown as Series[], + }; + const triggerOptions = await convertToLens(modelWithTerms); + expect(triggerOptions?.layers[0]?.collapseFn).toStrictEqual('sum'); + expect(triggerOptions?.layers[0]?.termsParams).toStrictEqual({ + size: 6, + otherBucket: false, + orderDirection: 'desc', + orderBy: { type: 'alphabetical' }, + includeIsRegex: false, + excludeIsRegex: false, + parentFormat: { + id: 'terms', + }, + }); + }); + + test('should return include exclude information if the chart is broken down by terms', async () => { + const modelWithTerms = { + ...model, + series: [ + { + ...model.series[0], + split_mode: 'terms', + terms_size: 6, + terms_direction: 'desc', + terms_order_by: '_key', + terms_include: 't.*', + }, + ] as unknown as Series[], + }; + const triggerOptions = await convertToLens(modelWithTerms); + expect(triggerOptions?.layers[0]?.termsParams).toStrictEqual({ + size: 6, + otherBucket: false, + orderDirection: 'desc', + orderBy: { type: 'alphabetical' }, + includeIsRegex: true, + include: ['t.*'], + excludeIsRegex: false, + parentFormat: { + id: 'terms', + }, + }); + }); + + test('should return custom time interval if it is given', async () => { + const modelWithTerms = { + ...model, + interval: '1h', + }; + const triggerOptions = await convertToLens(modelWithTerms); + expect(triggerOptions?.layers[0]?.timeInterval).toBe('1h'); + }); + + test('should return dropPartialbuckets if enabled', async () => { + const modelWithDropBuckets = { + ...model, + drop_last_bucket: 1, + }; + const triggerOptions = await convertToLens(modelWithDropBuckets); + expect(triggerOptions?.layers[0]?.dropPartialBuckets).toBe(true); + }); + + test('should return the correct chart configuration', async () => { + const modelWithConfig = { + ...model, + show_legend: 1, + legend_position: 'bottom', + truncate_legend: 0, + show_grid: 1, + series: [{ ...model.series[0], fill: '0.3', separate_axis: 1, axis_position: 'right' }], + }; + const triggerOptions = await convertToLens(modelWithConfig); + expect(triggerOptions).toStrictEqual({ + configuration: { + fill: '0.3', + gridLinesVisibility: { x: false, yLeft: false, yRight: false }, + legend: { + isVisible: true, + maxLines: 1, + position: 'bottom', + shouldTruncate: false, + showSingleSeries: true, + }, + valueLabels: true, + tickLabelsVisibility: { x: true, yLeft: false, yRight: false }, + axisTitlesVisibility: { x: false, yLeft: false, yRight: false }, + }, + type: 'lnsXY', + layers: { + '0': { + axisPosition: 'right', + chartType: 'bar_horizontal', + collapseFn: undefined, + indexPatternId: 'test2', + metrics: [ + { + agg: 'count', + color: '#000000', + fieldName: 'document', + isFullReference: false, + params: {}, + }, + ], + palette: { + name: 'default', + type: 'palette', + }, + splitWithDateHistogram: false, + xFieldName: undefined, + xMode: undefined, + timeInterval: 'auto', + dropPartialBuckets: false, + }, + }, + }); + }); +}); diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/top_n/index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/top_n/index.ts new file mode 100644 index 00000000000000..292a44aaf98d9f --- /dev/null +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/top_n/index.ts @@ -0,0 +1,115 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { VisualizeEditorLayersContext } from '@kbn/visualizations-plugin/public'; +import { PANEL_TYPES, TIME_RANGE_DATA_MODES } from '../../../common/enums'; +import { getDataViewsStart } from '../../services'; +import { getDataSourceInfo } from '../lib/datasource'; +import { getSeries } from '../lib/series'; +import { getFieldsForTerms } from '../../../common/fields_utils'; +import { ConvertTsvbToLensVisualization } from '../types'; +import { isSplitWithDateHistogram } from '../lib/split_chart'; +import { getLayerConfiguration } from '../lib/layers'; +import { getWindow, isValidMetrics } from '../lib/metrics'; + +export const convertToLens: ConvertTsvbToLensVisualization = async (model, timeRange) => { + const layersConfiguration: { [key: string]: VisualizeEditorLayersContext } = {}; + + // get the active series number + const seriesNum = model.series.filter((series) => !series.hidden).length; + const dataViews = getDataViewsStart(); + + // handle multiple layers/series + for (let layerIdx = 0; layerIdx < model.series.length; layerIdx++) { + const layer = model.series[layerIdx]; + if (layer.hidden) { + continue; + } + + if (!isValidMetrics(layer.metrics, PANEL_TYPES.TOP_N, layer.time_range_mode)) { + return null; + } + + const { indexPatternId } = await getDataSourceInfo( + model.index_pattern, + model.time_field, + Boolean(layer.override_index_pattern), + layer.series_index_pattern, + dataViews + ); + + const window = + model.time_range_mode === TIME_RANGE_DATA_MODES.LAST_VALUE + ? getWindow(model.interval, timeRange) + : undefined; + + // handle multiple metrics + const series = getSeries(layer.metrics, seriesNum, layer.split_mode, layer.color, window); + if (!series || !series.metrics) { + return null; + } + + const splitFields = getFieldsForTerms(layer.terms_field); + + // in case of terms in a date field, we want to apply the date_histogram + const splitWithDateHistogram = await isSplitWithDateHistogram( + layer, + splitFields, + indexPatternId, + dataViews + ); + + if (splitWithDateHistogram === null) { + return null; + } + + layersConfiguration[layerIdx] = getLayerConfiguration( + indexPatternId, + layerIdx, + 'bar_horizontal', + model, + series, + splitFields, + undefined, + undefined, + splitWithDateHistogram, + window + ); + } + + return { + layers: layersConfiguration, + type: 'lnsXY', + configuration: { + fill: model.series[0].fill ?? 0.3, + legend: { + isVisible: Boolean(model.show_legend), + showSingleSeries: Boolean(model.show_legend), + position: model.legend_position ?? 'right', + shouldTruncate: Boolean(model.truncate_legend), + maxLines: model.max_lines_legend ?? 1, + }, + gridLinesVisibility: { + x: false, + yLeft: false, + yRight: false, + }, + tickLabelsVisibility: { + x: true, + yLeft: false, + yRight: false, + }, + axisTitlesVisibility: { + x: false, + yLeft: false, + yRight: false, + }, + valueLabels: true, + }, + }; +}; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/types.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/types.ts index 8c17b9ec6ce577..cf91d9835bac73 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/types.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/types.ts @@ -6,11 +6,13 @@ * Side Public License, v 1. */ +import { TimeRange } from '@kbn/data-plugin/common'; import { NavigateToLensContext } from '@kbn/visualizations-plugin/public'; import type { Panel } from '../../common/types'; export type ConvertTsvbToLensVisualization = ( - model: Panel + model: Panel, + timeRange?: TimeRange ) => Promise; export interface Filter { diff --git a/src/plugins/vis_types/timeseries/public/metrics_type.ts b/src/plugins/vis_types/timeseries/public/metrics_type.ts index 10658b264c4a39..edd4ac0297b3c2 100644 --- a/src/plugins/vis_types/timeseries/public/metrics_type.ts +++ b/src/plugins/vis_types/timeseries/public/metrics_type.ts @@ -9,6 +9,7 @@ import { i18n } from '@kbn/i18n'; import uuid from 'uuid/v4'; import type { DataViewsContract, DataView } from '@kbn/data-views-plugin/public'; +import { TimeRange } from '@kbn/data-plugin/common'; import { Vis, VIS_EVENT_TO_TRIGGER, @@ -168,8 +169,8 @@ export const metricsVisDefinition: VisTypeDefinition< } return []; }, - navigateToLens: async (params?: VisParams) => - params ? await convertTSVBtoLensConfiguration(params as Panel) : null, + navigateToLens: async (params?: VisParams, timeRange?: TimeRange) => + params ? await convertTSVBtoLensConfiguration(params as Panel, timeRange) : null, inspectorAdapters: () => ({ requests: new RequestAdapter(), diff --git a/src/plugins/vis_types/timeseries/server/lib/vis_data/helpers/bucket_transform.js b/src/plugins/vis_types/timeseries/server/lib/vis_data/helpers/bucket_transform.js index bd96e95edd15b5..f6e032a35fd40f 100644 --- a/src/plugins/vis_types/timeseries/server/lib/vis_data/helpers/bucket_transform.js +++ b/src/plugins/vis_types/timeseries/server/lib/vis_data/helpers/bucket_transform.js @@ -7,7 +7,7 @@ */ import { getBucketsPath } from './get_buckets_path'; -import { set } from '@elastic/safer-lodash-set'; +import { set } from '@kbn/safer-lodash-set'; import { isEmpty } from 'lodash'; import { i18n } from '@kbn/i18n'; import { MODEL_SCRIPTS } from './moving_fn_scripts'; diff --git a/src/plugins/vis_types/vislib/kibana.json b/src/plugins/vis_types/vislib/kibana.json index 1eb0504c9e3e2e..1f0a76bd364f8b 100644 --- a/src/plugins/vis_types/vislib/kibana.json +++ b/src/plugins/vis_types/vislib/kibana.json @@ -5,7 +5,7 @@ "ui": true, "requiredPlugins": ["charts", "data", "expressions", "visualizations", "fieldFormats"], "optionalPlugins": ["usageCollection"], - "requiredBundles": ["kibanaUtils", "visTypeXy", "visTypePie", "visTypeHeatmap", "visTypeGauge", "kibanaReact"], + "requiredBundles": ["kibanaUtils", "visTypePie", "visTypeHeatmap", "visTypeGauge", "kibanaReact"], "owner": { "name": "Vis Editors", "githubTeam": "kibana-vis-editors" diff --git a/src/plugins/vis_types/vislib/public/vislib/helpers/point_series/_add_to_siri.ts b/src/plugins/vis_types/vislib/public/vislib/helpers/point_series/_add_to_siri.ts index 612a75b7e282fb..8863c0a5fc1ea2 100644 --- a/src/plugins/vis_types/vislib/public/vislib/helpers/point_series/_add_to_siri.ts +++ b/src/plugins/vis_types/vislib/public/vislib/helpers/point_series/_add_to_siri.ts @@ -6,11 +6,12 @@ * Side Public License, v 1. */ -import { getAggId } from '@kbn/vis-type-xy-plugin/public'; import type { Dimension } from '@kbn/vis-type-xy-plugin/public'; import { Point } from './_get_point'; +const getAggId = (accessor: string) => (accessor ?? '').split('-').pop() ?? ''; + export interface Serie { id: string; rawId: string; diff --git a/src/plugins/vis_types/vislib/public/vislib/lib/axis/axis_config.js b/src/plugins/vis_types/vislib/public/vislib/lib/axis/axis_config.js index 18958b6439a8c7..2a5ab819c00ac4 100644 --- a/src/plugins/vis_types/vislib/public/vislib/lib/axis/axis_config.js +++ b/src/plugins/vis_types/vislib/public/vislib/lib/axis/axis_config.js @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import { set } from '@elastic/safer-lodash-set'; +import { set } from '@kbn/safer-lodash-set'; import _ from 'lodash'; import d3 from 'd3'; import { SCALE_MODES } from './scale_modes'; diff --git a/src/plugins/vis_types/vislib/public/vislib/lib/chart_grid.js b/src/plugins/vis_types/vislib/public/vislib/lib/chart_grid.js index 32a41ec5ed489d..a9ffe384ee78fa 100644 --- a/src/plugins/vis_types/vislib/public/vislib/lib/chart_grid.js +++ b/src/plugins/vis_types/vislib/public/vislib/lib/chart_grid.js @@ -7,7 +7,7 @@ */ import d3 from 'd3'; -import { set } from '@elastic/safer-lodash-set'; +import { set } from '@kbn/safer-lodash-set'; import _ from 'lodash'; const defaults = { diff --git a/src/plugins/vis_types/vislib/public/vislib/lib/vis_config.js b/src/plugins/vis_types/vislib/public/vislib/lib/vis_config.js index cc9e48897d0535..3b60481c0affe6 100644 --- a/src/plugins/vis_types/vislib/public/vislib/lib/vis_config.js +++ b/src/plugins/vis_types/vislib/public/vislib/lib/vis_config.js @@ -9,7 +9,7 @@ /** * Provides vislib configuration, throws error if invalid property is accessed without providing defaults */ -import { set } from '@elastic/safer-lodash-set'; +import { set } from '@kbn/safer-lodash-set'; import _ from 'lodash'; import { vislibTypesConfig as visTypes } from './types'; import { Data } from './data'; diff --git a/src/plugins/vis_types/xy/common/index.ts b/src/plugins/vis_types/xy/common/index.ts index f17bc8476d9a68..da2c02d6145d20 100644 --- a/src/plugins/vis_types/xy/common/index.ts +++ b/src/plugins/vis_types/xy/common/index.ts @@ -14,8 +14,3 @@ export enum ChartType { Area = 'area', Histogram = 'histogram', } - -/** - * Type of xy visualizations - */ -export type XyVisType = ChartType | 'horizontal_bar'; diff --git a/src/plugins/vis_types/xy/kibana.json b/src/plugins/vis_types/xy/kibana.json index 45f1c36331dfbb..fa942c1530142e 100644 --- a/src/plugins/vis_types/xy/kibana.json +++ b/src/plugins/vis_types/xy/kibana.json @@ -3,9 +3,8 @@ "version": "kibana", "ui": true, "server": true, - "requiredPlugins": ["charts", "data", "expressions", "visualizations", "fieldFormats"], - "requiredBundles": ["kibanaUtils", "visDefaultEditor", "kibanaReact"], - "optionalPlugins": ["usageCollection"], + "requiredPlugins": ["charts", "visualizations", "data", "expressions"], + "requiredBundles": ["kibanaUtils", "visDefaultEditor"], "extraPublicDirs": ["common/index"], "owner": { "name": "Vis Editors", diff --git a/src/plugins/vis_types/xy/public/_chart.scss b/src/plugins/vis_types/xy/public/_chart.scss deleted file mode 100644 index ac9d4ed04aec47..00000000000000 --- a/src/plugins/vis_types/xy/public/_chart.scss +++ /dev/null @@ -1,7 +0,0 @@ -.xyChart__container { - position: absolute; - top: 0; - right: 0; - bottom: 0; - left: 0; -} diff --git a/src/plugins/vis_types/xy/public/chart_split.tsx b/src/plugins/vis_types/xy/public/chart_split.tsx deleted file mode 100644 index e1d096334f17c6..00000000000000 --- a/src/plugins/vis_types/xy/public/chart_split.tsx +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import React from 'react'; -import { Accessor, AccessorFn, GroupBy, SmallMultiples, Predicate } from '@elastic/charts'; - -interface ChartSplitProps { - splitColumnAccessor?: Accessor | AccessorFn; - splitRowAccessor?: Accessor | AccessorFn; -} - -const CHART_SPLIT_ID = '__chart_split__'; - -export const ChartSplit = ({ splitColumnAccessor, splitRowAccessor }: ChartSplitProps) => { - if (!splitColumnAccessor && !splitRowAccessor) return null; - - return ( - <> - { - const splitTypeAccessor = splitColumnAccessor || splitRowAccessor; - if (splitTypeAccessor) { - return typeof splitTypeAccessor === 'function' - ? splitTypeAccessor(datum) - : datum[splitTypeAccessor]; - } - return spec.id; - }} - sort={Predicate.DataIndex} - /> - - - ); -}; diff --git a/src/plugins/vis_types/xy/public/components/_detailed_tooltip.scss b/src/plugins/vis_types/xy/public/components/_detailed_tooltip.scss deleted file mode 100644 index 91b0a8d0232902..00000000000000 --- a/src/plugins/vis_types/xy/public/components/_detailed_tooltip.scss +++ /dev/null @@ -1,34 +0,0 @@ -.detailedTooltip { - @include euiToolTipStyle('s'); - pointer-events: none; - max-width: $euiSizeXL * 10; - overflow: hidden; - padding: $euiSizeS; - - table { - td, - th { - text-align: left; - padding: $euiSizeXS; - overflow-wrap: break-word; - word-wrap: break-word; - } - } -} - -.detailedTooltip__header { - > :last-child { - margin-bottom: $euiSizeS; - } -} - -.detailedTooltip__labelContainer, -.detailedTooltip__valueContainer { - overflow-wrap: break-word; - word-wrap: break-word; -} - -.detailedTooltip__label { - font-weight: $euiFontWeightMedium; - color: shade($euiColorGhost, 20%); -} diff --git a/src/plugins/vis_types/xy/public/components/detailed_tooltip.mock.ts b/src/plugins/vis_types/xy/public/components/detailed_tooltip.mock.ts deleted file mode 100644 index bc6a1f292dad34..00000000000000 --- a/src/plugins/vis_types/xy/public/components/detailed_tooltip.mock.ts +++ /dev/null @@ -1,187 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -export const aspects = { - x: { - accessor: 'col-0-3', - column: 0, - title: 'timestamp per 3 hours', - format: { - id: 'date', - params: { - pattern: 'YYYY-MM-DD HH:mm', - }, - }, - aggType: 'date_histogram', - aggId: '3', - params: { - date: true, - intervalESUnit: 'h', - intervalESValue: 3, - interval: 10800000, - format: 'YYYY-MM-DD HH:mm', - }, - }, - y: [ - { - accessor: 'col-1-1', - column: 1, - title: 'Count', - format: { - id: 'number', - }, - aggType: 'count', - aggId: '1', - params: {}, - }, - ], -}; - -export const aspectsWithSplitColumn = { - x: { - accessor: 'col-0-3', - column: 0, - title: 'timestamp per 3 hours', - format: { - id: 'date', - params: { - pattern: 'YYYY-MM-DD HH:mm', - }, - }, - aggType: 'date_histogram', - aggId: '3', - params: { - date: true, - intervalESUnit: 'h', - intervalESValue: 3, - interval: 10800000, - format: 'YYYY-MM-DD HH:mm', - }, - }, - y: [ - { - accessor: 'col-2-1', - column: 2, - title: 'Count', - format: { - id: 'number', - }, - aggType: 'count', - aggId: '1', - params: {}, - }, - ], - splitColumn: { - accessor: 'col-1-4', - column: 1, - title: 'Cancelled: Descending', - format: { - id: 'terms', - params: { - id: 'boolean', - otherBucketLabel: 'Other', - missingBucketLabel: 'Missing', - }, - }, - aggType: 'terms', - aggId: '4', - params: {}, - }, -}; - -export const aspectsWithSplitRow = { - x: { - accessor: 'col-0-3', - column: 0, - title: 'timestamp per 3 hours', - format: { - id: 'date', - params: { - pattern: 'YYYY-MM-DD HH:mm', - }, - }, - aggType: 'date_histogram', - aggId: '3', - params: { - date: true, - intervalESUnit: 'h', - intervalESValue: 3, - interval: 10800000, - format: 'YYYY-MM-DD HH:mm', - }, - }, - y: [ - { - accessor: 'col-3-1', - column: 2, - title: 'Count', - format: { - id: 'number', - }, - aggType: 'count', - aggId: '1', - params: {}, - }, - ], - splitRow: { - accessor: 'col-1-5', - column: 1, - title: 'Carrier: Descending', - format: { - id: 'terms', - params: { - id: 'string', - otherBucketLabel: 'Other', - missingBucketLabel: 'Missing', - }, - }, - aggType: 'terms', - aggId: '4', - params: {}, - }, -}; - -export const header = { - seriesIdentifier: { - key: 'groupId{__pseudo_stacked_group-ValueAxis-1__}spec{area-col-1-1}yAccessor{col-1-1}splitAccessors{}smV{__ECH_DEFAULT_SINGLE_PANEL_SM_VALUE__}smH{__ECH_DEFAULT_SINGLE_PANEL_SM_VALUE__}', - specId: 'area-col-1-1', - yAccessor: 'col-1-1', - splitAccessors: {}, - seriesKeys: ['col-1-1'], - smVerticalAccessorValue: '__ECH_DEFAULT_SINGLE_PANEL_SM_VALUE__', - smHorizontalAccessorValue: '__ECH_DEFAULT_SINGLE_PANEL_SM_VALUE__', - }, - valueAccessor: 'y1', - label: 'Count', - value: 1611817200000, - formattedValue: '1611817200000', - markValue: null, - color: '#54b399', - isHighlighted: false, - isVisible: true, -}; - -export const value = { - seriesIdentifier: { - key: 'groupId{__pseudo_stacked_group-ValueAxis-1__}spec{area-col-1-1}yAccessor{col-1-1}splitAccessors{}smV{__ECH_DEFAULT_SINGLE_PANEL_SM_VALUE__}smH{__ECH_DEFAULT_SINGLE_PANEL_SM_VALUE__}', - specId: 'area-col-1-1', - yAccessor: 'col-1-1', - splitAccessors: [], - seriesKeys: ['col-1-1'], - smVerticalAccessorValue: 'kibana', - smHorizontalAccessorValue: 'false', - }, - valueAccessor: 'y1', - label: 'Count', - value: 52, - formattedValue: '52', - markValue: null, - color: '#54b399', - isHighlighted: true, - isVisible: true, -}; diff --git a/src/plugins/vis_types/xy/public/components/detailed_tooltip.test.tsx b/src/plugins/vis_types/xy/public/components/detailed_tooltip.test.tsx deleted file mode 100644 index aa76b680f6cc05..00000000000000 --- a/src/plugins/vis_types/xy/public/components/detailed_tooltip.test.tsx +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { getTooltipData } from './detailed_tooltip'; -import { - aspects, - aspectsWithSplitColumn, - aspectsWithSplitRow, - header, - value, -} from './detailed_tooltip.mock'; - -describe('getTooltipData', () => { - it('returns an array with the header and data information', () => { - const tooltipData = getTooltipData(aspects, header, value); - expect(tooltipData).toStrictEqual([ - { - label: 'timestamp per 3 hours', - value: '1611817200000', - }, - { - label: 'Count', - value: '52', - }, - ]); - }); - - it('returns an array with the data information if the header is not applied', () => { - const tooltipData = getTooltipData(aspects, null, value); - expect(tooltipData).toStrictEqual([ - { - label: 'Count', - value: '52', - }, - ]); - }); - - it('returns an array with the split column information if it is provided', () => { - const tooltipData = getTooltipData(aspectsWithSplitColumn, null, value); - expect(tooltipData).toStrictEqual([ - { - label: 'Cancelled: Descending', - value: 'false', - }, - ]); - }); - - it('returns an array with the split row information if it is provided', () => { - const tooltipData = getTooltipData(aspectsWithSplitRow, null, value); - expect(tooltipData).toStrictEqual([ - { - label: 'Carrier: Descending', - value: 'kibana', - }, - ]); - }); -}); diff --git a/src/plugins/vis_types/xy/public/components/detailed_tooltip.tsx b/src/plugins/vis_types/xy/public/components/detailed_tooltip.tsx deleted file mode 100644 index a7eb7a909615b6..00000000000000 --- a/src/plugins/vis_types/xy/public/components/detailed_tooltip.tsx +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import React from 'react'; -import { isNil } from 'lodash'; - -import { - CustomTooltip, - TooltipValue, - TooltipValueFormatter, - XYChartSeriesIdentifier, -} from '@elastic/charts'; - -import { Aspects } from '../types'; - -import './_detailed_tooltip.scss'; -import { COMPLEX_SPLIT_ACCESSOR, isRangeAggType } from '../utils/accessors'; - -interface TooltipData { - label: string; - value: string; -} - -export const getTooltipData = ( - aspects: Aspects, - header: TooltipValue | null, - value: TooltipValue -): TooltipData[] => { - const data: TooltipData[] = []; - - if (header) { - const xFormatter = isRangeAggType(aspects.x.aggType) ? null : aspects.x.formatter; - data.push({ - label: aspects.x.title, - value: xFormatter ? xFormatter(header.value) : `${header.value}`, - }); - } - - const valueSeries = value.seriesIdentifier as XYChartSeriesIdentifier; - const yAccessor = aspects.y.find(({ accessor }) => accessor === valueSeries.yAccessor) ?? null; - - if (yAccessor) { - data.push({ - label: yAccessor.title, - value: yAccessor.formatter ? yAccessor.formatter(value.value) : `${value.value}`, - }); - } - - if (aspects.z && !isNil(value.markValue)) { - data.push({ - label: aspects.z.title, - value: aspects.z.formatter ? aspects.z.formatter(value.markValue) : `${value.markValue}`, - }); - } - - valueSeries.splitAccessors.forEach((splitValue, key) => { - const split = (aspects.series ?? []).find(({ accessor }, i) => { - return accessor === key || key === `${COMPLEX_SPLIT_ACCESSOR}::${i}`; - }); - - if (split) { - data.push({ - label: split?.title, - value: - split?.formatter && !key.toString().startsWith(COMPLEX_SPLIT_ACCESSOR) - ? split?.formatter(splitValue) - : `${splitValue}`, - }); - } - }); - - if ( - aspects.splitColumn && - valueSeries.smHorizontalAccessorValue !== undefined && - valueSeries.smHorizontalAccessorValue !== undefined - ) { - data.push({ - label: aspects.splitColumn.title, - value: `${valueSeries.smHorizontalAccessorValue}`, - }); - } - - if ( - aspects.splitRow && - valueSeries.smVerticalAccessorValue !== undefined && - valueSeries.smVerticalAccessorValue !== undefined - ) { - data.push({ - label: aspects.splitRow.title, - value: `${valueSeries.smVerticalAccessorValue}`, - }); - } - - return data; -}; - -const renderData = ({ label, value }: TooltipData, index: number) => { - return label && value ? ( - - -
{label}
- - - -
{value}
- - - ) : null; -}; - -export const getDetailedTooltip = - (aspects: Aspects) => - (headerFormatter?: TooltipValueFormatter): CustomTooltip => { - return function DetailedTooltip({ header, values }) { - // Note: first value is not necessarily the closest value - // To be fixed with https://github.com/elastic/elastic-charts/issues/835 - // TODO: Allow multiple values to be displayed in tooltip - const highlightedValue = values.find(({ isHighlighted }) => isHighlighted); - - if (!highlightedValue) { - return null; - } - - const tooltipData = getTooltipData(aspects, header, highlightedValue); - - if (tooltipData.length === 0) { - return null; - } - - return ( -
- {headerFormatter && header && ( -
{headerFormatter(header)}
- )} - - {tooltipData.map(renderData)} -
-
- ); - }; - }; diff --git a/src/plugins/vis_types/xy/public/components/index.ts b/src/plugins/vis_types/xy/public/components/index.ts deleted file mode 100644 index 7aaeb17ab28288..00000000000000 --- a/src/plugins/vis_types/xy/public/components/index.ts +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -export { XYAxis } from './xy_axis'; -export { XYEndzones } from './xy_endzones'; -export { XYCurrentTime } from './xy_current_time'; -export { XYSettings } from './xy_settings'; -export { XYThresholdLine } from './xy_threshold_line'; diff --git a/src/plugins/vis_types/xy/public/components/xy_axis.tsx b/src/plugins/vis_types/xy/public/components/xy_axis.tsx deleted file mode 100644 index b224639bdbff3a..00000000000000 --- a/src/plugins/vis_types/xy/public/components/xy_axis.tsx +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import React, { FC } from 'react'; - -import { Axis } from '@elastic/charts'; - -import { AxisConfig } from '../types'; - -type XYAxisPros = AxisConfig; - -export const XYAxis: FC = ({ - id, - title, - show, - position, - groupId, - grid, - ticks, - domain, - style, - integersOnly, - timeAxisLayerCount, -}) => ( - -); diff --git a/src/plugins/vis_types/xy/public/components/xy_current_time.tsx b/src/plugins/vis_types/xy/public/components/xy_current_time.tsx deleted file mode 100644 index 68f1dd0d60b132..00000000000000 --- a/src/plugins/vis_types/xy/public/components/xy_current_time.tsx +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import React, { FC } from 'react'; -import { DomainRange } from '@elastic/charts'; -import { CurrentTime } from '@kbn/charts-plugin/public'; - -interface XYCurrentTime { - enabled: boolean; - isDarkMode: boolean; - domain?: DomainRange; -} - -export const XYCurrentTime: FC = ({ enabled, isDarkMode, domain }) => { - if (!enabled) { - return null; - } - - const domainEnd = domain && 'max' in domain ? domain.max : undefined; - return ; -}; diff --git a/src/plugins/vis_types/xy/public/components/xy_endzones.tsx b/src/plugins/vis_types/xy/public/components/xy_endzones.tsx deleted file mode 100644 index 50982cc30dc3c5..00000000000000 --- a/src/plugins/vis_types/xy/public/components/xy_endzones.tsx +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import React, { FC } from 'react'; - -import { DomainRange } from '@elastic/charts'; - -import { Endzones } from '@kbn/charts-plugin/public'; - -interface XYEndzones { - enabled: boolean; - isDarkMode: boolean; - isFullBin: boolean; - hideTooltips?: boolean; - domain?: DomainRange; - adjustedDomain?: DomainRange; -} - -export const XYEndzones: FC = ({ - enabled, - isDarkMode, - isFullBin, - hideTooltips, - domain, - adjustedDomain, -}) => { - if ( - enabled && - domain && - adjustedDomain && - 'min' in domain && - 'max' in domain && - domain.minInterval !== undefined && - 'min' in adjustedDomain && - 'max' in adjustedDomain - ) { - return ( - - ); - } - - return null; -}; diff --git a/src/plugins/vis_types/xy/public/components/xy_settings.tsx b/src/plugins/vis_types/xy/public/components/xy_settings.tsx deleted file mode 100644 index f934a2c203196f..00000000000000 --- a/src/plugins/vis_types/xy/public/components/xy_settings.tsx +++ /dev/null @@ -1,195 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import React, { FC } from 'react'; - -import { - Direction, - Settings, - SettingsProps, - DomainRange, - Position, - PartialTheme, - ElementClickListener, - BrushEndListener, - RenderChangeListener, - LegendAction, - LegendColorPicker, - TooltipProps, - TickFormatter, - VerticalAlignment, - HorizontalAlignment, -} from '@elastic/charts'; - -import { renderEndzoneTooltip } from '@kbn/charts-plugin/public'; - -import { getThemeService } from '../services'; -import { VisConfig } from '../types'; - -declare global { - interface Window { - /** - * Flag used to enable debugState on elastic charts - */ - _echDebugStateFlag?: boolean; - } -} - -type XYSettingsProps = Pick< - VisConfig, - | 'markSizeRatio' - | 'rotation' - | 'enableHistogramMode' - | 'tooltip' - | 'isTimeChart' - | 'xAxis' - | 'orderBucketsBySum' -> & { - onPointerUpdate: SettingsProps['onPointerUpdate']; - externalPointerEvents: SettingsProps['externalPointerEvents']; - xDomain?: DomainRange; - adjustedXDomain?: DomainRange; - showLegend: boolean; - onElementClick: ElementClickListener; - onBrushEnd?: BrushEndListener; - onRenderChange: RenderChangeListener; - legendAction?: LegendAction; - legendColorPicker: LegendColorPicker; - legendPosition: Position; - truncateLegend: boolean; - maxLegendLines: number; - legendSize?: number; - ariaLabel?: string; -}; - -function getValueLabelsStyling() { - const VALUE_LABELS_MAX_FONTSIZE = 12; - const VALUE_LABELS_MIN_FONTSIZE = 10; - - return { - displayValue: { - fontSize: { min: VALUE_LABELS_MIN_FONTSIZE, max: VALUE_LABELS_MAX_FONTSIZE }, - alignment: { horizontal: HorizontalAlignment.Center, vertical: VerticalAlignment.Middle }, - }, - }; -} - -export const XYSettings: FC = ({ - markSizeRatio, - rotation, - enableHistogramMode, - tooltip, - isTimeChart, - xAxis, - orderBucketsBySum, - xDomain, - adjustedXDomain, - showLegend, - onElementClick, - onPointerUpdate, - externalPointerEvents, - onBrushEnd, - onRenderChange, - legendAction, - legendColorPicker, - legendPosition, - maxLegendLines, - truncateLegend, - legendSize, - ariaLabel, -}) => { - const themeService = getThemeService(); - const theme = themeService.useChartsTheme(); - const baseTheme = themeService.useChartsBaseTheme(); - const valueLabelsStyling = getValueLabelsStyling(); - - const themeOverrides: PartialTheme = { - markSizeRatio, - barSeriesStyle: { - ...valueLabelsStyling, - }, - crosshair: { - ...theme.crosshair, - }, - legend: { - labelOptions: { maxLines: truncateLegend ? maxLegendLines ?? 1 : 0 }, - }, - axes: { - axisTitle: { - padding: { - outer: 10, - }, - }, - }, - chartMargins: - legendPosition === Position.Top || legendPosition === Position.Right - ? { - bottom: (theme.chartMargins?.bottom ?? 0) + 10, - } - : { - right: (theme.chartMargins?.right ?? 0) + 10, - }, - }; - - const headerValueFormatter: TickFormatter | undefined = xAxis.ticks?.formatter - ? (value) => xAxis.ticks?.formatter?.(value) ?? '' - : undefined; - const headerFormatter = - isTimeChart && xDomain && adjustedXDomain - ? renderEndzoneTooltip( - xDomain.minInterval, - 'min' in xDomain ? xDomain.min : undefined, - 'max' in xDomain ? xDomain.max : undefined, - headerValueFormatter, - !tooltip.detailedTooltip - ) - : headerValueFormatter && - (tooltip.detailedTooltip ? undefined : ({ value }: any) => headerValueFormatter(value)); - - const boundary = document.getElementById('app-fixed-viewport') ?? undefined; - const tooltipProps: TooltipProps = tooltip.detailedTooltip - ? { - ...tooltip, - boundary, - customTooltip: tooltip.detailedTooltip(headerFormatter), - headerFormatter: undefined, - } - : { ...tooltip, boundary, headerFormatter }; - - return ( - - ); -}; diff --git a/src/plugins/vis_types/xy/public/components/xy_threshold_line.tsx b/src/plugins/vis_types/xy/public/components/xy_threshold_line.tsx deleted file mode 100644 index f28dbf726d2877..00000000000000 --- a/src/plugins/vis_types/xy/public/components/xy_threshold_line.tsx +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import React, { FC } from 'react'; - -import { AnnotationDomainType, LineAnnotation } from '@elastic/charts'; - -import { ThresholdLineConfig } from '../types'; - -type XYThresholdLineProps = ThresholdLineConfig & { - groupId?: string; -}; - -export const XYThresholdLine: FC = ({ - show, - value: dataValue, - color, - width, - groupId, - dash, -}) => { - if (!show) { - return null; - } - - return ( - - ); -}; diff --git a/src/plugins/vis_types/xy/public/config/get_agg_id.ts b/src/plugins/vis_types/xy/public/config/get_agg_id.ts deleted file mode 100644 index 9586d0f082c1ab..00000000000000 --- a/src/plugins/vis_types/xy/public/config/get_agg_id.ts +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -/** - * Get agg id from accessor - * - * For now this is determined by the esaggs column name. Could be cleaned up in the future. - */ -export const getAggId = (accessor: string) => (accessor ?? '').split('-').pop() ?? ''; diff --git a/src/plugins/vis_types/xy/public/config/get_aspects.ts b/src/plugins/vis_types/xy/public/config/get_aspects.ts deleted file mode 100644 index ee4b403301d87e..00000000000000 --- a/src/plugins/vis_types/xy/public/config/get_aspects.ts +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { compact } from 'lodash'; - -import { i18n } from '@kbn/i18n'; - -import { DatatableColumn } from '@kbn/expressions-plugin/public'; - -import { Aspect, Dimension, Aspects, Dimensions } from '../types'; -import { getFormatService } from '../services'; -import { getAggId } from './get_agg_id'; - -export function getEmptyAspect(): Aspect { - return { - accessor: null, - aggId: null, - aggType: null, - title: i18n.translate('visTypeXy.aggResponse.allDocsTitle', { - defaultMessage: 'All docs', - }), - params: { - defaultValue: '_all', - }, - }; -} -export function getAspects( - columns: DatatableColumn[], - { x, y, z, series, splitColumn, splitRow }: Dimensions -): Aspects { - const seriesDimensions = Array.isArray(series) || series === undefined ? series : [series]; - - return { - x: getAspectsFromDimension(columns, x) ?? getEmptyAspect(), - y: getAspectsFromDimension(columns, y) ?? [], - z: z && z?.length > 0 ? getAspectsFromDimension(columns, z[0]) : undefined, - series: getAspectsFromDimension(columns, seriesDimensions), - splitColumn: splitColumn?.length ? getAspectsFromDimension(columns, splitColumn[0]) : undefined, - splitRow: splitRow?.length ? getAspectsFromDimension(columns, splitRow[0]) : undefined, - }; -} - -function getAspectsFromDimension( - columns: DatatableColumn[], - dimension?: Dimension | null -): Aspect | undefined; -function getAspectsFromDimension( - columns: DatatableColumn[], - dimensions?: Dimension[] | null -): Aspect[] | undefined; -function getAspectsFromDimension( - columns: DatatableColumn[], - dimensions?: Dimension | Dimension[] | null -): Aspect[] | Aspect | undefined { - if (!dimensions) { - return; - } - - if (Array.isArray(dimensions)) { - return compact( - dimensions.map((d) => { - const column = d && columns[d.accessor]; - return column && getAspect(column, d); - }) - ); - } - - const column = columns[dimensions.accessor]; - return column && getAspect(column, dimensions); -} - -const getAspect = ( - { id: accessor, name: title }: DatatableColumn, - { accessor: column, format, params, aggType }: Dimension -): Aspect => ({ - accessor, - column, - title, - format, - aggType, - aggId: getAggId(accessor), - formatter: (value: any) => getFormatService().deserialize(format).convert(value), - params, -}); diff --git a/src/plugins/vis_types/xy/public/config/get_axis.test.ts b/src/plugins/vis_types/xy/public/config/get_axis.test.ts deleted file mode 100644 index 7dddae5702b2e8..00000000000000 --- a/src/plugins/vis_types/xy/public/config/get_axis.test.ts +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { getScale } from './get_axis'; -import type { Scale } from '../types'; - -describe('getScale', () => { - const axisScale = { - type: 'linear', - mode: 'normal', - scaleType: 'linear', - } as Scale; - - it('returns linear type for a number', () => { - const format = { id: 'number' }; - const scale = getScale(axisScale, {}, format, true); - expect(scale.type).toBe('linear'); - }); - - it('returns ordinal type for a terms aggregation on a number field', () => { - const format = { - id: 'terms', - params: { - id: 'number', - otherBucketLabel: 'Other', - missingBucketLabel: 'Missing', - }, - }; - const scale = getScale(axisScale, {}, format, true); - expect(scale.type).toBe('ordinal'); - }); - - it('returns ordinal type for a terms aggregation on a string field', () => { - const format = { - id: 'terms', - params: { - id: 'string', - otherBucketLabel: 'Other', - missingBucketLabel: 'Missing', - }, - }; - const scale = getScale(axisScale, {}, format, true); - expect(scale.type).toBe('ordinal'); - }); - - it('returns ordinal type for a range aggregation on a number field', () => { - const format = { - id: 'range', - params: { - id: 'number', - }, - }; - const scale = getScale(axisScale, {}, format, true); - expect(scale.type).toBe('ordinal'); - }); - - it('returns time type for a date histogram aggregation', () => { - const format = { - id: 'date', - params: { - pattern: 'HH:mm', - }, - }; - const scale = getScale(axisScale, { date: true }, format, true); - expect(scale.type).toBe('time'); - }); - - it('returns linear type for an histogram aggregation', () => { - const format = { id: 'number' }; - const scale = getScale(axisScale, { interval: 1 }, format, true); - expect(scale.type).toBe('linear'); - }); -}); diff --git a/src/plugins/vis_types/xy/public/config/get_axis.ts b/src/plugins/vis_types/xy/public/config/get_axis.ts deleted file mode 100644 index 62e2345c805662..00000000000000 --- a/src/plugins/vis_types/xy/public/config/get_axis.ts +++ /dev/null @@ -1,199 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { identity } from 'lodash'; - -import { AxisSpec, TickFormatter, YDomainRange, ScaleType as ECScaleType } from '@elastic/charts'; - -import { LabelRotation } from '@kbn/charts-plugin/public'; -import { BUCKET_TYPES } from '@kbn/data-plugin/public'; -import { MULTILAYER_TIME_AXIS_STYLE } from '@kbn/charts-plugin/common'; - -import { - Aspect, - CategoryAxis, - Grid, - AxisConfig, - TickOptions, - ScaleConfig, - Scale, - ScaleType, - AxisType, - XScaleType, - YScaleType, - SeriesParam, -} from '../types'; - -export function getAxis( - { type, title: axisTitle, labels, scale: axisScale, ...axis }: CategoryAxis, - { categoryLines, valueAxis }: Grid, - { params, format, formatter, title: fallbackTitle = '', aggType }: Aspect, - seriesParams: SeriesParam[], - isDateHistogram = false, - useMultiLayerTimeAxis = false, - darkMode = false -): AxisConfig { - const isCategoryAxis = type === AxisType.Category; - // Hide unassigned axis, not supported in elastic charts - // TODO: refactor when disallowing unassigned axes - // https://github.com/elastic/kibana/issues/82752 - const show = - (isCategoryAxis || seriesParams.some(({ valueAxis: id }) => id === axis.id)) && axis.show; - const groupId = axis.id; - - const grid = isCategoryAxis - ? { - show: categoryLines, - } - : { - show: valueAxis === axis.id, - }; - // Date range formatter applied on xAccessor - const tickFormatter = - aggType === BUCKET_TYPES.DATE_RANGE || aggType === BUCKET_TYPES.RANGE ? identity : formatter; - const ticks: TickOptions = { - formatter: tickFormatter, - labelFormatter: getLabelFormatter(labels.truncate, tickFormatter), - show: labels.show, - rotation: labels.rotate, - showOverlappingLabels: !labels.filter, - showDuplicates: !labels.filter, - }; - const scale = getScale(axisScale, params, format, isCategoryAxis); - const title = axisTitle.text || fallbackTitle; - const fallbackRotation = - isCategoryAxis && isDateHistogram ? LabelRotation.Horizontal : LabelRotation.Vertical; - - return { - ...axis, - show, - groupId, - title, - ticks, - grid, - scale, - style: getAxisStyle(useMultiLayerTimeAxis, darkMode, ticks, title, fallbackRotation), - domain: getAxisDomain(scale, isCategoryAxis), - integersOnly: aggType === 'count', - timeAxisLayerCount: useMultiLayerTimeAxis ? 3 : 0, - }; -} - -function getLabelFormatter( - truncate?: number | null, - formatter?: TickFormatter -): TickFormatter | undefined { - if (truncate === null || truncate === undefined) { - return formatter; - } - - return (value: any) => { - const finalValue = `${formatter ? formatter(value) : value}`; - - if (finalValue.length > truncate) { - return `${finalValue.slice(0, truncate)}...`; - } - - return finalValue; - }; -} - -function getScaleType( - scale?: Scale, - isNumber?: boolean, - isTime = false, - isHistogram = false -): ECScaleType | undefined { - if (isTime) return ECScaleType.Time; - if (isHistogram) return ECScaleType.Linear; - - if (!isNumber) { - return ECScaleType.Ordinal; - } - - const type = scale?.type; - if (type === ScaleType.SquareRoot) { - return ECScaleType.Sqrt; - } - - return type; -} - -export function getScale( - scale: Scale, - params: Aspect['params'], - format: Aspect['format'], - isCategoryAxis: boolean -): ScaleConfig { - const type = ( - isCategoryAxis - ? getScaleType( - scale, - format?.id === 'number' || - (format?.params?.id === 'number' && - format?.id !== BUCKET_TYPES.RANGE && - format?.id !== BUCKET_TYPES.TERMS), - 'date' in params, - 'interval' in params - ) - : getScaleType(scale, true) - ) as S; - - return { - ...scale, - type, - }; -} - -function getAxisStyle( - isMultiLayerTimeAxis: boolean, - darkMode: boolean, - ticks?: TickOptions, - title?: string, - rotationFallback: LabelRotation = LabelRotation.Vertical -): AxisSpec['style'] { - return isMultiLayerTimeAxis - ? { - ...MULTILAYER_TIME_AXIS_STYLE, - tickLabel: { - ...MULTILAYER_TIME_AXIS_STYLE.tickLabel, - visible: Boolean(ticks?.show), - }, - tickLine: { - ...MULTILAYER_TIME_AXIS_STYLE.tickLine, - visible: Boolean(ticks?.show), - }, - axisTitle: { - visible: (title ?? '').trim().length > 0, - }, - } - : { - axisTitle: { - visible: (title ?? '').trim().length > 0, - }, - tickLabel: { - visible: Boolean(ticks?.show), - rotation: -(ticks?.rotation ?? rotationFallback), - }, - }; -} - -function getAxisDomain( - scale: ScaleConfig, - isCategoryAxis: boolean -): YDomainRange | undefined { - if (isCategoryAxis || !scale) { - return; - } - - const { min, max, defaultYExtents, boundsMargin } = scale; - const fit = defaultYExtents; - const padding = boundsMargin || undefined; - - return { fit, padding, min: min ?? NaN, max: max ?? NaN }; -} diff --git a/src/plugins/vis_types/xy/public/config/get_config.test.ts b/src/plugins/vis_types/xy/public/config/get_config.test.ts deleted file mode 100644 index 7608ef7cda4608..00000000000000 --- a/src/plugins/vis_types/xy/public/config/get_config.test.ts +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { getConfig } from './get_config'; -import { visData, visDataPercentile, visParamsWithTwoYAxes } from '../mocks'; -import { VisParams } from '../types'; - -// ToDo: add more tests for all the config properties -describe('getConfig', () => { - it('identifies it as a timeChart if the x axis has a date field', () => { - const config = getConfig(visData, visParamsWithTwoYAxes); - expect(config.isTimeChart).toBe(true); - }); - - it('not adds the current time marker if the param is set to false', () => { - const config = getConfig(visData, visParamsWithTwoYAxes); - expect(config.showCurrentTime).toBe(false); - }); - - it('adds the current time marker if the param is set to false', () => { - const newVisParams = { - ...visParamsWithTwoYAxes, - addTimeMarker: true, - }; - const config = getConfig(visData, newVisParams); - expect(config.showCurrentTime).toBe(true); - }); - - it('enables the histogram mode for a date_histogram', () => { - const config = getConfig(visData, visParamsWithTwoYAxes); - expect(config.enableHistogramMode).toBe(true); - }); - - it('assigns the correct formatter per y axis', () => { - const config = getConfig(visData, visParamsWithTwoYAxes); - expect(config.yAxes.length).toBe(2); - expect(config.yAxes[0].ticks?.formatter).toStrictEqual(config.aspects.y[0].formatter); - expect(config.yAxes[1].ticks?.formatter).toStrictEqual(config.aspects.y[1].formatter); - }); - - it('assigns the correct number of yAxes if the agg is hidden', () => { - // We have two axes but the one y dimension is hidden - const newVisParams = { - ...visParamsWithTwoYAxes, - dimensions: { - ...visParamsWithTwoYAxes.dimensions, - y: [ - { - label: 'Average memory', - aggType: 'avg', - params: {}, - accessor: 1, - format: { - id: 'number', - params: {}, - }, - }, - ], - }, - }; - const config = getConfig(visData, newVisParams); - expect(config.yAxes.length).toBe(1); - }); - - it('assigns the correct number of yAxes if the agg is Percentile', () => { - const newVisParams = { - ...visParamsWithTwoYAxes, - seriesParams: [ - { - type: 'line', - data: { - label: 'Percentiles of bytes', - id: '1', - }, - drawLinesBetweenPoints: true, - interpolate: 'linear', - lineWidth: 2, - mode: 'normal', - show: true, - showCircles: true, - circlesRadius: 3, - valueAxis: 'ValueAxis-1', - }, - ], - dimensions: { - ...visParamsWithTwoYAxes.dimensions, - y: ['1st', '5th', '25th', '50th', '75th', '95th', '99th'].map((prefix, accessor) => ({ - label: `${prefix} percentile of bytes`, - aggType: 'percentiles', - params: {}, - accessor, - format: { - id: 'number', - params: {}, - }, - })), - }, - } as VisParams; - const config = getConfig(visDataPercentile, newVisParams); - expect(config.yAxes.length).toBe(1); - }); -}); diff --git a/src/plugins/vis_types/xy/public/config/get_config.ts b/src/plugins/vis_types/xy/public/config/get_config.ts deleted file mode 100644 index 1a78b65f19f330..00000000000000 --- a/src/plugins/vis_types/xy/public/config/get_config.ts +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { Fit, ScaleContinuousType } from '@elastic/charts'; - -import { Datatable } from '@kbn/expressions-plugin/public'; -import { BUCKET_TYPES } from '@kbn/data-plugin/public'; -import { DateHistogramParams } from '@kbn/visualizations-plugin/public'; - -import { - Aspect, - AxisConfig, - SeriesParam, - VisConfig, - VisParams, - XScaleType, - YScaleType, -} from '../types'; -import { getThresholdLine } from './get_threshold_line'; -import { getRotation } from './get_rotation'; -import { getTooltip } from './get_tooltip'; -import { getLegend } from './get_legend'; -import { getAxis } from './get_axis'; -import { getAspects } from './get_aspects'; -import { ChartType } from '..'; -import { getSafeId } from '../utils/accessors'; - -export function getConfig( - table: Datatable, - params: VisParams, - useLegacyTimeAxis = false, - darkMode = false -): VisConfig { - const { - thresholdLine, - orderBucketsBySum, - addTimeMarker, - radiusRatio, - labels, - fittingFunction, - detailedTooltip, - isVislibVis, - fillOpacity, - } = params; - const aspects = getAspects(table.columns, params.dimensions); - const tooltip = getTooltip(aspects, params); - - const yAxes: Array> = []; - - // avoid duplicates based on aggId - const aspectVisited = new Set(); - params.dimensions.y.forEach((y) => { - const accessor = y.accessor; - const aspect = aspects.y.find(({ column }) => column === accessor); - const aggId = getSafeId(aspect?.aggId); - const serie = params.seriesParams.find(({ data: { id } }) => id === aggId); - const valueAxis = params.valueAxes.find(({ id }) => id === serie?.valueAxis); - if (aspect && valueAxis && !aspectVisited.has(aggId)) { - yAxes.push(getAxis(valueAxis, params.grid, aspect, params.seriesParams)); - aspectVisited.add(aggId); - } - }); - - const rotation = getRotation(params.categoryAxes[0]); - - const isDateHistogram = params.dimensions.x?.aggType === BUCKET_TYPES.DATE_HISTOGRAM; - const isHistogram = params.dimensions.x?.aggType === BUCKET_TYPES.HISTOGRAM; - const enableHistogramMode = - (isDateHistogram || isHistogram) && - shouldEnableHistogramMode(params.seriesParams, aspects.y, yAxes); - - const useMultiLayerTimeAxis = - enableHistogramMode && isDateHistogram && !useLegacyTimeAxis && rotation === 0; - - const xAxis = getAxis( - params.categoryAxes[0], - params.grid, - aspects.x, - params.seriesParams, - isDateHistogram, - useMultiLayerTimeAxis, - darkMode - ); - - const isTimeChart = (aspects.x.params as DateHistogramParams).date ?? false; - - return { - // NOTE: downscale ratio to match current vislib implementation - markSizeRatio: radiusRatio * 0.6, - fittingFunction: fittingFunction ?? Fit.Linear, - fillOpacity, - detailedTooltip, - orderBucketsBySum, - isTimeChart, - isVislibVis, - showCurrentTime: addTimeMarker && isTimeChart, - showValueLabel: labels.show ?? false, - enableHistogramMode, - tooltip, - aspects, - xAxis, - yAxes, - legend: getLegend(params), - rotation, - thresholdLine: getThresholdLine(thresholdLine, yAxes, params.seriesParams), - }; -} - -/** - * disables histogram mode for any config that has non-stacked clustered bars - * - * @param seriesParams - * @param yAspects - * @param yAxes - */ -const shouldEnableHistogramMode = ( - seriesParams: SeriesParam[], - yAspects: Aspect[], - yAxes: Array> -): boolean => { - const bars = seriesParams.filter(({ type, data: { id: paramId } }) => { - return ( - type === ChartType.Histogram && yAspects.find(({ aggId }) => aggId === paramId) !== undefined - ); - }); - - const groupIds = [ - ...bars.reduce>((acc, { valueAxis: groupId, mode }) => { - acc.add(groupId); - return acc; - }, new Set()), - ]; - - if (groupIds.length > 1) { - return false; - } - - return bars.every(({ valueAxis: groupId, mode }) => { - return mode === 'stacked'; - }); -}; diff --git a/src/plugins/vis_types/xy/public/config/get_legend.ts b/src/plugins/vis_types/xy/public/config/get_legend.ts deleted file mode 100644 index 9a1c9e4bc9c58e..00000000000000 --- a/src/plugins/vis_types/xy/public/config/get_legend.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { LegendOptions, VisParams } from '../types'; - -export function getLegend({ addLegend, legendPosition }: VisParams): LegendOptions { - return { - show: addLegend, - position: legendPosition, - }; -} diff --git a/src/plugins/vis_types/xy/public/config/get_threshold_line.ts b/src/plugins/vis_types/xy/public/config/get_threshold_line.ts deleted file mode 100644 index 64eb7e5e24a805..00000000000000 --- a/src/plugins/vis_types/xy/public/config/get_threshold_line.ts +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { - ThresholdLineConfig, - ThresholdLine, - ThresholdLineStyle, - AxisConfig, - SeriesParam, - YScaleType, -} from '../types'; - -export function getThresholdLine( - { style, ...rest }: ThresholdLine, - yAxes: Array>, - seriesParams: SeriesParam[] -): ThresholdLineConfig { - const groupId = yAxes.find(({ id }) => - seriesParams.some(({ valueAxis }) => id === valueAxis) - )?.groupId; - - return { - ...rest, - dash: getDash(style), - groupId, - }; -} - -function getDash(style: ThresholdLineStyle): number[] | undefined { - switch (style) { - case ThresholdLineStyle.Dashed: - return [10, 5]; - case ThresholdLineStyle.DotDashed: - return [20, 5, 5, 5]; - case ThresholdLineStyle.Full: - default: - return; - } -} diff --git a/src/plugins/vis_types/xy/public/config/get_tooltip.ts b/src/plugins/vis_types/xy/public/config/get_tooltip.ts deleted file mode 100644 index 69961cbed7699c..00000000000000 --- a/src/plugins/vis_types/xy/public/config/get_tooltip.ts +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { TooltipType } from '@elastic/charts'; - -import { Aspects, VisParams, TooltipConfig } from '../types'; -import { getDetailedTooltip } from '../components/detailed_tooltip'; - -export function getTooltip( - aspects: Aspects, - { addTooltip, detailedTooltip }: VisParams -): TooltipConfig { - return { - type: addTooltip ? TooltipType.VerticalCursor : TooltipType.None, - detailedTooltip: detailedTooltip ? getDetailedTooltip(aspects) : undefined, - }; -} diff --git a/src/plugins/vis_types/xy/public/expression_functions/category_axis.ts b/src/plugins/vis_types/xy/public/expression_functions/category_axis.ts deleted file mode 100644 index 5283a54e57f30c..00000000000000 --- a/src/plugins/vis_types/xy/public/expression_functions/category_axis.ts +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { i18n } from '@kbn/i18n'; -import type { - ExpressionFunctionDefinition, - Datatable, - ExpressionValueBoxed, -} from '@kbn/expressions-plugin/public'; -import type { CategoryAxis } from '../types'; -import type { ExpressionValueScale } from './vis_scale'; -import type { ExpressionValueLabel } from './label'; - -export interface Arguments extends Omit { - title?: string; - scale: ExpressionValueScale; - labels: ExpressionValueLabel; -} - -export type ExpressionValueCategoryAxis = ExpressionValueBoxed< - 'category_axis', - { - id: CategoryAxis['id']; - show: CategoryAxis['show']; - position: CategoryAxis['position']; - axisType: CategoryAxis['type']; - title: { - text?: string; - }; - labels: CategoryAxis['labels']; - scale: CategoryAxis['scale']; - } ->; - -export const categoryAxis = (): ExpressionFunctionDefinition< - 'categoryaxis', - Datatable | null, - Arguments, - ExpressionValueCategoryAxis -> => ({ - name: 'categoryaxis', - help: i18n.translate('visTypeXy.function.categoryAxis.help', { - defaultMessage: 'Generates category axis object', - }), - type: 'category_axis', - args: { - id: { - types: ['string'], - help: i18n.translate('visTypeXy.function.categoryAxis.id.help', { - defaultMessage: 'Id of category axis', - }), - required: true, - }, - show: { - types: ['boolean'], - help: i18n.translate('visTypeXy.function.categoryAxis.show.help', { - defaultMessage: 'Show the category axis', - }), - required: true, - }, - position: { - types: ['string'], - help: i18n.translate('visTypeXy.function.categoryAxis.position.help', { - defaultMessage: 'Position of the category axis', - }), - required: true, - }, - type: { - types: ['string'], - help: i18n.translate('visTypeXy.function.categoryAxis.type.help', { - defaultMessage: 'Type of the category axis. Can be category or value', - }), - required: true, - }, - title: { - types: ['string'], - help: i18n.translate('visTypeXy.function.categoryAxis.title.help', { - defaultMessage: 'Title of the category axis', - }), - }, - scale: { - types: ['vis_scale'], - help: i18n.translate('visTypeXy.function.categoryAxis.scale.help', { - defaultMessage: 'Scale config', - }), - }, - labels: { - types: ['label'], - help: i18n.translate('visTypeXy.function.categoryAxis.labels.help', { - defaultMessage: 'Axis label config', - }), - }, - }, - fn: (context, args) => { - return { - type: 'category_axis', - id: args.id, - show: args.show, - position: args.position, - axisType: args.type, - title: { - text: args.title, - }, - scale: { - ...args.scale, - type: args.scale.scaleType, - }, - labels: args.labels, - }; - }, -}); diff --git a/src/plugins/vis_types/xy/public/expression_functions/index.ts b/src/plugins/vis_types/xy/public/expression_functions/index.ts deleted file mode 100644 index 4d6b2305a36514..00000000000000 --- a/src/plugins/vis_types/xy/public/expression_functions/index.ts +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -export { visTypeXyVisFn } from './xy_vis_fn'; - -export type { ExpressionValueCategoryAxis } from './category_axis'; -export { categoryAxis } from './category_axis'; -export type { ExpressionValueTimeMarker } from './time_marker'; -export { timeMarker } from './time_marker'; -export type { ExpressionValueValueAxis } from './value_axis'; -export { valueAxis } from './value_axis'; -export type { ExpressionValueSeriesParam } from './series_param'; -export { seriesParam } from './series_param'; -export type { ExpressionValueThresholdLine } from './threshold_line'; -export { thresholdLine } from './threshold_line'; -export type { ExpressionValueLabel } from './label'; -export { label } from './label'; -export type { ExpressionValueScale } from './vis_scale'; -export { visScale } from './vis_scale'; diff --git a/src/plugins/vis_types/xy/public/expression_functions/label.ts b/src/plugins/vis_types/xy/public/expression_functions/label.ts deleted file mode 100644 index cd3eea2b68bc7f..00000000000000 --- a/src/plugins/vis_types/xy/public/expression_functions/label.ts +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { i18n } from '@kbn/i18n'; -import type { Labels } from '@kbn/charts-plugin/public'; -import type { - ExpressionFunctionDefinition, - Datatable, - ExpressionValueBoxed, -} from '@kbn/expressions-plugin/public'; - -export type ExpressionValueLabel = ExpressionValueBoxed< - 'label', - { - color?: Labels['color']; - filter?: Labels['filter']; - overwriteColor?: Labels['overwriteColor']; - rotate?: Labels['rotate']; - show?: Labels['show']; - truncate?: Labels['truncate']; - } ->; - -export const label = (): ExpressionFunctionDefinition< - 'label', - Datatable | null, - Labels, - ExpressionValueLabel -> => ({ - name: 'label', - help: i18n.translate('visTypeXy.function.label.help', { - defaultMessage: 'Generates label object', - }), - type: 'label', - args: { - color: { - types: ['string'], - help: i18n.translate('visTypeXy.function.label.color.help', { - defaultMessage: 'Color of label', - }), - }, - filter: { - types: ['boolean'], - help: i18n.translate('visTypeXy.function.label.filter.help', { - defaultMessage: 'Hides overlapping labels and duplicates on axis', - }), - }, - overwriteColor: { - types: ['boolean'], - help: i18n.translate('visTypeXy.function.label.overwriteColor.help', { - defaultMessage: 'Overwrite color', - }), - }, - rotate: { - types: ['number'], - help: i18n.translate('visTypeXy.function.label.rotate.help', { - defaultMessage: 'Rotate angle', - }), - }, - show: { - types: ['boolean'], - help: i18n.translate('visTypeXy.function.label.show.help', { - defaultMessage: 'Show label', - }), - }, - truncate: { - types: ['number', 'null'], - help: i18n.translate('visTypeXy.function.label.truncate.help', { - defaultMessage: 'The number of symbols before truncating', - }), - }, - }, - fn: (context, args) => { - return { - type: 'label', - color: args.color, - filter: args.hasOwnProperty('filter') ? args.filter : undefined, - overwriteColor: args.overwriteColor, - rotate: args.rotate, - show: args.show, - truncate: args.truncate, - }; - }, -}); diff --git a/src/plugins/vis_types/xy/public/expression_functions/series_param.ts b/src/plugins/vis_types/xy/public/expression_functions/series_param.ts deleted file mode 100644 index df5ed2ec0d9b4c..00000000000000 --- a/src/plugins/vis_types/xy/public/expression_functions/series_param.ts +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { i18n } from '@kbn/i18n'; -import type { - ExpressionFunctionDefinition, - Datatable, - ExpressionValueBoxed, -} from '@kbn/expressions-plugin/public'; -import type { SeriesParam } from '../types'; - -export interface Arguments extends Omit { - label: string; - id: string; -} - -export type ExpressionValueSeriesParam = ExpressionValueBoxed< - 'series_param', - { - data: { label: string; id: string }; - drawLinesBetweenPoints?: boolean; - interpolate?: SeriesParam['interpolate']; - lineWidth?: number; - mode: SeriesParam['mode']; - show: boolean; - showCircles: boolean; - circlesRadius: number; - seriesParamType: SeriesParam['type']; - valueAxis: string; - } ->; - -export const seriesParam = (): ExpressionFunctionDefinition< - 'seriesparam', - Datatable, - Arguments, - ExpressionValueSeriesParam -> => ({ - name: 'seriesparam', - help: i18n.translate('visTypeXy.function.seriesparam.help', { - defaultMessage: 'Generates series param object', - }), - type: 'series_param', - inputTypes: ['datatable'], - args: { - label: { - types: ['string'], - help: i18n.translate('visTypeXy.function.seriesParam.label.help', { - defaultMessage: 'Name of series param', - }), - required: true, - }, - id: { - types: ['string'], - help: i18n.translate('visTypeXy.function.seriesParam.id.help', { - defaultMessage: 'Id of series param', - }), - required: true, - }, - drawLinesBetweenPoints: { - types: ['boolean'], - help: i18n.translate('visTypeXy.function.seriesParam.drawLinesBetweenPoints.help', { - defaultMessage: 'Draw lines between points', - }), - }, - interpolate: { - types: ['string'], - help: i18n.translate('visTypeXy.function.seriesParam.interpolate.help', { - defaultMessage: 'Interpolate mode. Can be linear, cardinal or step-after', - }), - }, - show: { - types: ['boolean'], - help: i18n.translate('visTypeXy.function.seriesParam.show.help', { - defaultMessage: 'Show param', - }), - required: true, - }, - lineWidth: { - types: ['number'], - help: i18n.translate('visTypeXy.function.seriesParam.lineWidth.help', { - defaultMessage: 'Width of line', - }), - }, - mode: { - types: ['string'], - help: i18n.translate('visTypeXy.function.seriesParam.mode.help', { - defaultMessage: 'Chart mode. Can be stacked or percentage', - }), - }, - showCircles: { - types: ['boolean'], - help: i18n.translate('visTypeXy.function.seriesParam.showCircles.help', { - defaultMessage: 'Show circles', - }), - }, - circlesRadius: { - types: ['number'], - help: i18n.translate('visTypeXy.function.seriesParam.circlesRadius.help', { - defaultMessage: 'Defines the circles size (radius)', - }), - }, - type: { - types: ['string'], - help: i18n.translate('visTypeXy.function.seriesParam.type.help', { - defaultMessage: 'Chart type. Can be line, area or histogram', - }), - }, - valueAxis: { - types: ['string'], - help: i18n.translate('visTypeXy.function.seriesParam.valueAxis.help', { - defaultMessage: 'Name of value axis', - }), - }, - }, - fn: (context, args) => { - return { - type: 'series_param', - data: { label: args.label, id: args.id }, - drawLinesBetweenPoints: args.drawLinesBetweenPoints, - interpolate: args.interpolate, - lineWidth: args.lineWidth, - mode: args.mode, - show: args.show, - showCircles: args.showCircles, - circlesRadius: args.circlesRadius, - seriesParamType: args.type, - valueAxis: args.valueAxis, - }; - }, -}); diff --git a/src/plugins/vis_types/xy/public/expression_functions/threshold_line.ts b/src/plugins/vis_types/xy/public/expression_functions/threshold_line.ts deleted file mode 100644 index 9a496158bf5a79..00000000000000 --- a/src/plugins/vis_types/xy/public/expression_functions/threshold_line.ts +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { i18n } from '@kbn/i18n'; -import type { - ExpressionFunctionDefinition, - Datatable, - ExpressionValueBoxed, -} from '@kbn/expressions-plugin/public'; -import type { ThresholdLine } from '../types'; - -export type ExpressionValueThresholdLine = ExpressionValueBoxed< - 'threshold_line', - { - show: ThresholdLine['show']; - value: ThresholdLine['value']; - width: ThresholdLine['width']; - style: ThresholdLine['style']; - color: ThresholdLine['color']; - } ->; - -export const thresholdLine = (): ExpressionFunctionDefinition< - 'thresholdline', - Datatable | null, - ThresholdLine, - ExpressionValueThresholdLine -> => ({ - name: 'thresholdline', - help: i18n.translate('visTypeXy.function.thresholdLine.help', { - defaultMessage: 'Generates threshold line object', - }), - type: 'threshold_line', - args: { - show: { - types: ['boolean'], - help: i18n.translate('visTypeXy.function.thresholdLine.show.help', { - defaultMessage: 'Show threshould line', - }), - required: true, - }, - value: { - types: ['number', 'null'], - help: i18n.translate('visTypeXy.function.thresholdLine.value.help', { - defaultMessage: 'Threshold value', - }), - required: true, - }, - width: { - types: ['number', 'null'], - help: i18n.translate('visTypeXy.function.thresholdLine.width.help', { - defaultMessage: 'Width of threshold line', - }), - required: true, - }, - style: { - types: ['string'], - help: i18n.translate('visTypeXy.function.thresholdLine.style.help', { - defaultMessage: 'Style of threshold line. Can be full, dashed or dot-dashed', - }), - required: true, - }, - color: { - types: ['string'], - help: i18n.translate('visTypeXy.function.thresholdLine.color.help', { - defaultMessage: 'Color of threshold line', - }), - required: true, - }, - }, - fn: (context, args) => { - return { - type: 'threshold_line', - show: args.show, - value: args.value, - width: args.width, - style: args.style, - color: args.color, - }; - }, -}); diff --git a/src/plugins/vis_types/xy/public/expression_functions/time_marker.ts b/src/plugins/vis_types/xy/public/expression_functions/time_marker.ts deleted file mode 100644 index f3b8e9cdc61d06..00000000000000 --- a/src/plugins/vis_types/xy/public/expression_functions/time_marker.ts +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { i18n } from '@kbn/i18n'; -import type { - ExpressionFunctionDefinition, - Datatable, - ExpressionValueBoxed, -} from '@kbn/expressions-plugin/public'; -import type { TimeMarker } from '../types'; - -export type ExpressionValueTimeMarker = ExpressionValueBoxed< - 'time_marker', - { - time: string; - class?: string; - color?: string; - opacity?: number; - width?: number; - } ->; - -export const timeMarker = (): ExpressionFunctionDefinition< - 'timemarker', - Datatable | null, - TimeMarker, - ExpressionValueTimeMarker -> => ({ - name: 'timemarker', - help: i18n.translate('visTypeXy.function.timemarker.help', { - defaultMessage: 'Generates time marker object', - }), - type: 'time_marker', - args: { - time: { - types: ['string'], - help: i18n.translate('visTypeXy.function.timeMarker.time.help', { - defaultMessage: 'Exact Time', - }), - required: true, - }, - class: { - types: ['string'], - help: i18n.translate('visTypeXy.function.timeMarker.class.help', { - defaultMessage: 'Css class name', - }), - }, - color: { - types: ['string'], - help: i18n.translate('visTypeXy.function.timeMarker.color.help', { - defaultMessage: 'Color of time marker', - }), - }, - opacity: { - types: ['number'], - help: i18n.translate('visTypeXy.function.timeMarker.opacity.help', { - defaultMessage: 'Opacity of time marker', - }), - }, - width: { - types: ['number'], - help: i18n.translate('visTypeXy.function.timeMarker.width.help', { - defaultMessage: 'Width of time marker', - }), - }, - }, - fn: (context, args) => { - return { - type: 'time_marker', - time: args.time, - class: args.class, - color: args.color, - opacity: args.opacity, - width: args.width, - }; - }, -}); diff --git a/src/plugins/vis_types/xy/public/expression_functions/value_axis.ts b/src/plugins/vis_types/xy/public/expression_functions/value_axis.ts deleted file mode 100644 index 8b32084d8b5884..00000000000000 --- a/src/plugins/vis_types/xy/public/expression_functions/value_axis.ts +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { i18n } from '@kbn/i18n'; -import type { - ExpressionFunctionDefinition, - Datatable, - ExpressionValueBoxed, -} from '@kbn/expressions-plugin/public'; -import type { ExpressionValueCategoryAxis } from './category_axis'; -import type { CategoryAxis } from '../types'; - -interface Arguments { - name: string; - axisParams: ExpressionValueCategoryAxis; -} - -export type ExpressionValueValueAxis = ExpressionValueBoxed< - 'value_axis', - { - name: string; - id: string; - show: boolean; - position: CategoryAxis['position']; - axisType: CategoryAxis['type']; - title: { - text?: string; - }; - labels: CategoryAxis['labels']; - scale: CategoryAxis['scale']; - } ->; - -export const valueAxis = (): ExpressionFunctionDefinition< - 'valueaxis', - Datatable | null, - Arguments, - ExpressionValueValueAxis -> => ({ - name: 'valueaxis', - help: i18n.translate('visTypeXy.function.valueaxis.help', { - defaultMessage: 'Generates value axis object', - }), - type: 'value_axis', - args: { - name: { - types: ['string'], - help: i18n.translate('visTypeXy.function.valueAxis.name.help', { - defaultMessage: 'Name of value axis', - }), - required: true, - }, - axisParams: { - types: ['category_axis'], - help: i18n.translate('visTypeXy.function.valueAxis.axisParams.help', { - defaultMessage: 'Value axis params', - }), - required: true, - }, - }, - fn: (context, args) => { - return { - type: 'value_axis', - name: args.name, - id: args.axisParams.id, - show: args.axisParams.show, - position: args.axisParams.position, - axisType: args.axisParams.axisType, - title: args.axisParams.title, - scale: args.axisParams.scale, - labels: args.axisParams.labels, - }; - }, -}); diff --git a/src/plugins/vis_types/xy/public/expression_functions/vis_scale.ts b/src/plugins/vis_types/xy/public/expression_functions/vis_scale.ts deleted file mode 100644 index 33952473e59162..00000000000000 --- a/src/plugins/vis_types/xy/public/expression_functions/vis_scale.ts +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { i18n } from '@kbn/i18n'; -import type { - ExpressionFunctionDefinition, - Datatable, - ExpressionValueBoxed, -} from '@kbn/expressions-plugin/public'; -import type { Scale } from '../types'; - -export type ExpressionValueScale = ExpressionValueBoxed< - 'vis_scale', - { - boundsMargin?: Scale['boundsMargin']; - defaultYExtents?: Scale['defaultYExtents']; - max?: Scale['max']; - min?: Scale['min']; - mode?: Scale['mode']; - setYExtents?: Scale['setYExtents']; - scaleType: Scale['type']; - } ->; - -export const visScale = (): ExpressionFunctionDefinition< - 'visscale', - Datatable | null, - Scale, - ExpressionValueScale -> => ({ - name: 'visscale', - help: i18n.translate('visTypeXy.function.scale.help', { - defaultMessage: 'Generates scale object', - }), - type: 'vis_scale', - args: { - boundsMargin: { - types: ['number', 'string'], - help: i18n.translate('visTypeXy.function.scale.boundsMargin.help', { - defaultMessage: 'Margin of bounds', - }), - }, - defaultYExtents: { - types: ['boolean'], - help: i18n.translate('visTypeXy.function.scale.defaultYExtents.help', { - defaultMessage: 'Flag which allows to scale to data bounds', - }), - }, - setYExtents: { - types: ['boolean'], - help: i18n.translate('visTypeXy.function.scale.setYExtents.help', { - defaultMessage: 'Flag which allows to set your own extents', - }), - }, - max: { - types: ['number', 'null'], - help: i18n.translate('visTypeXy.function.scale.max.help', { - defaultMessage: 'Max value', - }), - }, - min: { - types: ['number', 'null'], - help: i18n.translate('visTypeXy.function.scale.min.help', { - defaultMessage: 'Min value', - }), - }, - mode: { - types: ['string'], - help: i18n.translate('visTypeXy.function.scale.mode.help', { - defaultMessage: 'Scale mode. Can be normal, percentage, wiggle or silhouette', - }), - }, - type: { - types: ['string'], - help: i18n.translate('visTypeXy.function.scale.type.help', { - defaultMessage: 'Scale type. Can be linear, log or square root', - }), - required: true, - }, - }, - fn: (context, args) => { - return { - type: 'vis_scale', - boundsMargin: args.boundsMargin, - defaultYExtents: args.defaultYExtents, - setYExtents: args.setYExtents, - max: args.max, - min: args.min, - mode: args.mode, - scaleType: args.type, - }; - }, -}); diff --git a/src/plugins/vis_types/xy/public/expression_functions/xy_vis_fn.ts b/src/plugins/vis_types/xy/public/expression_functions/xy_vis_fn.ts deleted file mode 100644 index 8dc7481300bc0a..00000000000000 --- a/src/plugins/vis_types/xy/public/expression_functions/xy_vis_fn.ts +++ /dev/null @@ -1,370 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { i18n } from '@kbn/i18n'; - -import type { - ExpressionFunctionDefinition, - Datatable, - Render, -} from '@kbn/expressions-plugin/common'; -import { - prepareLogTable, - Dimension, - DEFAULT_LEGEND_SIZE, - LegendSize, -} from '@kbn/visualizations-plugin/public'; -import type { VisParams, XYVisConfig } from '../types'; -import type { XyVisType } from '../../common'; - -export const visName = 'xy_vis'; -export interface RenderValue { - visData: Datatable; - visType: XyVisType; - visConfig: VisParams; - syncColors: boolean; - syncTooltips: boolean; -} - -export type VisTypeXyExpressionFunctionDefinition = ExpressionFunctionDefinition< - typeof visName, - Datatable, - XYVisConfig, - Render ->; - -export const visTypeXyVisFn = (): VisTypeXyExpressionFunctionDefinition => ({ - name: visName, - type: 'render', - context: { - types: ['datatable'], - }, - help: i18n.translate('visTypeXy.functions.help', { - defaultMessage: 'XY visualization', - }), - args: { - type: { - types: ['string'], - default: '""', - help: 'xy vis type', - }, - chartType: { - types: ['string'], - help: i18n.translate('visTypeXy.function.args.args.chartType.help', { - defaultMessage: 'Type of a chart. Can be line, area or histogram', - }), - }, - addTimeMarker: { - types: ['boolean'], - help: i18n.translate('visTypeXy.function.args.addTimeMarker.help', { - defaultMessage: 'Show time marker', - }), - }, - truncateLegend: { - types: ['boolean'], - help: i18n.translate('visTypeXy.function.args.truncateLegend.help', { - defaultMessage: 'Defines if the legend will be truncated or not', - }), - }, - maxLegendLines: { - types: ['number'], - help: i18n.translate('visTypeXy.function.args.args.maxLegendLines.help', { - defaultMessage: 'Defines the maximum lines per legend item', - }), - }, - legendSize: { - types: ['string'], - default: DEFAULT_LEGEND_SIZE, - help: i18n.translate('visTypeXy.function.args.args.legendSize.help', { - defaultMessage: 'Specifies the legend size.', - }), - options: [ - LegendSize.AUTO, - LegendSize.SMALL, - LegendSize.MEDIUM, - LegendSize.LARGE, - LegendSize.EXTRA_LARGE, - ], - strict: true, - }, - addLegend: { - types: ['boolean'], - help: i18n.translate('visTypeXy.function.args.addLegend.help', { - defaultMessage: 'Show chart legend', - }), - }, - addTooltip: { - types: ['boolean'], - help: i18n.translate('visTypeXy.function.args.addTooltip.help', { - defaultMessage: 'Show tooltip on hover', - }), - }, - legendPosition: { - types: ['string'], - help: i18n.translate('visTypeXy.function.args.legendPosition.help', { - defaultMessage: 'Position the legend on top, bottom, left, right of the chart', - }), - }, - categoryAxes: { - types: ['category_axis'], - help: i18n.translate('visTypeXy.function.args.categoryAxes.help', { - defaultMessage: 'Category axis config', - }), - multi: true, - }, - thresholdLine: { - types: ['threshold_line'], - help: i18n.translate('visTypeXy.function.args.thresholdLine.help', { - defaultMessage: 'Threshold line config', - }), - }, - labels: { - types: ['label'], - help: i18n.translate('visTypeXy.function.args.labels.help', { - defaultMessage: 'Chart labels config', - }), - }, - orderBucketsBySum: { - types: ['boolean'], - help: i18n.translate('visTypeXy.function.args.orderBucketsBySum.help', { - defaultMessage: 'Order buckets by sum', - }), - }, - seriesParams: { - types: ['series_param'], - help: i18n.translate('visTypeXy.function.args.seriesParams.help', { - defaultMessage: 'Series param config', - }), - multi: true, - }, - valueAxes: { - types: ['value_axis'], - help: i18n.translate('visTypeXy.function.args.valueAxes.help', { - defaultMessage: 'Value axis config', - }), - multi: true, - }, - radiusRatio: { - types: ['number'], - help: i18n.translate('visTypeXy.function.args.radiusRatio.help', { - defaultMessage: 'Dot size ratio', - }), - }, - gridCategoryLines: { - types: ['boolean'], - help: i18n.translate('visTypeXy.function.args.gridCategoryLines.help', { - defaultMessage: 'Show grid category lines in chart', - }), - }, - gridValueAxis: { - types: ['string'], - help: i18n.translate('visTypeXy.function.args.gridValueAxis.help', { - defaultMessage: 'Name of value axis for which we show grid', - }), - }, - isVislibVis: { - types: ['boolean'], - help: i18n.translate('visTypeXy.function.args.isVislibVis.help', { - defaultMessage: - 'Flag to indicate old vislib visualizations. Used for backwards compatibility including colors', - }), - }, - detailedTooltip: { - types: ['boolean'], - help: i18n.translate('visTypeXy.function.args.detailedTooltip.help', { - defaultMessage: 'Show detailed tooltip', - }), - }, - fittingFunction: { - types: ['string'], - help: i18n.translate('visTypeXy.function.args.fittingFunction.help', { - defaultMessage: 'Name of fitting function', - }), - }, - times: { - types: ['time_marker'], - help: i18n.translate('visTypeXy.function.args.times.help', { - defaultMessage: 'Time marker config', - }), - multi: true, - }, - palette: { - types: ['string'], - help: i18n.translate('visTypeXy.function.args.palette.help', { - defaultMessage: 'Defines the chart palette name', - }), - }, - fillOpacity: { - types: ['number'], - help: i18n.translate('visTypeXy.function.args.fillOpacity.help', { - defaultMessage: 'Defines the area chart fill opacity', - }), - }, - xDimension: { - types: ['xy_dimension', 'null'], - help: i18n.translate('visTypeXy.function.args.xDimension.help', { - defaultMessage: 'X axis dimension config', - }), - }, - yDimension: { - types: ['xy_dimension'], - help: i18n.translate('visTypeXy.function.args.yDimension.help', { - defaultMessage: 'Y axis dimension config', - }), - multi: true, - }, - zDimension: { - types: ['xy_dimension'], - help: i18n.translate('visTypeXy.function.args.zDimension.help', { - defaultMessage: 'Z axis dimension config', - }), - multi: true, - }, - widthDimension: { - types: ['xy_dimension'], - help: i18n.translate('visTypeXy.function.args.widthDimension.help', { - defaultMessage: 'Width dimension config', - }), - multi: true, - }, - seriesDimension: { - types: ['xy_dimension'], - help: i18n.translate('visTypeXy.function.args.seriesDimension.help', { - defaultMessage: 'Series dimension config', - }), - multi: true, - }, - splitRowDimension: { - types: ['xy_dimension'], - help: i18n.translate('visTypeXy.function.args.splitRowDimension.help', { - defaultMessage: 'Split by row dimension config', - }), - multi: true, - }, - splitColumnDimension: { - types: ['xy_dimension'], - help: i18n.translate('visTypeXy.function.args.splitColumnDimension.help', { - defaultMessage: 'Split by column dimension config', - }), - multi: true, - }, - ariaLabel: { - types: ['string'], - help: i18n.translate('visTypeXy.function.args.ariaLabel.help', { - defaultMessage: 'Specifies the aria label of the xy chart', - }), - required: false, - }, - }, - fn(context, args, handlers) { - const visType = args.type; - const visConfig = { - ariaLabel: - args.ariaLabel ?? - (handlers.variables?.embeddableTitle as string) ?? - handlers.getExecutionContext?.()?.description, - type: args.chartType, - addLegend: args.addLegend, - addTooltip: args.addTooltip, - legendPosition: args.legendPosition, - addTimeMarker: args.addTimeMarker, - maxLegendLines: args.maxLegendLines, - truncateLegend: args.truncateLegend, - legendSize: args.legendSize, - categoryAxes: args.categoryAxes.map((categoryAxis) => ({ - ...categoryAxis, - type: categoryAxis.axisType, - })), - orderBucketsBySum: args.orderBucketsBySum, - labels: args.labels, - thresholdLine: args.thresholdLine, - valueAxes: args.valueAxes.map((valueAxis) => ({ ...valueAxis, type: valueAxis.axisType })), - grid: { - categoryLines: args.gridCategoryLines, - valueAxis: args.gridValueAxis, - }, - seriesParams: args.seriesParams.map((seriesParam) => ({ - ...seriesParam, - type: seriesParam.seriesParamType, - })), - radiusRatio: args.radiusRatio, - times: args.times, - isVislibVis: args.isVislibVis, - detailedTooltip: args.detailedTooltip, - palette: { - type: 'palette', - name: args.palette, - }, - fillOpacity: args.fillOpacity, - fittingFunction: args.fittingFunction, - dimensions: { - x: args.xDimension, - y: args.yDimension, - z: args.zDimension, - width: args.widthDimension, - series: args.seriesDimension, - splitRow: args.splitRowDimension, - splitColumn: args.splitColumnDimension, - }, - } as VisParams; - - if (handlers?.inspectorAdapters?.tables) { - const argsTable: Dimension[] = [ - [ - args.yDimension, - i18n.translate('visTypeXy.function.dimension.metric', { - defaultMessage: 'Metric', - }), - ], - [ - args.zDimension, - i18n.translate('visTypeXy.function.adimension.dotSize', { - defaultMessage: 'Dot size', - }), - ], - [ - args.splitColumnDimension, - i18n.translate('visTypeXy.function.dimension.splitcolumn', { - defaultMessage: 'Column split', - }), - ], - [ - args.splitRowDimension, - i18n.translate('visTypeXy.function.dimension.splitrow', { - defaultMessage: 'Row split', - }), - ], - ]; - - if (args.xDimension) { - argsTable.push([ - [args.xDimension], - i18n.translate('visTypeXy.function.adimension.bucket', { - defaultMessage: 'Bucket', - }), - ]); - } - - const logTable = prepareLogTable(context, argsTable); - handlers.inspectorAdapters.tables.logDatatable('default', logTable); - } - - return { - type: 'render', - as: visName, - value: { - context, - visType, - visConfig, - visData: context, - syncColors: handlers?.isSyncColorsEnabled?.() ?? false, - syncTooltips: handlers?.isSyncTooltipsEnabled?.() ?? false, - }, - }; - }, -}); diff --git a/src/plugins/vis_types/xy/public/index.ts b/src/plugins/vis_types/xy/public/index.ts index 41a8e08fa1ad25..7ad2e3058e49f0 100644 --- a/src/plugins/vis_types/xy/public/index.ts +++ b/src/plugins/vis_types/xy/public/index.ts @@ -29,7 +29,6 @@ export type { ValidationVisOptionsProps } from './editor/components/common/valid export { TruncateLabelsOption } from './editor/components/common/truncate_labels'; export { getPositions } from './editor/positions'; export { getScaleTypes } from './editor/scale_types'; -export { getAggId } from './config/get_agg_id'; // Export common types export * from '../common'; diff --git a/src/plugins/vis_types/xy/public/plugin.ts b/src/plugins/vis_types/xy/public/plugin.ts index 29a5e434a5f011..4561006e43e922 100644 --- a/src/plugins/vis_types/xy/public/plugin.ts +++ b/src/plugins/vis_types/xy/public/plugin.ts @@ -6,31 +6,12 @@ * Side Public License, v 1. */ -import type { CoreSetup, CoreStart, Plugin } from '@kbn/core/public'; -import type { Plugin as ExpressionsPublicPlugin } from '@kbn/expressions-plugin/public'; -import type { VisualizationsSetup, VisualizationsStart } from '@kbn/visualizations-plugin/public'; -import type { FieldFormatsStart } from '@kbn/field-formats-plugin/public'; -import type { ChartsPluginSetup, ChartsPluginStart } from '@kbn/charts-plugin/public'; -import type { DataPublicPluginStart } from '@kbn/data-plugin/public'; -import type { - UsageCollectionSetup, - UsageCollectionStart, -} from '@kbn/usage-collection-plugin/public'; -import { createStartServicesGetter } from '@kbn/kibana-utils-plugin/public'; -import { - setDataActions, - setFormatService, - setThemeService, - setUISettings, - setDocLinks, - setPalettesService, - setActiveCursor, -} from './services'; +import type { CoreSetup, Plugin } from '@kbn/core/public'; +import type { VisualizationsSetup } from '@kbn/visualizations-plugin/public'; +import type { ChartsPluginSetup } from '@kbn/charts-plugin/public'; +import { setUISettings, setPalettesService } from './services'; import { visTypesDefinitions } from './vis_types'; -import { getXYVisRenderer } from './vis_renderer'; - -import * as expressionFunctions from './expression_functions'; // eslint-disable-next-line @typescript-eslint/no-empty-interface export interface VisTypeXyPluginSetup {} @@ -39,70 +20,29 @@ export interface VisTypeXyPluginStart {} /** @internal */ export interface VisTypeXyPluginSetupDependencies { - expressions: ReturnType; visualizations: VisualizationsSetup; charts: ChartsPluginSetup; - usageCollection: UsageCollectionSetup; -} - -/** @internal */ -export interface VisTypeXyPluginStartDependencies { - expressions: ReturnType; - visualizations: VisualizationsStart; - data: DataPublicPluginStart; - fieldFormats: FieldFormatsStart; - charts: ChartsPluginStart; - usageCollection?: UsageCollectionStart; } -type VisTypeXyCoreSetup = CoreSetup; +type VisTypeXyCoreSetup = CoreSetup<{}, VisTypeXyPluginStart>; /** @internal */ export class VisTypeXyPlugin implements - Plugin< - VisTypeXyPluginSetup, - VisTypeXyPluginStart, - VisTypeXyPluginSetupDependencies, - VisTypeXyPluginStartDependencies - > + Plugin { public setup( core: VisTypeXyCoreSetup, - { expressions, visualizations, charts, usageCollection }: VisTypeXyPluginSetupDependencies + { visualizations, charts }: VisTypeXyPluginSetupDependencies ) { setUISettings(core.uiSettings); - setThemeService(charts.theme); setPalettesService(charts.palettes); - const getStartDeps = createStartServicesGetter< - VisTypeXyPluginStartDependencies, - VisTypeXyPluginStart - >(core.getStartServices); - - expressions.registerRenderer( - getXYVisRenderer({ - getStartDeps, - }) - ); - expressions.registerFunction(expressionFunctions.visTypeXyVisFn); - expressions.registerFunction(expressionFunctions.categoryAxis); - expressions.registerFunction(expressionFunctions.timeMarker); - expressions.registerFunction(expressionFunctions.valueAxis); - expressions.registerFunction(expressionFunctions.seriesParam); - expressions.registerFunction(expressionFunctions.thresholdLine); - expressions.registerFunction(expressionFunctions.label); - expressions.registerFunction(expressionFunctions.visScale); - visTypesDefinitions.forEach(visualizations.createBaseVisualization); return {}; } - public start(core: CoreStart, { data, charts, fieldFormats }: VisTypeXyPluginStartDependencies) { - setFormatService(fieldFormats); - setDataActions(data.actions); - setDocLinks(core.docLinks); - setActiveCursor(charts.activeCursor); + public start() { return {}; } } diff --git a/src/plugins/vis_types/xy/public/services.ts b/src/plugins/vis_types/xy/public/services.ts index d680a5d7f4498b..2358bcb5ede2ed 100644 --- a/src/plugins/vis_types/xy/public/services.ts +++ b/src/plugins/vis_types/xy/public/services.ts @@ -6,29 +6,13 @@ * Side Public License, v 1. */ -import type { CoreSetup, DocLinksStart } from '@kbn/core/public'; -import type { FieldFormatsStart } from '@kbn/field-formats-plugin/public'; -import type { DataPublicPluginStart } from '@kbn/data-plugin/public'; -import type { ChartsPluginSetup, ChartsPluginStart } from '@kbn/charts-plugin/public'; +import type { CoreSetup } from '@kbn/core/public'; +import type { ChartsPluginSetup } from '@kbn/charts-plugin/public'; import { createGetterSetter } from '@kbn/kibana-utils-plugin/public'; export const [getUISettings, setUISettings] = createGetterSetter('xy core.uiSettings'); -export const [getDataActions, setDataActions] = - createGetterSetter('xy data.actions'); - -export const [getFormatService, setFormatService] = - createGetterSetter('xy fieldFormats'); - -export const [getThemeService, setThemeService] = - createGetterSetter('xy charts.theme'); - -export const [getActiveCursor, setActiveCursor] = - createGetterSetter('xy charts.activeCursor'); - export const [getPalettesService, setPalettesService] = createGetterSetter('xy charts.palette'); - -export const [getDocLinks, setDocLinks] = createGetterSetter('DocLinks'); diff --git a/src/plugins/vis_types/xy/public/types/config.ts b/src/plugins/vis_types/xy/public/types/config.ts deleted file mode 100644 index 287787193bd202..00000000000000 --- a/src/plugins/vis_types/xy/public/types/config.ts +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { - AxisSpec, - CustomTooltip, - Fit, - GridLineStyle, - Position, - Rotation, - SeriesScales, - TickFormatter, - TooltipProps, - TooltipValueFormatter, - YDomainRange, -} from '@elastic/charts'; - -import type { Dimension, Scale, ThresholdLine } from './param'; - -export interface Column { - id: string | null; - name: string; -} - -export interface Aspect { - accessor: Column['id']; - aggType: string | null; - aggId: string | null; - column?: Dimension['accessor']; - title: Column['name']; - format?: Dimension['format']; - formatter?: TickFormatter; - params: Dimension['params']; -} - -export interface Aspects { - x: Aspect; - y: Aspect[]; - z?: Aspect; - series?: Aspect[]; - splitColumn?: Aspect; - splitRow?: Aspect; -} - -export interface AxisGrid { - show?: boolean; - styles?: GridLineStyle; -} - -export interface TickOptions { - show?: boolean; - size?: number; - count?: number; - padding?: number; - formatter?: TickFormatter; - labelFormatter?: TickFormatter; - rotation?: number; - showDuplicates?: boolean; - integersOnly?: boolean; - showOverlappingTicks?: boolean; - showOverlappingLabels?: boolean; -} - -export type YScaleType = SeriesScales['yScaleType']; -export type XScaleType = SeriesScales['xScaleType']; - -export type ScaleConfig = Omit & { - type?: S; -}; - -export interface AxisConfig { - id: string; - groupId?: string; - position: Position; - ticks?: TickOptions; - show: boolean; - style: AxisSpec['style']; - scale: ScaleConfig; - domain?: YDomainRange; - title?: string; - grid?: AxisGrid; - integersOnly: boolean; - timeAxisLayerCount?: number; -} - -export interface LegendOptions { - show: boolean; - position?: Position; -} - -export type ThresholdLineConfig = Omit & { - dash?: number[]; - groupId?: string; -}; - -export type TooltipConfig = Omit & { - detailedTooltip?: (headerFormatter?: TooltipValueFormatter) => CustomTooltip; -}; - -export interface VisConfig { - legend: LegendOptions; - tooltip: TooltipConfig; - xAxis: AxisConfig; - yAxes: Array>; - aspects: Aspects; - rotation: Rotation; - thresholdLine: ThresholdLineConfig; - orderBucketsBySum?: boolean; - showCurrentTime: boolean; - isTimeChart: boolean; - markSizeRatio: number; - showValueLabel: boolean; - enableHistogramMode: boolean; - fittingFunction?: Exclude; - fillOpacity?: number; - detailedTooltip?: boolean; - isVislibVis?: boolean; -} diff --git a/src/plugins/vis_types/xy/public/types/constants.ts b/src/plugins/vis_types/xy/public/types/constants.ts index 05ed0783d4c686..e4c7c30dc2e899 100644 --- a/src/plugins/vis_types/xy/public/types/constants.ts +++ b/src/plugins/vis_types/xy/public/types/constants.ts @@ -40,9 +40,3 @@ export enum ThresholdLineStyle { Dashed = 'dashed', DotDashed = 'dot-dashed', } - -export enum ColorMode { - Background = 'Background', - Labels = 'Labels', - None = 'None', -} diff --git a/src/plugins/vis_types/xy/public/types/index.ts b/src/plugins/vis_types/xy/public/types/index.ts index 6abbdfabaa9563..04426b03c5b874 100644 --- a/src/plugins/vis_types/xy/public/types/index.ts +++ b/src/plugins/vis_types/xy/public/types/index.ts @@ -7,6 +7,4 @@ */ export * from './constants'; -export * from './config'; export * from './param'; -export type { VisTypeNames, XyVisTypeDefinition } from './vis_type'; diff --git a/src/plugins/vis_types/xy/public/types/param.ts b/src/plugins/vis_types/xy/public/types/param.ts index a491efad97fcb8..5e65c85e9f2e9f 100644 --- a/src/plugins/vis_types/xy/public/types/param.ts +++ b/src/plugins/vis_types/xy/public/types/param.ts @@ -11,21 +11,12 @@ import type { PaletteOutput } from '@kbn/coloring'; import type { Style, Labels } from '@kbn/charts-plugin/public'; import type { SchemaConfig, - ExpressionValueXYDimension, FakeParams, HistogramParams, DateHistogramParams, LegendSize, } from '@kbn/visualizations-plugin/public'; -import type { ChartType, XyVisType } from '../../common'; -import type { - ExpressionValueCategoryAxis, - ExpressionValueSeriesParam, - ExpressionValueValueAxis, - ExpressionValueLabel, - ExpressionValueThresholdLine, - ExpressionValueTimeMarker, -} from '../expression_functions'; +import type { ChartType } from '../../common'; import type { ChartMode, @@ -150,45 +141,3 @@ export interface VisParams { fittingFunction?: Exclude; ariaLabel?: string; } - -export interface XYVisConfig { - type: XyVisType; - chartType: ChartType; - gridCategoryLines: boolean; - gridValueAxis?: string; - categoryAxes: ExpressionValueCategoryAxis[]; - valueAxes: ExpressionValueValueAxis[]; - seriesParams: ExpressionValueSeriesParam[]; - palette: string; - addLegend: boolean; - addTooltip: boolean; - legendPosition: Position; - addTimeMarker: boolean; - truncateLegend: boolean; - maxLegendLines: number; - legendSize?: LegendSize; - orderBucketsBySum?: boolean; - labels: ExpressionValueLabel; - thresholdLine: ExpressionValueThresholdLine; - radiusRatio: number; - times: ExpressionValueTimeMarker[]; // For compatibility with vislib - /** - * flag to indicate old vislib visualizations - * used for backwards compatibility including colors - */ - isVislibVis?: boolean; - /** - * Add for detailed tooltip option - */ - detailedTooltip?: boolean; - fittingFunction?: Exclude; - fillOpacity?: number; - xDimension: ExpressionValueXYDimension | null; - yDimension: ExpressionValueXYDimension[]; - zDimension?: ExpressionValueXYDimension[]; - widthDimension?: ExpressionValueXYDimension[]; - seriesDimension?: ExpressionValueXYDimension[]; - splitRowDimension?: ExpressionValueXYDimension[]; - splitColumnDimension?: ExpressionValueXYDimension[]; - ariaLabel?: string; -} diff --git a/src/plugins/vis_types/xy/public/types/vis_type.ts b/src/plugins/vis_types/xy/public/types/vis_type.ts deleted file mode 100644 index 39d762465c34f0..00000000000000 --- a/src/plugins/vis_types/xy/public/types/vis_type.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { VisTypeDefinition } from '@kbn/visualizations-plugin/public'; -import { ChartType } from '../../common'; - -import { VisParams } from './param'; - -export type VisTypeNames = ChartType | 'horizontal_bar'; - -export type XyVisTypeDefinition = VisTypeDefinition; diff --git a/src/plugins/vis_types/xy/public/utils/accessors.test.ts b/src/plugins/vis_types/xy/public/utils/accessors.test.ts deleted file mode 100644 index 882c3d382a237f..00000000000000 --- a/src/plugins/vis_types/xy/public/utils/accessors.test.ts +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { - COMPLEX_SPLIT_ACCESSOR, - getComplexAccessor, - isPercentileIdEqualToSeriesId, -} from './accessors'; -import { BUCKET_TYPES } from '@kbn/data-plugin/common'; -import { AccessorFn, Datum } from '@elastic/charts'; - -describe('XY chart datum accessors', () => { - const aspectBase = { - accessor: 'col-0-2', - formatter: (value: Datum) => value, - aggId: '', - title: '', - params: {}, - }; - - it('should return complex accessor for IP range aggregation', () => { - const aspect = { - aggType: BUCKET_TYPES.IP_RANGE, - ...aspectBase, - }; - const accessor = getComplexAccessor(COMPLEX_SPLIT_ACCESSOR)(aspect); - const datum = { - 'col-0-2': { type: 'range', from: '0.0.0.0', to: '127.255.255.255' }, - }; - - expect(typeof accessor).toBe('function'); - expect((accessor as AccessorFn)(datum)).toStrictEqual({ - type: 'range', - from: '0.0.0.0', - to: '127.255.255.255', - }); - }); - - it('should return complex accessor for date range aggregation', () => { - const aspect = { - aggType: BUCKET_TYPES.DATE_RANGE, - ...aspectBase, - }; - const accessor = getComplexAccessor(COMPLEX_SPLIT_ACCESSOR)(aspect); - const datum = { - 'col-0-2': { from: '1613941200000', to: '1614685113537' }, - }; - - expect(typeof accessor).toBe('function'); - expect((accessor as AccessorFn)(datum)).toStrictEqual({ - from: '1613941200000', - to: '1614685113537', - }); - }); - - it('should return complex accessor when isComplex option set to true', () => { - const aspect = { - aggType: BUCKET_TYPES.TERMS, - ...aspectBase, - }; - const accessor = getComplexAccessor(COMPLEX_SPLIT_ACCESSOR, true)(aspect); - - expect(typeof accessor).toBe('function'); - expect((accessor as AccessorFn)({ 'col-0-2': 'some value' })).toBe('some value'); - }); - - it('should return simple string accessor for not range (date histogram) aggregation', () => { - const aspect = { - aggType: BUCKET_TYPES.DATE_HISTOGRAM, - ...aspectBase, - }; - const accessor = getComplexAccessor(COMPLEX_SPLIT_ACCESSOR)(aspect); - - expect(typeof accessor).toBe('string'); - expect(accessor).toBe('col-0-2'); - }); - - it('should return simple string accessor when aspect has no formatter', () => { - const aspect = { - aggType: BUCKET_TYPES.RANGE, - ...aspectBase, - formatter: undefined, - }; - const accessor = getComplexAccessor(COMPLEX_SPLIT_ACCESSOR)(aspect); - - expect(typeof accessor).toBe('string'); - expect(accessor).toBe('col-0-2'); - }); - - it('should return undefined when aspect has no accessor', () => { - const aspect = { - aggType: BUCKET_TYPES.RANGE, - ...aspectBase, - accessor: null, - }; - const accessor = getComplexAccessor(COMPLEX_SPLIT_ACCESSOR)(aspect); - - expect(accessor).toBeUndefined(); - }); -}); - -describe('isPercentileIdEqualToSeriesId', () => { - it('should be equal for plain column ids', () => { - const seriesColumnId = 'col-0-1'; - const columnId = `${seriesColumnId}`; - - const isEqual = isPercentileIdEqualToSeriesId(columnId, seriesColumnId); - expect(isEqual).toBeTruthy(); - }); - - it('should be equal for column with percentile', () => { - const seriesColumnId = '1'; - const columnId = `${seriesColumnId}.95`; - - const isEqual = isPercentileIdEqualToSeriesId(columnId, seriesColumnId); - expect(isEqual).toBeTruthy(); - }); - - it('should not be equal for column with percentile equal to seriesColumnId', () => { - const seriesColumnId = '1'; - const columnId = `2.1`; - - const isEqual = isPercentileIdEqualToSeriesId(columnId, seriesColumnId); - expect(isEqual).toBeFalsy(); - }); - - it('should be equal for column with percentile with decimal points', () => { - const seriesColumnId = '1'; - const columnId = `${seriesColumnId}['95.5']`; - - const isEqual = isPercentileIdEqualToSeriesId(columnId, seriesColumnId); - expect(isEqual).toBeTruthy(); - }); - - it('should not be equal for column with percentile with decimal points equal to seriesColumnId', () => { - const seriesColumnId = '1'; - const columnId = `2['1.3']`; - - const isEqual = isPercentileIdEqualToSeriesId(columnId, seriesColumnId); - expect(isEqual).toBeFalsy(); - }); - - it('should not be equal for column with percentile, where columnId contains seriesColumnId', () => { - const seriesColumnId = '1'; - const columnId = `${seriesColumnId}2.1`; - - const isEqual = isPercentileIdEqualToSeriesId(columnId, seriesColumnId); - expect(isEqual).toBeFalsy(); - }); -}); diff --git a/src/plugins/vis_types/xy/public/utils/accessors.tsx b/src/plugins/vis_types/xy/public/utils/accessors.tsx index 9739a9d3328ea9..40f87f8e780611 100644 --- a/src/plugins/vis_types/xy/public/utils/accessors.tsx +++ b/src/plugins/vis_types/xy/public/utils/accessors.tsx @@ -6,78 +6,6 @@ * Side Public License, v 1. */ -import { AccessorFn, Accessor } from '@elastic/charts'; -import { BUCKET_TYPES } from '@kbn/data-plugin/public'; -import { FakeParams } from '@kbn/visualizations-plugin/public'; -import type { Aspect } from '../types'; - -export const COMPLEX_X_ACCESSOR = '__customXAccessor__'; -export const COMPLEX_SPLIT_ACCESSOR = '__complexSplitAccessor__'; -const SHARD_DELAY = 'shard_delay'; - -export const getXAccessor = (aspect: Aspect): Accessor | AccessorFn => { - return ( - getComplexAccessor(COMPLEX_X_ACCESSOR)(aspect) ?? - (() => (aspect.params as FakeParams)?.defaultValue) - ); -}; - -const getFieldName = (fieldName: string, index?: number) => { - const indexStr = index !== undefined ? `::${index}` : ''; - - return `${fieldName}${indexStr}`; -}; - -export const isRangeAggType = (type: string | null) => - type === BUCKET_TYPES.DATE_RANGE || type === BUCKET_TYPES.RANGE || type === BUCKET_TYPES.IP_RANGE; - -/** - * Returns accessor function for complex accessor types - * @param aspect - * @param isComplex - forces to be functional/complex accessor - */ -export const getComplexAccessor = - (fieldName: string, isComplex: boolean = false) => - (aspect: Aspect, index?: number): Accessor | AccessorFn | undefined => { - if (!aspect.accessor || aspect.aggType === SHARD_DELAY) { - return; - } - - if (!((isComplex || isRangeAggType(aspect.aggType)) && aspect.formatter)) { - return aspect.accessor; - } - - const formatter = aspect.formatter; - const accessor = aspect.accessor; - const fn: AccessorFn = (d) => { - const v = d[accessor]; - if (v === undefined) { - return; - } - const f = formatter(v); - return f; - }; - - fn.fieldName = getFieldName(fieldName, index); - - return fn; - }; - -export const getSplitSeriesAccessorFnMap = ( - splitSeriesAccessors: Array -): Map => { - const m = new Map(); - - splitSeriesAccessors.forEach((accessor, index) => { - if (typeof accessor === 'function') { - const fieldName = getFieldName(COMPLEX_SPLIT_ACCESSOR, index); - m.set(fieldName, accessor); - } - }); - - return m; -}; - // For percentile, the aggregation id is coming in the form %s.%d, where %s is agg_id and %d - percents export const getSafeId = (columnId?: number | string | null) => { const id = String(columnId); @@ -89,12 +17,3 @@ export const getSafeId = (columnId?: number | string | null) => { const baseId = id.substring(0, id.indexOf('[') !== -1 ? id.indexOf('[') : id.indexOf('.')); return baseId; }; - -export const isPercentileIdEqualToSeriesId = ( - columnId: number | string | null | undefined, - seriesColumnId: string -) => getSafeId(columnId) === seriesColumnId; - -export const isValidSeriesForDimension = (seriesColumnId: string, { aggId, accessor }: Aspect) => - (aggId === seriesColumnId || isPercentileIdEqualToSeriesId(aggId ?? '', seriesColumnId)) && - accessor !== null; diff --git a/src/plugins/vis_types/xy/public/utils/compute_percentage_data.test.ts b/src/plugins/vis_types/xy/public/utils/compute_percentage_data.test.ts deleted file mode 100644 index 0429bb5253b6f3..00000000000000 --- a/src/plugins/vis_types/xy/public/utils/compute_percentage_data.test.ts +++ /dev/null @@ -1,216 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { computePercentageData } from './compute_percentage_data'; - -const rowsOneMetric = [ - { - 'col-0-4': 'Kibana Airlines', - 'col-1-1': 85, - }, - { - 'col-0-4': 'ES-Air', - 'col-1-1': 84, - }, - { - 'col-0-4': 'Logstash Airways', - 'col-1-1': 82, - }, - { - 'col-0-4': 'JetBeats', - 'col-1-1': 81, - }, -]; - -const twoMetricsRows = [ - { - 'col-0-4': 'ES-Air', - 'col-1-5': 10, - 'col-2-1': 71, - 'col-3-1': 1, - }, - { - 'col-0-4': 'ES-Air', - 'col-1-5': 9, - 'col-2-1': 14, - 'col-3-1': 1, - }, - { - 'col-0-4': 'Kibana Airlines', - 'col-1-5': 5, - 'col-2-1': 71, - 'col-3-1': 0, - }, - { - 'col-0-4': 'Kibana Airlines', - 'col-1-5': 8, - 'col-2-1': 13, - 'col-3-1': 1, - }, - { - 'col-0-4': 'JetBeats', - 'col-1-5': 11, - 'col-2-1': 72, - 'col-3-1': 0, - }, - { - 'col-0-4': 'JetBeats', - 'col-1-5': 12, - 'col-2-1': 9, - 'col-3-1': 0, - }, - { - 'col-0-4': 'Logstash Airways', - 'col-1-5': 5, - 'col-2-1': 71, - 'col-3-1': 1, - }, - { - 'col-0-4': 'Logstash Airways', - 'col-1-5': 7, - 'col-2-1': 10, - 'col-3-1': 0, - }, -]; - -describe('computePercentageData', () => { - it('returns ratio 1 if there is only one metric in the axis', () => { - const data = computePercentageData(rowsOneMetric, 'col-0-4', ['col-1-1']); - expect(data).toStrictEqual([ - { - 'col-0-4': 'Kibana Airlines', - 'col-1-1': 1, - }, - { - 'col-0-4': 'ES-Air', - 'col-1-1': 1, - }, - { - 'col-0-4': 'Logstash Airways', - 'col-1-1': 1, - }, - { - 'col-0-4': 'JetBeats', - 'col-1-1': 1, - }, - ]); - }); - - it('returns correct ratio if there are two metrics in the same axis with no small multiples', () => { - const data = computePercentageData(twoMetricsRows, 'col-0-4', ['col-1-5', 'col-2-1']); - expect(data).toStrictEqual([ - { - 'col-0-4': 'ES-Air', - 'col-1-5': 0.09615384615384616, - 'col-2-1': 0.6826923076923077, - 'col-3-1': 1, - }, - { - 'col-0-4': 'ES-Air', - 'col-1-5': 0.08653846153846154, - 'col-2-1': 0.1346153846153846, - 'col-3-1': 1, - }, - { - 'col-0-4': 'Kibana Airlines', - 'col-1-5': 0.05154639175257732, - 'col-2-1': 0.7319587628865979, - 'col-3-1': 0, - }, - { - 'col-0-4': 'Kibana Airlines', - 'col-1-5': 0.08247422680412371, - 'col-2-1': 0.13402061855670103, - 'col-3-1': 1, - }, - { - 'col-0-4': 'JetBeats', - 'col-1-5': 0.10576923076923077, - 'col-2-1': 0.6923076923076923, - 'col-3-1': 0, - }, - { - 'col-0-4': 'JetBeats', - 'col-1-5': 0.11538461538461539, - 'col-2-1': 0.08653846153846154, - 'col-3-1': 0, - }, - { - 'col-0-4': 'Logstash Airways', - 'col-1-5': 0.053763440860215055, - 'col-2-1': 0.7634408602150538, - 'col-3-1': 1, - }, - { - 'col-0-4': 'Logstash Airways', - 'col-1-5': 0.07526881720430108, - 'col-2-1': 0.10752688172043011, - 'col-3-1': 0, - }, - ]); - }); - - it('returns correct ratio if there are two metrics in the same axis with small multiples', () => { - const data = computePercentageData( - twoMetricsRows, - 'col-0-4', - ['col-1-5', 'col-2-1'], - 'col-3-1' - ); - expect(data).toStrictEqual([ - { - 'col-0-4': 'ES-Air', - 'col-1-5': 0.09615384615384616, - 'col-2-1': 0.6826923076923077, - 'col-3-1': 1, - }, - { - 'col-0-4': 'ES-Air', - 'col-1-5': 0.08653846153846154, - 'col-2-1': 0.1346153846153846, - 'col-3-1': 1, - }, - { - 'col-0-4': 'Kibana Airlines', - 'col-1-5': 0.06578947368421052, - 'col-2-1': 0.9342105263157895, - 'col-3-1': 0, - }, - { - 'col-0-4': 'Kibana Airlines', - 'col-1-5': 0.38095238095238093, - 'col-2-1': 0.6190476190476191, - 'col-3-1': 1, - }, - { - 'col-0-4': 'JetBeats', - 'col-1-5': 0.10576923076923077, - 'col-2-1': 0.6923076923076923, - 'col-3-1': 0, - }, - { - 'col-0-4': 'JetBeats', - 'col-1-5': 0.11538461538461539, - 'col-2-1': 0.08653846153846154, - 'col-3-1': 0, - }, - { - 'col-0-4': 'Logstash Airways', - 'col-1-5': 0.06578947368421052, - 'col-2-1': 0.9342105263157895, - 'col-3-1': 1, - }, - { - 'col-0-4': 'Logstash Airways', - 'col-1-5': 0.4117647058823529, - 'col-2-1': 0.5882352941176471, - 'col-3-1': 0, - }, - ]); - }); -}); diff --git a/src/plugins/vis_types/xy/public/utils/compute_percentage_data.ts b/src/plugins/vis_types/xy/public/utils/compute_percentage_data.ts deleted file mode 100644 index 65b43495d8c6d6..00000000000000 --- a/src/plugins/vis_types/xy/public/utils/compute_percentage_data.ts +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ -import type { Accessor, AccessorFn } from '@elastic/charts'; -import { computeRatioByGroups } from '@elastic/charts'; -import type { DatatableRow } from '@kbn/expressions-plugin/public'; - -export const computePercentageData = ( - rows: DatatableRow[], - xAccessor: Accessor | AccessorFn, - yAccessors: string[], - splitChartAccessor?: string | null -) => { - // compute percentage mode data - const groupAccessors = [String(xAccessor)]; - if (splitChartAccessor) { - groupAccessors.push(splitChartAccessor); - } - - return computeRatioByGroups( - rows, - groupAccessors, - yAccessors.map((accessor) => { - return [(d) => d[accessor], (d, v) => ({ ...d, [accessor]: v })]; - }) - ); -}; diff --git a/src/plugins/vis_types/xy/public/utils/domain.ts b/src/plugins/vis_types/xy/public/utils/domain.ts deleted file mode 100644 index 1f07509f55aa19..00000000000000 --- a/src/plugins/vis_types/xy/public/utils/domain.ts +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { uniq } from 'lodash'; -import { unitOfTime } from 'moment'; - -import { DomainRange } from '@elastic/charts'; - -import { getAdjustedInterval } from '@kbn/charts-plugin/public'; -import { Datatable } from '@kbn/expressions-plugin/public'; -import { DateHistogramParams, HistogramParams } from '@kbn/visualizations-plugin/public'; - -import { Aspect } from '../types'; - -export const getXDomain = (params: Aspect['params']): DomainRange => { - const minInterval = (params as DateHistogramParams | HistogramParams)?.interval ?? undefined; - const bounds = (params as DateHistogramParams).date - ? (params as DateHistogramParams).bounds - : null; - - if (bounds) { - return { - min: bounds.min as number, - max: bounds.max as number, - minInterval, - }; - } - - return { - minInterval, - min: NaN, - max: NaN, - }; -}; - -export const getAdjustedDomain = ( - data: Datatable['rows'], - { accessor, params }: Aspect, - timeZone: string, - domain: DomainRange | undefined, - hasBars?: boolean -): DomainRange => { - if ( - accessor && - domain && - 'min' in domain && - 'max' in domain && - 'intervalESValue' in params && - 'intervalESUnit' in params - ) { - const { interval, intervalESValue, intervalESUnit } = params; - const xValues = uniq(data.map((d) => d[accessor]).sort()); - - const [firstXValue] = xValues; - const lastXValue = xValues[xValues.length - 1]; - - const domainMin = Math.min(firstXValue, domain.min); - const domainMaxValue = Math.max(domain.max - interval, lastXValue); - const domainMax = hasBars ? domainMaxValue : domainMaxValue + interval; - const minInterval = getAdjustedInterval( - xValues, - intervalESValue, - intervalESUnit as unitOfTime.Base, - timeZone - ); - - return { - min: domainMin, - max: domainMax, - minInterval, - }; - } - - return { - minInterval: 'interval' in params ? params.interval : undefined, - min: NaN, - max: NaN, - }; -}; diff --git a/src/plugins/vis_types/xy/public/utils/get_all_series.test.ts b/src/plugins/vis_types/xy/public/utils/get_all_series.test.ts deleted file mode 100644 index 6c6b78dfd73f7b..00000000000000 --- a/src/plugins/vis_types/xy/public/utils/get_all_series.test.ts +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { getAllSeries } from './get_all_series'; - -const rowsNoSplitSeries = [ - { - 'col-0-4': 'Kibana Airlines', - 'col-1-1': 85, - }, - { - 'col-0-4': 'ES-Air', - 'col-1-1': 84, - }, - { - 'col-0-4': 'Logstash Airways', - 'col-1-1': 82, - }, - { - 'col-0-4': 'JetBeats', - 'col-1-1': 81, - }, -]; - -const rowsWithSplitSeries = [ - { - 'col-0-4': 'ES-Air', - 'col-1-5': 0, - 'col-2-1': 71, - }, - { - 'col-0-4': 'ES-Air', - 'col-1-5': 1, - 'col-2-1': 14, - }, - { - 'col-0-4': 'Kibana Airlines', - 'col-1-5': 0, - 'col-2-1': 71, - }, - { - 'col-0-4': 'Kibana Airlines', - 'col-1-5': 1, - 'col-2-1': 13, - }, - { - 'col-0-4': 'JetBeats', - 'col-1-5': 0, - 'col-2-1': 72, - }, - { - 'col-0-4': 'JetBeats', - 'col-1-5': 1, - 'col-2-1': 9, - }, - { - 'col-0-4': 'Logstash Airways', - 'col-1-5': 0, - 'col-2-1': 71, - }, - { - 'col-0-4': 'Logstash Airways', - 'col-1-5': 1, - 'col-2-1': 10, - }, -]; - -const yAspects = [ - { - accessor: 'col-2-1', - column: 2, - title: 'Count', - format: { - id: 'number', - }, - aggType: 'count', - aggId: '1', - params: {}, - }, -]; - -const myltipleYAspects = [ - { - accessor: 'col-2-1', - column: 2, - title: 'Count', - format: { - id: 'number', - }, - aggType: 'count', - aggId: '1', - params: {}, - }, - { - accessor: 'col-3-4', - column: 3, - title: 'Average AvgTicketPrice', - format: { - id: 'number', - params: { - pattern: '$0,0.[00]', - }, - }, - aggType: 'avg', - aggId: '4', - params: {}, - }, -]; - -describe('getAllSeries', () => { - it('returns empty array if splitAccessors is undefined', () => { - const splitAccessors = undefined; - const series = getAllSeries(rowsNoSplitSeries, splitAccessors, yAspects); - expect(series).toStrictEqual([]); - }); - - it('returns an array of series names if splitAccessors is an array', () => { - const splitAccessors = [ - { - accessor: 'col-1-5', - }, - ]; - const series = getAllSeries(rowsWithSplitSeries, splitAccessors, yAspects); - expect(series).toStrictEqual([0, 1]); - }); - - it('returns the correct array of series names for two splitAccessors without duplicates', () => { - const splitAccessors = [ - { - accessor: 'col-0-4', - }, - { - accessor: 'col-1-5', - }, - ]; - const series = getAllSeries(rowsWithSplitSeries, splitAccessors, yAspects); - expect(series).toStrictEqual([ - 'ES-Air - 0', - 'ES-Air - 1', - 'Kibana Airlines - 0', - 'Kibana Airlines - 1', - 'JetBeats - 0', - 'JetBeats - 1', - 'Logstash Airways - 0', - 'Logstash Airways - 1', - ]); - }); - - it('returns the correct array of series names for two splitAccessors and two y axis', () => { - const splitAccessors = [ - { - accessor: 'col-0-4', - }, - { - accessor: 'col-1-5', - }, - ]; - const series = getAllSeries(rowsWithSplitSeries, splitAccessors, myltipleYAspects); - expect(series).toStrictEqual([ - 'ES-Air - 0: Count', - 'ES-Air - 0: Average AvgTicketPrice', - 'ES-Air - 1: Count', - 'ES-Air - 1: Average AvgTicketPrice', - 'Kibana Airlines - 0: Count', - 'Kibana Airlines - 0: Average AvgTicketPrice', - 'Kibana Airlines - 1: Count', - 'Kibana Airlines - 1: Average AvgTicketPrice', - 'JetBeats - 0: Count', - 'JetBeats - 0: Average AvgTicketPrice', - 'JetBeats - 1: Count', - 'JetBeats - 1: Average AvgTicketPrice', - 'Logstash Airways - 0: Count', - 'Logstash Airways - 0: Average AvgTicketPrice', - 'Logstash Airways - 1: Count', - 'Logstash Airways - 1: Average AvgTicketPrice', - ]); - }); -}); diff --git a/src/plugins/vis_types/xy/public/utils/get_all_series.ts b/src/plugins/vis_types/xy/public/utils/get_all_series.ts deleted file mode 100644 index 6ec625cb884c1a..00000000000000 --- a/src/plugins/vis_types/xy/public/utils/get_all_series.ts +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { TickFormatter } from '@elastic/charts'; -import { DatatableRow } from '@kbn/expressions-plugin/public'; -import { Column, Aspect } from '../types'; - -interface SplitAccessors { - accessor: Column['id']; - formatter?: TickFormatter; -} - -export const getAllSeries = ( - rows: DatatableRow[], - splitAccessors: SplitAccessors[] | undefined, - yAspects: Aspect[] -) => { - const allSeries: string[] = []; - if (!splitAccessors) return []; - - rows.forEach((row) => { - let seriesName = ''; - splitAccessors?.forEach(({ accessor, formatter }) => { - if (!accessor) return; - const name = formatter ? formatter(row[accessor]) : row[accessor]; - if (seriesName) { - seriesName += ` - ${name}`; - } else { - seriesName = name; - } - }); - - // multiple y axis - if (yAspects.length > 1) { - yAspects.forEach((aspect) => { - if (!allSeries.includes(`${seriesName}: ${aspect.title}`)) { - allSeries.push(`${seriesName}: ${aspect.title}`); - } - }); - } else { - if (!allSeries.includes(seriesName)) { - allSeries.push(seriesName); - } - } - }); - return allSeries; -}; diff --git a/src/plugins/vis_types/xy/public/utils/get_color_picker.test.tsx b/src/plugins/vis_types/xy/public/utils/get_color_picker.test.tsx deleted file mode 100644 index 6c541fc27161e6..00000000000000 --- a/src/plugins/vis_types/xy/public/utils/get_color_picker.test.tsx +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import React from 'react'; -import { LegendColorPickerProps, XYChartSeriesIdentifier } from '@elastic/charts'; -import { EuiPopover } from '@elastic/eui'; -import { mountWithIntl } from '@kbn/test-jest-helpers'; -import { ComponentType, ReactWrapper } from 'enzyme'; -import { getColorPicker } from './get_color_picker'; -import { ColorPicker } from '@kbn/charts-plugin/public'; -import type { PersistedState } from '@kbn/visualizations-plugin/public'; - -jest.mock('@elastic/charts', () => { - const original = jest.requireActual('@elastic/charts'); - - return { - ...original, - getSpecId: jest.fn(() => {}), - }; -}); - -describe('getColorPicker', function () { - const mockState = new Map(); - const uiState = { - get: jest - .fn() - .mockImplementation((key, fallback) => (mockState.has(key) ? mockState.get(key) : fallback)), - set: jest.fn().mockImplementation((key, value) => mockState.set(key, value)), - emit: jest.fn(), - setSilent: jest.fn(), - } as unknown as PersistedState; - - let wrapperProps: LegendColorPickerProps; - const Component: ComponentType = getColorPicker( - 'left', - jest.fn(), - jest.fn().mockImplementation((seriesIdentifier) => seriesIdentifier.seriesKeys[0]), - 'default', - uiState - ); - let wrapper: ReactWrapper; - - beforeAll(() => { - wrapperProps = { - color: 'rgb(109, 204, 177)', - onClose: jest.fn(), - onChange: jest.fn(), - anchor: document.createElement('div'), - seriesIdentifiers: [ - { - yAccessor: 'col-2-1', - splitAccessors: {}, - seriesKeys: ['Logstash Airways', 'col-2-1'], - specId: 'histogram-col-2-1', - key: 'groupId{__pseudo_stacked_group-ValueAxis-1__}spec{histogram-col-2-1}yAccessor{col-2-1}splitAccessors{col-1-3-Logstash Airways}', - } as XYChartSeriesIdentifier, - ], - }; - }); - - it('renders the color picker', () => { - wrapper = mountWithIntl(); - expect(wrapper.find(ColorPicker).length).toBe(1); - }); - - it('renders the color picker with the colorIsOverwritten prop set to false if color is not overwritten for the specific series', () => { - wrapper = mountWithIntl(); - expect(wrapper.find(ColorPicker).prop('colorIsOverwritten')).toBe(false); - }); - - it('renders the color picker with the colorIsOverwritten prop set to true if color is overwritten for the specific series', () => { - uiState.set('vis.colors', { 'Logstash Airways': '#6092c0' }); - wrapper = mountWithIntl(); - expect(wrapper.find(ColorPicker).prop('colorIsOverwritten')).toBe(true); - }); - - it('renders the picker on the correct position', () => { - wrapper = mountWithIntl(); - expect(wrapper.find(EuiPopover).prop('anchorPosition')).toEqual('rightCenter'); - }); - - it('renders the picker for kibana palette with useLegacyColors set to true', () => { - const LegacyPaletteComponent: ComponentType = getColorPicker( - 'left', - jest.fn(), - jest.fn(), - 'kibana_palette', - uiState - ); - wrapper = mountWithIntl(); - expect(wrapper.find(ColorPicker).prop('useLegacyColors')).toBe(true); - }); -}); diff --git a/src/plugins/vis_types/xy/public/utils/get_color_picker.tsx b/src/plugins/vis_types/xy/public/utils/get_color_picker.tsx deleted file mode 100644 index 18ba4296e2545b..00000000000000 --- a/src/plugins/vis_types/xy/public/utils/get_color_picker.tsx +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import React, { useCallback } from 'react'; - -import { LegendColorPicker, Position, XYChartSeriesIdentifier, SeriesName } from '@elastic/charts'; -import { PopoverAnchorPosition, EuiWrappingPopover, EuiOutsideClickDetector } from '@elastic/eui'; -import type { PersistedState } from '@kbn/visualizations-plugin/public'; -import { ColorPicker } from '@kbn/charts-plugin/public'; - -function getAnchorPosition(legendPosition: Position): PopoverAnchorPosition { - switch (legendPosition) { - case Position.Bottom: - return 'upCenter'; - case Position.Top: - return 'downCenter'; - case Position.Left: - return 'rightCenter'; - default: - return 'leftCenter'; - } -} - -const KEY_CODE_ENTER = 13; - -export const getColorPicker = - ( - legendPosition: Position, - setColor: (newColor: string | null, seriesKey: string | number) => void, - getSeriesName: (series: XYChartSeriesIdentifier) => SeriesName, - paletteName: string, - uiState: PersistedState - ): LegendColorPicker => - ({ anchor, color, onClose, onChange, seriesIdentifiers: [seriesIdentifier] }) => { - const seriesName = getSeriesName(seriesIdentifier as XYChartSeriesIdentifier); - const overwriteColors: Record = uiState?.get('vis.colors', {}); - const colorIsOverwritten = Object.keys(overwriteColors).includes(seriesName as string); - let keyDownEventOn = false; - - const handleChange = (newColor: string | null) => { - if (!seriesName) { - return; - } - if (newColor) { - onChange(newColor); - } - setColor(newColor, seriesName); - // close the popover if no color is applied or the user has clicked a color - if (!newColor || !keyDownEventOn) { - onClose(); - } - }; - - const onKeyDown = (e: React.KeyboardEvent) => { - if (e.keyCode === KEY_CODE_ENTER) { - onClose?.(); - } - keyDownEventOn = true; - }; - - const handleOutsideClick = useCallback(() => { - onClose?.(); - }, [onClose]); - - return ( - - - - - - ); - }; diff --git a/src/plugins/vis_types/xy/public/utils/get_legend_actions.tsx b/src/plugins/vis_types/xy/public/utils/get_legend_actions.tsx deleted file mode 100644 index 3d79b607c4da16..00000000000000 --- a/src/plugins/vis_types/xy/public/utils/get_legend_actions.tsx +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import React, { useState, useEffect, useMemo } from 'react'; - -import { i18n } from '@kbn/i18n'; -import { EuiContextMenuPanelDescriptor, EuiIcon, EuiPopover, EuiContextMenu } from '@elastic/eui'; -import { - LegendAction, - XYChartSeriesIdentifier, - SeriesName, - useLegendAction, -} from '@elastic/charts'; - -import { ClickTriggerEvent } from '@kbn/charts-plugin/public'; - -export const getLegendActions = ( - canFilter: (data: ClickTriggerEvent | null) => Promise, - getFilterEventData: (series: XYChartSeriesIdentifier) => ClickTriggerEvent | null, - onFilter: (data: ClickTriggerEvent, negate?: any) => void, - getSeriesName: (series: XYChartSeriesIdentifier) => SeriesName -): LegendAction => { - return ({ series: [xySeries] }) => { - const [popoverOpen, setPopoverOpen] = useState(false); - const [isfilterable, setIsfilterable] = useState(false); - const series = xySeries as XYChartSeriesIdentifier; - const filterData = useMemo(() => getFilterEventData(series), [series]); - const [ref, onClose] = useLegendAction(); - - useEffect(() => { - (async () => setIsfilterable(await canFilter(filterData)))(); - }, [filterData]); - - if (!isfilterable || !filterData) { - return null; - } - - const name = getSeriesName(series); - const panels: EuiContextMenuPanelDescriptor[] = [ - { - id: 'main', - title: `${name}`, - items: [ - { - name: i18n.translate('visTypeXy.legend.filterForValueButtonAriaLabel', { - defaultMessage: 'Filter for value', - }), - 'data-test-subj': `legend-${name}-filterIn`, - icon: , - onClick: () => { - setPopoverOpen(false); - onFilter(filterData); - }, - }, - { - name: i18n.translate('visTypeXy.legend.filterOutValueButtonAriaLabel', { - defaultMessage: 'Filter out value', - }), - 'data-test-subj': `legend-${name}-filterOut`, - icon: , - onClick: () => { - setPopoverOpen(false); - onFilter(filterData, true); - }, - }, - ], - }, - ]; - - const Button = ( -
setPopoverOpen(!popoverOpen)} - onClick={() => setPopoverOpen(!popoverOpen)} - > - -
- ); - - return ( - { - setPopoverOpen(false); - onClose(); - }} - panelPaddingSize="none" - anchorPosition="upLeft" - title={i18n.translate('visTypeXy.legend.filterOptionsLegend', { - defaultMessage: '{legendDataLabel}, filter options', - values: { legendDataLabel: name }, - })} - > - - - ); - }; -}; diff --git a/src/plugins/vis_types/xy/public/utils/get_series_name_fn.test.ts b/src/plugins/vis_types/xy/public/utils/get_series_name_fn.test.ts deleted file mode 100644 index 88be9ab1608963..00000000000000 --- a/src/plugins/vis_types/xy/public/utils/get_series_name_fn.test.ts +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { XYChartSeriesIdentifier } from '@elastic/charts'; -import { getSeriesNameFn } from './get_series_name_fn'; - -const aspects = { - series: [ - { - accessor: 'col-1-3', - column: 1, - title: 'FlightDelayType: Descending', - format: { - id: 'terms', - params: { - id: 'string', - otherBucketLabel: 'Other', - missingBucketLabel: 'Missing', - }, - }, - aggType: 'terms', - aggId: '3', - params: {}, - }, - ], - x: { - accessor: 'col-0-2', - column: 0, - title: 'timestamp per day', - format: { - id: 'date', - params: { - pattern: 'YYYY-MM-DD', - }, - }, - aggType: 'date_histogram', - aggId: '2', - params: { - date: true, - intervalESUnit: 'd', - intervalESValue: 1, - interval: 86400000, - format: 'YYYY-MM-DD', - }, - }, - y: [ - { - accessor: 'col-1-1', - column: 1, - title: 'Count', - format: { - id: 'number', - }, - aggType: 'count', - aggId: '1', - params: {}, - }, - ], -}; - -const series = { - specId: 'histogram-col-1-1', - seriesKeys: ['col-1-1'], - yAccessor: 'col-1-1', - splitAccessors: [], - smVerticalAccessorValue: '__ECH_DEFAULT_SINGLE_PANEL_SM_VALUE__', - smHorizontalAccessorValue: '__ECH_DEFAULT_SINGLE_PANEL_SM_VALUE__', - groupId: '__pseudo_stacked_group-ValueAxis-1__', - seriesType: 'bar', - isStacked: true, -} as unknown as XYChartSeriesIdentifier; - -const splitAccessors = new Map(); -splitAccessors.set('col-1-3', 'Weather Delay'); - -const seriesSplitAccessors = { - specId: 'histogram-col-2-1', - seriesKeys: ['Weather Delay', 'col-2-1'], - yAccessor: 'col-2-1', - splitAccessors, - smVerticalAccessorValue: '__ECH_DEFAULT_SINGLE_PANEL_SM_VALUE__', - smHorizontalAccessorValue: '__ECH_DEFAULT_SINGLE_PANEL_SM_VALUE__', - groupId: '__pseudo_stacked_group-ValueAxis-1__', - seriesType: 'bar', - isStacked: true, -} as unknown as XYChartSeriesIdentifier; - -describe('getSeriesNameFn', () => { - it('returns the y aspects title if splitAccessors are empty array', () => { - const getSeriesName = getSeriesNameFn(aspects, false); - expect(getSeriesName(series)).toStrictEqual('Count'); - }); - - it('returns the y aspects title if splitAccessors are empty array but mupliple flag is set to true', () => { - const getSeriesName = getSeriesNameFn(aspects, true); - expect(getSeriesName(series)).toStrictEqual('Count'); - }); - - it('returns the correct string for multiple set to false and given split accessors', () => { - const aspectsSplitSeries = { - ...aspects, - y: [ - { - accessor: 'col-2-1', - column: 2, - title: 'Count', - format: { - id: 'number', - }, - aggType: 'count', - aggId: '1', - params: {}, - }, - ], - }; - const getSeriesName = getSeriesNameFn(aspectsSplitSeries, false); - expect(getSeriesName(seriesSplitAccessors)).toStrictEqual('Weather Delay'); - }); - - it('returns the correct string for multiple set to true and given split accessors', () => { - const aspectsSplitSeries = { - ...aspects, - y: [ - { - accessor: 'col-2-1', - column: 2, - title: 'Count', - format: { - id: 'number', - }, - aggType: 'count', - aggId: '1', - params: {}, - }, - ], - }; - const getSeriesName = getSeriesNameFn(aspectsSplitSeries, true); - expect(getSeriesName(seriesSplitAccessors)).toStrictEqual('Weather Delay: Count'); - }); -}); diff --git a/src/plugins/vis_types/xy/public/utils/get_series_name_fn.ts b/src/plugins/vis_types/xy/public/utils/get_series_name_fn.ts deleted file mode 100644 index 8019e36c1e6d54..00000000000000 --- a/src/plugins/vis_types/xy/public/utils/get_series_name_fn.ts +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { memoize } from 'lodash'; - -import { XYChartSeriesIdentifier, SeriesName } from '@elastic/charts'; - -import { VisConfig } from '../types'; - -function getSplitValues( - splitAccessors: XYChartSeriesIdentifier['splitAccessors'], - seriesAspects?: VisConfig['aspects']['series'] -) { - if (splitAccessors.size < 1) { - return []; - } - - const splitValues: Array = []; - splitAccessors.forEach((value, key) => { - const split = (seriesAspects ?? []).find(({ accessor }) => accessor === key); - splitValues.push(split?.formatter ? split?.formatter(value) : value); - }); - return splitValues; -} - -export const getSeriesNameFn = (aspects: VisConfig['aspects'], multipleY = false) => - memoize(({ splitAccessors, yAccessor }: XYChartSeriesIdentifier): SeriesName => { - const splitValues = getSplitValues(splitAccessors, aspects.series); - const yAccessorTitle = aspects.y.find(({ accessor }) => accessor === yAccessor)?.title ?? null; - - if (!yAccessorTitle) { - return null; - } - - if (multipleY) { - if (splitValues.length === 0) { - return yAccessorTitle; - } - return `${splitValues.join(' - ')}: ${yAccessorTitle}`; - } - - return splitValues.length > 0 ? splitValues.join(' - ') : yAccessorTitle; - }); diff --git a/src/plugins/vis_types/xy/public/utils/get_series_params.test.ts b/src/plugins/vis_types/xy/public/utils/get_series_params.test.ts deleted file mode 100644 index 21b2dac5da3226..00000000000000 --- a/src/plugins/vis_types/xy/public/utils/get_series_params.test.ts +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ -import type { AggConfigs } from '@kbn/data-plugin/public'; -import type { SeriesParam } from '../types'; -import { getSeriesParams } from './get_series_params'; -import { sampleAreaVis } from '../sample_vis.test.mocks'; - -describe('getSeriesParams', () => { - it('returns correct params', () => { - const seriesParams = getSeriesParams( - sampleAreaVis.data.aggs as unknown as AggConfigs, - sampleAreaVis.params.seriesParams as unknown as SeriesParam[], - 'metric', - 'ValueAxis-1' - ); - expect(seriesParams).toStrictEqual([ - { - circlesRadius: 5, - data: { - id: '1', - label: 'Total quantity', - }, - drawLinesBetweenPoints: true, - interpolate: 'linear', - mode: 'stacked', - show: 'true', - showCircles: true, - type: 'area', - valueAxis: 'ValueAxis-1', - }, - ]); - }); - - it('returns default params if no params provided', () => { - const seriesParams = getSeriesParams( - sampleAreaVis.data.aggs as unknown as AggConfigs, - [], - 'metric', - 'ValueAxis-1' - ); - expect(seriesParams).toStrictEqual([ - { - circlesRadius: 1, - data: { - id: '1', - label: 'Total quantity', - }, - drawLinesBetweenPoints: true, - interpolate: 'linear', - lineWidth: 2, - mode: 'normal', - show: true, - showCircles: true, - type: 'line', - valueAxis: 'ValueAxis-1', - }, - ]); - }); -}); diff --git a/src/plugins/vis_types/xy/public/utils/get_time_zone.tsx b/src/plugins/vis_types/xy/public/utils/get_time_zone.tsx deleted file mode 100644 index 2d63eebbdc3e20..00000000000000 --- a/src/plugins/vis_types/xy/public/utils/get_time_zone.tsx +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import moment from 'moment'; - -import { getUISettings } from '../services'; - -/** - * Get timeZone from uiSettings - */ -export function getTimeZone() { - const uiSettings = getUISettings(); - if (uiSettings.isDefault('dateFormat:tz')) { - const detectedTimeZone = moment.tz.guess(); - if (detectedTimeZone) return detectedTimeZone; - else return moment().format('Z'); - } else { - return uiSettings.get('dateFormat:tz', 'Browser'); - } -} diff --git a/src/plugins/vis_types/xy/public/utils/index.tsx b/src/plugins/vis_types/xy/public/utils/index.tsx deleted file mode 100644 index d68a6e8068fa80..00000000000000 --- a/src/plugins/vis_types/xy/public/utils/index.tsx +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -export { renderAllSeries } from './render_all_series'; -export { getTimeZone } from './get_time_zone'; -export { getLegendActions } from './get_legend_actions'; -export { getSeriesNameFn } from './get_series_name_fn'; -export { getXDomain, getAdjustedDomain } from './domain'; -export { getColorPicker } from './get_color_picker'; -export { getXAccessor } from './accessors'; -export { getAllSeries } from './get_all_series'; diff --git a/src/plugins/vis_types/xy/public/utils/render_all_series.test.mocks.ts b/src/plugins/vis_types/xy/public/utils/render_all_series.test.mocks.ts deleted file mode 100644 index 4c51d8cad64e43..00000000000000 --- a/src/plugins/vis_types/xy/public/utils/render_all_series.test.mocks.ts +++ /dev/null @@ -1,529 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { AxisMode, VisConfig } from '../types'; - -export const getVisConfig = (): VisConfig => { - return { - markSizeRatio: 5.3999999999999995, - fittingFunction: 'linear', - detailedTooltip: true, - isTimeChart: true, - showCurrentTime: false, - showValueLabel: false, - enableHistogramMode: true, - tooltip: { - type: 'vertical', - }, - aspects: { - x: { - accessor: 'col-0-2', - column: 0, - title: 'order_date per minute', - format: { - id: 'date', - params: { - pattern: 'HH:mm', - }, - }, - aggType: 'date_histogram', - aggId: '2', - params: { - date: true, - intervalESUnit: 'm', - intervalESValue: 1, - interval: 60000, - format: 'HH:mm', - }, - }, - y: [ - { - accessor: 'col-1-3', - column: 1, - title: 'Average products.base_price', - format: { - id: 'number', - }, - aggType: 'avg', - aggId: '3', - params: {}, - }, - ], - }, - xAxis: { - id: 'CategoryAxis-1', - position: 'bottom', - show: true, - style: { - axisTitle: { - visible: true, - }, - tickLabel: { - visible: true, - rotation: 0, - }, - }, - groupId: 'CategoryAxis-1', - title: 'order_date per minute', - ticks: { - show: true, - showOverlappingLabels: false, - showDuplicates: false, - }, - grid: { - show: false, - }, - scale: { - type: 'time', - }, - integersOnly: false, - }, - yAxes: [ - { - id: 'ValueAxis-1', - position: 'left', - show: true, - style: { - axisTitle: { - visible: true, - }, - tickLabel: { - visible: true, - rotation: 0, - }, - }, - groupId: 'ValueAxis-1', - title: 'Avg of products.base_price', - ticks: { - show: true, - rotation: 0, - showOverlappingLabels: true, - showDuplicates: true, - }, - grid: { - show: false, - }, - scale: { - mode: AxisMode.Percentage, - type: 'linear', - }, - domain: { - min: NaN, - max: NaN, - }, - integersOnly: false, - }, - ], - legend: { - show: true, - position: 'right', - }, - rotation: 0, - thresholdLine: { - color: '#E7664C', - show: false, - value: 10, - width: 1, - groupId: 'ValueAxis-1', - }, - }; -}; - -export const getVisConfigMutipleYaxis = (): VisConfig => { - return { - markSizeRatio: 5.3999999999999995, - fittingFunction: 'linear', - detailedTooltip: true, - isTimeChart: true, - showCurrentTime: false, - showValueLabel: false, - enableHistogramMode: true, - tooltip: { - type: 'vertical', - }, - aspects: { - x: { - accessor: 'col-0-2', - column: 0, - title: 'order_date per minute', - format: { - id: 'date', - params: { - pattern: 'HH:mm', - }, - }, - aggType: 'date_histogram', - aggId: '2', - params: { - date: true, - intervalESUnit: 'm', - intervalESValue: 1, - interval: 60000, - format: 'HH:mm', - }, - }, - y: [ - { - accessor: 'col-1-3', - column: 1, - title: 'Average products.base_price', - format: { - id: 'number', - }, - aggType: 'avg', - aggId: '3', - params: {}, - }, - { - accessor: 'col-1-2', - column: 1, - title: 'Average products.taxful_price', - format: { - id: 'number', - }, - aggType: 'avg', - aggId: '33', - params: {}, - }, - ], - }, - xAxis: { - id: 'CategoryAxis-1', - position: 'bottom', - show: true, - style: { - axisTitle: { - visible: true, - }, - tickLabel: { - visible: true, - rotation: 0, - }, - }, - groupId: 'CategoryAxis-1', - title: 'order_date per minute', - ticks: { - show: true, - showOverlappingLabels: false, - showDuplicates: false, - }, - grid: { - show: false, - }, - scale: { - type: 'time', - }, - integersOnly: false, - }, - yAxes: [ - { - id: 'ValueAxis-1', - position: 'left', - show: true, - style: { - axisTitle: { - visible: true, - }, - tickLabel: { - visible: true, - rotation: 0, - }, - }, - groupId: 'ValueAxis-1', - title: 'Avg of products.base_price', - ticks: { - show: true, - rotation: 0, - showOverlappingLabels: true, - showDuplicates: true, - }, - grid: { - show: false, - }, - scale: { - mode: AxisMode.Normal, - type: 'linear', - }, - domain: { - min: NaN, - max: NaN, - }, - integersOnly: false, - }, - ], - legend: { - show: true, - position: 'right', - }, - rotation: 0, - thresholdLine: { - color: '#E7664C', - show: false, - value: 10, - width: 1, - groupId: 'ValueAxis-1', - }, - }; -}; - -export const getVisConfigPercentiles = (): VisConfig => { - return { - markSizeRatio: 5.3999999999999995, - fittingFunction: 'linear', - detailedTooltip: true, - isTimeChart: true, - showCurrentTime: false, - showValueLabel: false, - enableHistogramMode: true, - tooltip: { - type: 'vertical', - }, - aspects: { - x: { - accessor: 'col-0-2', - column: 0, - title: 'order_date per minute', - format: { - id: 'date', - params: { - pattern: 'HH:mm', - }, - }, - aggType: 'date_histogram', - aggId: '2', - params: { - date: true, - intervalESUnit: 'm', - intervalESValue: 1, - interval: 60000, - format: 'HH:mm', - }, - }, - y: [ - { - accessor: 'col-1-3.1', - column: 1, - title: '1st percentile of products.base_price', - format: { - id: 'number', - }, - aggType: 'percentiles', - aggId: '3.1', - params: {}, - }, - { - accessor: 'col-2-3.5', - column: 2, - title: '5th percentile of products.base_price', - format: { - id: 'number', - }, - aggType: 'percentiles', - aggId: '3.5', - params: {}, - }, - { - accessor: 'col-3-3.25', - column: 3, - title: '25th percentile of products.base_price', - format: { - id: 'number', - }, - aggType: 'percentiles', - aggId: '3.25', - params: {}, - }, - { - accessor: 'col-4-3.50', - column: 4, - title: '50th percentile of products.base_price', - format: { - id: 'number', - }, - aggType: 'percentiles', - aggId: '3.50', - params: {}, - }, - { - accessor: 'col-5-3.75', - column: 5, - title: '75th percentile of products.base_price', - format: { - id: 'number', - }, - aggType: 'percentiles', - aggId: '3.75', - params: {}, - }, - { - accessor: 'col-6-3.95', - column: 6, - title: '95th percentile of products.base_price', - format: { - id: 'number', - }, - aggType: 'percentiles', - aggId: '3.95', - params: {}, - }, - { - accessor: 'col-7-3.99', - column: 7, - title: '99th percentile of products.base_price', - format: { - id: 'number', - }, - aggType: 'percentiles', - aggId: '3.99', - params: {}, - }, - ], - }, - xAxis: { - id: 'CategoryAxis-1', - position: 'bottom', - show: true, - style: { - axisTitle: { - visible: true, - }, - tickLabel: { - visible: true, - rotation: 0, - }, - }, - groupId: 'CategoryAxis-1', - title: 'order_date per minute', - ticks: { - show: true, - showOverlappingLabels: false, - showDuplicates: false, - }, - grid: { - show: false, - }, - scale: { - type: 'time', - }, - integersOnly: false, - }, - yAxes: [ - { - id: 'ValueAxis-1', - position: 'left', - show: true, - style: { - axisTitle: { - visible: true, - }, - tickLabel: { - visible: true, - rotation: 0, - }, - }, - groupId: 'ValueAxis-1', - title: 'Percentiles of products.base_price', - ticks: { - show: true, - rotation: 0, - showOverlappingLabels: true, - showDuplicates: true, - }, - grid: { - show: false, - }, - scale: { - mode: AxisMode.Normal, - type: 'linear', - }, - domain: { - min: NaN, - max: NaN, - }, - integersOnly: false, - }, - ], - legend: { - show: true, - position: 'right', - }, - rotation: 0, - thresholdLine: { - color: '#E7664C', - show: false, - value: 10, - width: 1, - groupId: 'ValueAxis-1', - }, - }; -}; - -export const getPercentilesData = () => { - return [ - { - 'col-0-2': 1610961900000, - 'col-1-3.1': 11.9921875, - 'col-2-3.5': 11.9921875, - 'col-3-3.25': 11.9921875, - 'col-4-3.50': 38.49609375, - 'col-5-3.75': 65, - 'col-6-3.95': 65, - 'col-7-3.99': 65, - }, - { - 'col-0-2': 1610962980000, - 'col-1-3.1': 28.984375000000004, - 'col-2-3.5': 28.984375, - 'col-3-3.25': 28.984375, - 'col-4-3.50': 30.9921875, - 'col-5-3.75': 41.5, - 'col-6-3.95': 50, - 'col-7-3.99': 50, - }, - { - 'col-0-2': 1610963280000, - 'col-1-3.1': 11.9921875, - 'col-2-3.5': 11.9921875, - 'col-3-3.25': 11.9921875, - 'col-4-3.50': 12.9921875, - 'col-5-3.75': 13.9921875, - 'col-6-3.95': 13.9921875, - 'col-7-3.99': 13.9921875, - }, - { - 'col-0-2': 1610964180000, - 'col-1-3.1': 11.9921875, - 'col-2-3.5': 11.9921875, - 'col-3-3.25': 14.9921875, - 'col-4-3.50': 15.98828125, - 'col-5-3.75': 24.984375, - 'col-6-3.95': 85, - 'col-7-3.99': 85, - }, - { - 'col-0-2': 1610964420000, - 'col-1-3.1': 11.9921875, - 'col-2-3.5': 11.9921875, - 'col-3-3.25': 11.9921875, - 'col-4-3.50': 23.99609375, - 'col-5-3.75': 42, - 'col-6-3.95': 42, - 'col-7-3.99': 42, - }, - { - 'col-0-2': 1610964600000, - 'col-1-3.1': 10.9921875, - 'col-2-3.5': 10.992187500000002, - 'col-3-3.25': 10.9921875, - 'col-4-3.50': 12.4921875, - 'col-5-3.75': 13.9921875, - 'col-6-3.95': 13.9921875, - 'col-7-3.99': 13.9921875, - }, - ]; -}; diff --git a/src/plugins/vis_types/xy/public/utils/render_all_series.test.tsx b/src/plugins/vis_types/xy/public/utils/render_all_series.test.tsx deleted file mode 100644 index 6be7c31cb10608..00000000000000 --- a/src/plugins/vis_types/xy/public/utils/render_all_series.test.tsx +++ /dev/null @@ -1,187 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import React from 'react'; -import { shallow } from 'enzyme'; -import { AreaSeries, BarSeries, CurveType } from '@elastic/charts'; -import { DatatableRow } from '@kbn/expressions-plugin/public'; -import { renderAllSeries } from './render_all_series'; -import { - getVisConfig, - getVisConfigPercentiles, - getPercentilesData, - getVisConfigMutipleYaxis, -} from './render_all_series.test.mocks'; -import { SeriesParam, VisConfig } from '../types'; - -const defaultSeriesParams = [ - { - data: { - id: '3', - label: 'Label', - }, - drawLinesBetweenPoints: true, - interpolate: 'linear', - lineWidth: 2, - mode: 'stacked', - show: true, - showCircles: true, - circlesRadius: 3, - type: 'area', - valueAxis: 'ValueAxis-1', - }, -] as SeriesParam[]; - -const defaultData = [ - { - 'col-0-2': 1610960220000, - 'col-1-3': 26.984375, - }, - { - 'col-0-2': 1610961300000, - 'col-1-3': 30.99609375, - }, - { - 'col-0-2': 1610961900000, - 'col-1-3': 38.49609375, - }, - { - 'col-0-2': 1610962980000, - 'col-1-3': 35.2421875, - }, -]; - -describe('renderAllSeries', function () { - const getAllSeries = (visConfig: VisConfig, params: SeriesParam[], data: DatatableRow[]) => { - return renderAllSeries( - visConfig, - params, - data, - jest.fn(), - jest.fn(), - 'Europe/Athens', - 'col-0-2', - [] - ); - }; - - it('renders an area Series and not a bar series if type is area', () => { - const renderSeries = getAllSeries(getVisConfig(), defaultSeriesParams, defaultData); - const wrapper = shallow(
{renderSeries}
); - expect(wrapper.find(AreaSeries).length).toBe(1); - expect(wrapper.find(BarSeries).length).toBe(0); - }); - - it('renders a bar Series in case of histogram', () => { - const barSeriesParams = [{ ...defaultSeriesParams[0], type: 'histogram' }]; - - const renderBarSeries = renderAllSeries( - getVisConfig(), - barSeriesParams as SeriesParam[], - defaultData, - jest.fn(), - jest.fn(), - 'Europe/Athens', - 'col-0-2', - [] - ); - const wrapper = shallow(
{renderBarSeries}
); - expect(wrapper.find(AreaSeries).length).toBe(0); - expect(wrapper.find(BarSeries).length).toBe(1); - }); - - it('renders percentage data for percentage mode', () => { - const barSeriesParams = [{ ...defaultSeriesParams[0], type: 'histogram', mode: 'percentage' }]; - const config = getVisConfig(); - - const renderBarSeries = renderAllSeries( - config, - barSeriesParams as SeriesParam[], - defaultData, - jest.fn(), - jest.fn(), - 'Europe/Athens', - 'col-0-2', - [] - ); - const wrapper = shallow(
{renderBarSeries}
); - expect(wrapper.find(BarSeries).length).toBe(1); - expect(wrapper.find(BarSeries).prop('stackMode')).toEqual('percentage'); - expect(wrapper.find(BarSeries).prop('data')).toEqual([ - { - 'col-0-2': 1610960220000, - 'col-1-3': 1, - }, - { - 'col-0-2': 1610961300000, - 'col-1-3': 1, - }, - { - 'col-0-2': 1610961900000, - 'col-1-3': 1, - }, - { - 'col-0-2': 1610962980000, - 'col-1-3': 1, - }, - ]); - }); - - it('renders the correct yAccessors for not percentile aggs', () => { - const renderSeries = getAllSeries(getVisConfig(), defaultSeriesParams, defaultData); - const wrapper = shallow(
{renderSeries}
); - expect(wrapper.find(AreaSeries).prop('yAccessors')).toEqual(['col-1-3']); - }); - - it('renders the correct yAccessors for multiple yAxis', () => { - const mutipleYAxisConfig = getVisConfigMutipleYaxis(); - const renderMutipleYAxisSeries = renderAllSeries( - mutipleYAxisConfig, - defaultSeriesParams as SeriesParam[], - defaultData, - jest.fn(), - jest.fn(), - 'Europe/Athens', - 'col-0-2', - [] - ); - const wrapper = shallow(
{renderMutipleYAxisSeries}
); - expect(wrapper.find(AreaSeries).prop('yAccessors')).toEqual(['col-1-3']); - }); - - it('renders the correct yAccessors for percentile aggs', () => { - const percentilesConfig = getVisConfigPercentiles(); - const percentilesData = getPercentilesData(); - const renderPercentileSeries = renderAllSeries( - percentilesConfig, - defaultSeriesParams as SeriesParam[], - percentilesData, - jest.fn(), - jest.fn(), - 'Europe/Athens', - 'col-0-2', - [] - ); - const wrapper = shallow(
{renderPercentileSeries}
); - expect(wrapper.find(AreaSeries).prop('yAccessors')).toEqual([ - 'col-1-3.1', - 'col-2-3.5', - 'col-3-3.25', - 'col-4-3.50', - 'col-5-3.75', - 'col-6-3.95', - 'col-7-3.99', - ]); - }); - - it('defaults the CurveType to linear', () => { - const renderSeries = getAllSeries(getVisConfig(), defaultSeriesParams, defaultData); - const wrapper = shallow(
{renderSeries}
); - expect(wrapper.find(AreaSeries).prop('curve')).toEqual(CurveType.LINEAR); - }); -}); diff --git a/src/plugins/vis_types/xy/public/utils/render_all_series.tsx b/src/plugins/vis_types/xy/public/utils/render_all_series.tsx deleted file mode 100644 index 0e3787a27560de..00000000000000 --- a/src/plugins/vis_types/xy/public/utils/render_all_series.tsx +++ /dev/null @@ -1,222 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import React from 'react'; -import { - AreaSeries, - CurveType, - BarSeries, - XYChartSeriesIdentifier, - SeriesColorAccessorFn, - SeriesName, - Accessor, - AccessorFn, - ColorVariant, - LabelOverflowConstraint, -} from '@elastic/charts'; - -import { DatatableRow } from '@kbn/expressions-plugin/public'; - -import { ChartType } from '../../common'; -import { SeriesParam, VisConfig, Aspect } from '../types'; -import { isValidSeriesForDimension } from './accessors'; -import { computePercentageData } from './compute_percentage_data'; - -/** - * Matches vislib curve to elastic charts - * @param type curve type - */ -const getCurveType = (type?: 'linear' | 'cardinal' | 'step-after'): CurveType => { - switch (type) { - case 'cardinal': - return CurveType.CURVE_MONOTONE_X; - case 'step-after': - return CurveType.CURVE_STEP_AFTER; - case 'linear': - default: - return CurveType.LINEAR; - } -}; - -/** - * Renders chart Line, Area or Bar series - * @param config - * @param seriesParams - * @param data - * @param getSeriesName - * @param getSeriesColor - */ -export const renderAllSeries = ( - { - aspects, - yAxes, - xAxis, - showValueLabel, - enableHistogramMode, - fittingFunction, - fillOpacity, - }: VisConfig, - seriesParams: SeriesParam[], - data: DatatableRow[], - getSeriesName: (series: XYChartSeriesIdentifier) => SeriesName, - getSeriesColor: SeriesColorAccessorFn, - timeZone: string, - xAccessor: Accessor | AccessorFn, - splitSeriesAccessors: Array -) => { - let percentageModeComputedData: DatatableRow[] = []; - yAxes.forEach((yAxis) => { - const scale = yAxis.scale; - // find the series that are positioned on this axis - const series = seriesParams.filter((seriesParam) => seriesParam.valueAxis === yAxis.groupId); - const yAspects: Aspect[] = []; - series.forEach((seriesParam) => { - const aggId = seriesParam.data.id; - const accessorsInSeries = aspects.y.filter((aspect) => aspect.aggId === aggId); - yAspects.push(...accessorsInSeries); - }); - const yAccessors = yAspects.map((aspect) => { - return aspect.accessor; - }) as string[]; - if (scale.mode === 'percentage') { - const splitChartAccessor = aspects.splitColumn?.accessor || aspects.splitRow?.accessor; - percentageModeComputedData = computePercentageData( - data, - xAccessor, - yAccessors, - splitChartAccessor - ); - } - }); - - return seriesParams.map( - ({ - show, - valueAxis: groupId, - data: { id: paramId }, - lineWidth: strokeWidth, - showCircles, - circlesRadius, - drawLinesBetweenPoints, - mode, - interpolate, - type, - }) => { - const yAspects = aspects.y.filter((aspect) => isValidSeriesForDimension(paramId, aspect)); - if (!show || !yAspects.length) { - return null; - } - const yAccessors = yAspects.map((aspect) => aspect.accessor) as string[]; - - const id = `${type}-${yAccessors[0]}`; - const yAxisScale = yAxes.find(({ groupId: axisGroupId }) => axisGroupId === groupId)?.scale; - - const isStacked = mode === 'stacked'; - - const stackMode = yAxisScale?.mode === 'normal' ? undefined : yAxisScale?.mode; - // needed to seperate stacked and non-stacked bars into unique pseudo groups - const pseudoGroupId = isStacked ? `__pseudo_stacked_group-${groupId}__` : groupId; - // set domain of stacked groups to use actual groupId not pseudo groupdId - const useDefaultGroupDomain = isStacked ? groupId : undefined; - - switch (type) { - case ChartType.Histogram: - return ( - - ); - - case ChartType.Area: - case ChartType.Line: - const markSizeAccessor = showCircles ? aspects.z?.accessor ?? undefined : undefined; - - return ( - - ); - default: - // Error: unsupported chart type - return null; - } - } - ); -}; diff --git a/src/plugins/vis_types/xy/public/vis_component.tsx b/src/plugins/vis_types/xy/public/vis_component.tsx deleted file mode 100644 index a744841601a67b..00000000000000 --- a/src/plugins/vis_types/xy/public/vis_component.tsx +++ /dev/null @@ -1,413 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import React, { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react'; -import type { PaletteRegistry } from '@kbn/coloring'; -import { - Chart, - ElementClickListener, - XYChartElementEvent, - Position, - XYChartSeriesIdentifier, - BrushEndListener, - RenderChangeListener, - ScaleType, - AccessorFn, - Accessor, - XYBrushEvent, - Placement, -} from '@elastic/charts'; - -import { compact } from 'lodash'; -import { - getFilterFromChartClickEventFn, - getFilterFromSeriesFn, - LegendToggle, - getBrushFromChartBrushEventFn, - ClickTriggerEvent, - useActiveCursor, -} from '@kbn/charts-plugin/public'; -import { Datatable, IInterpreterRenderHandlers } from '@kbn/expressions-plugin/public'; -import { - DEFAULT_LEGEND_SIZE, - LegendSizeToPixels, - PersistedState, -} from '@kbn/visualizations-plugin/public'; -import { VisParams } from './types'; -import { - getAdjustedDomain, - getXDomain, - getTimeZone, - renderAllSeries, - getSeriesNameFn, - getLegendActions, - getColorPicker, - getXAccessor, - getAllSeries, -} from './utils'; -import { XYAxis, XYEndzones, XYCurrentTime, XYSettings, XYThresholdLine } from './components'; -import { getConfig } from './config'; -import { getThemeService, getDataActions, getPalettesService, getActiveCursor } from './services'; -import { ChartType } from '../common'; - -import './_chart.scss'; -import { - COMPLEX_SPLIT_ACCESSOR, - getComplexAccessor, - getSplitSeriesAccessorFnMap, -} from './utils/accessors'; -import { ChartSplit } from './chart_split'; - -export interface VisComponentProps { - visParams: VisParams; - visData: Datatable; - uiState: PersistedState; - fireEvent: IInterpreterRenderHandlers['event']; - renderComplete: IInterpreterRenderHandlers['done']; - syncColors: boolean; - syncTooltips: boolean; - useLegacyTimeAxis: boolean; -} - -export type VisComponentType = typeof VisComponent; - -const VisComponent = (props: VisComponentProps) => { - const [showLegend, setShowLegend] = useState(() => { - // TODO: Check when this bwc can safely be removed - const bwcLegendStateDefault = - props.visParams.addLegend == null ? true : props.visParams.addLegend; - return props.uiState?.get('vis.legendOpen', bwcLegendStateDefault) as boolean; - }); - const [palettesRegistry, setPalettesRegistry] = useState(null); - const chartRef = useRef(null); - - const handleCursorUpdate = useActiveCursor(getActiveCursor(), chartRef, { - datatables: [props.visData], - }); - - const onRenderChange = useCallback( - (isRendered) => { - if (isRendered) { - props.renderComplete(); - } - }, - [props] - ); - - useEffect(() => { - const fetchPalettes = async () => { - const palettes = await getPalettesService().getPalettes(); - setPalettesRegistry(palettes); - }; - fetchPalettes(); - }, []); - - const handleFilterClick = useCallback( - ( - visData: Datatable, - xAccessor: Accessor | AccessorFn, - splitSeriesAccessors: Array, - splitChartAccessor?: Accessor | AccessorFn - ): ElementClickListener => { - const splitSeriesAccessorFnMap = getSplitSeriesAccessorFnMap(splitSeriesAccessors); - return (elements) => { - if (xAccessor !== null) { - const event = getFilterFromChartClickEventFn( - visData, - xAccessor, - splitSeriesAccessorFnMap, - splitChartAccessor - )(elements as XYChartElementEvent[]); - props.fireEvent(event); - } - }; - }, - [props] - ); - - const handleBrush = useCallback( - ( - visData: Datatable, - xAccessor: Accessor | AccessorFn, - isInterval: boolean - ): BrushEndListener | undefined => { - if (xAccessor !== null && isInterval) { - return (brushArea) => { - const event = getBrushFromChartBrushEventFn( - visData, - xAccessor - )(brushArea as XYBrushEvent); - props.fireEvent(event); - }; - } - }, - [props] - ); - - const getFilterEventData = useCallback( - ( - visData: Datatable, - xAccessor: Accessor | AccessorFn, - splitSeriesAccessors: Array - ) => { - const splitSeriesAccessorFnMap = getSplitSeriesAccessorFnMap(splitSeriesAccessors); - return (series: XYChartSeriesIdentifier): ClickTriggerEvent | null => { - if (xAccessor !== null) { - return getFilterFromSeriesFn(visData)(series, splitSeriesAccessorFnMap); - } - - return null; - }; - }, - [] - ); - - const handleFilterAction = useCallback( - (event: ClickTriggerEvent, negate = false) => { - props.fireEvent({ - ...event, - data: { - ...event.data, - negate, - }, - }); - }, - [props] - ); - - const canFilter = async (event: ClickTriggerEvent | null): Promise => { - if (!event) { - return false; - } - const filters = await getDataActions().createFiltersFromValueClickAction(event.data); - return Boolean(filters.length); - }; - - const toggleLegend = useCallback(() => { - setShowLegend((value) => { - const newValue = !value; - if (props.uiState?.set) { - props.uiState.set('vis.legendOpen', newValue); - } - return newValue; - }); - }, [props.uiState]); - - const setColor = useCallback( - (newColor: string | null, seriesLabel: string | number) => { - const colors = props.uiState?.get('vis.colors') || {}; - if (colors[seriesLabel] === newColor || !newColor) { - delete colors[seriesLabel]; - } else { - colors[seriesLabel] = newColor; - } - - if (props.uiState?.set) { - props.uiState.setSilent('vis.colors', null); - props.uiState.set('vis.colors', colors); - props.uiState.emit('colorChanged'); - } - }, - [props.uiState] - ); - - const { visData, visParams, syncColors, syncTooltips } = props; - const isDarkMode = getThemeService().useDarkMode(); - - const config = getConfig(visData, visParams, props.useLegacyTimeAxis, isDarkMode); - const timeZone = getTimeZone(); - const xDomain = - config.xAxis.scale.type === ScaleType.Ordinal ? undefined : getXDomain(config.aspects.x.params); - const hasBars = visParams.seriesParams.some( - ({ type, data: { id: paramId } }) => - type === ChartType.Histogram && - config.aspects.y.find(({ aggId }) => aggId === paramId) !== undefined - ); - const adjustedXDomain = - config.xAxis.scale.type === ScaleType.Ordinal - ? undefined - : getAdjustedDomain(visData.rows, config.aspects.x, timeZone, xDomain, hasBars); - const legendPosition = useMemo( - () => config.legend.position ?? Position.Right, - [config.legend.position] - ); - - const getSeriesName = getSeriesNameFn(config.aspects, config.aspects.y.length > 1); - - const splitAccessors = config.aspects.series?.map(({ accessor, formatter }) => { - return { accessor, formatter }; - }); - - const allSeries = useMemo( - () => getAllSeries(visData.rows, splitAccessors, config.aspects.y), - [config.aspects.y, splitAccessors, visData.rows] - ); - - const getSeriesColor = useCallback( - (series: XYChartSeriesIdentifier) => { - const seriesName = getSeriesName(series) as string; - if (!seriesName) { - return null; - } - const overwriteColors: Record = props.uiState?.get - ? props.uiState.get('vis.colors', {}) - : {}; - - if (Object.keys(overwriteColors).includes(seriesName)) { - return overwriteColors[seriesName]; - } - const outputColor = palettesRegistry?.get(visParams.palette.name).getCategoricalColor( - [ - { - name: seriesName, - rankAtDepth: splitAccessors - ? allSeries.findIndex((name) => name === seriesName) - : config.aspects.y.findIndex((aspect) => aspect.accessor === series.yAccessor), - totalSeriesAtDepth: splitAccessors ? allSeries.length : config.aspects.y.length, - }, - ], - { - maxDepth: 1, - totalSeries: splitAccessors ? allSeries.length : config.aspects.y.length, - behindText: false, - syncColors, - } - ); - return outputColor || null; - }, - [ - allSeries, - config.aspects.y, - getSeriesName, - props.uiState, - splitAccessors, - syncColors, - visParams.palette.name, - palettesRegistry, - ] - ); - const xAccessor = getXAccessor(config.aspects.x); - - const splitSeriesAccessors = useMemo( - () => - config.aspects.series - ? compact(config.aspects.series.map(getComplexAccessor(COMPLEX_SPLIT_ACCESSOR))) - : [], - [config.aspects.series] - ); - const splitChartColumnAccessor = config.aspects.splitColumn - ? getComplexAccessor(COMPLEX_SPLIT_ACCESSOR, true)(config.aspects.splitColumn) - : undefined; - const splitChartRowAccessor = config.aspects.splitRow - ? getComplexAccessor(COMPLEX_SPLIT_ACCESSOR, true)(config.aspects.splitRow) - : undefined; - - const renderSeries = useMemo( - () => - renderAllSeries( - config, - visParams.seriesParams, - visData.rows, - getSeriesName, - getSeriesColor, - timeZone, - xAccessor, - splitSeriesAccessors - ), - [ - config, - getSeriesColor, - getSeriesName, - splitSeriesAccessors, - timeZone, - visData.rows, - visParams.seriesParams, - xAccessor, - ] - ); - - const legendColorPicker = useMemo( - () => - getColorPicker( - legendPosition, - setColor, - getSeriesName, - visParams.palette.name, - props.uiState - ), - [getSeriesName, legendPosition, props.uiState, setColor, visParams.palette.name] - ); - - return ( -
- - - - 0 - ? getLegendActions( - canFilter, - getFilterEventData(visData, xAccessor, splitSeriesAccessors), - handleFilterAction, - getSeriesName - ) - : undefined - } - /> - - - - - {config.yAxes.map((axisProps) => ( - - ))} - {renderSeries} - -
- ); -}; - -// eslint-disable-next-line import/no-default-export -export default memo(VisComponent); diff --git a/src/plugins/vis_types/xy/public/vis_renderer.tsx b/src/plugins/vis_types/xy/public/vis_renderer.tsx deleted file mode 100644 index 246f85ee600895..00000000000000 --- a/src/plugins/vis_types/xy/public/vis_renderer.tsx +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import React, { lazy } from 'react'; -import { render, unmountComponentAtNode } from 'react-dom'; -import { I18nProvider } from '@kbn/i18n-react'; -import { KibanaExecutionContext } from '@kbn/core-execution-context-common'; - -import { METRIC_TYPE } from '@kbn/analytics'; -import { KibanaThemeProvider } from '@kbn/kibana-react-plugin/public'; -import { VisualizationContainer } from '@kbn/visualizations-plugin/public'; -import type { PersistedState } from '@kbn/visualizations-plugin/public'; -import type { ExpressionRenderDefinition } from '@kbn/expressions-plugin/public'; - -import { LEGACY_TIME_AXIS } from '@kbn/charts-plugin/common'; -import { StartServicesGetter } from '@kbn/kibana-utils-plugin/public'; -import type { XyVisType } from '../common'; -import type { VisComponentType } from './vis_component'; -import { RenderValue, visName } from './expression_functions/xy_vis_fn'; -import { VisTypeXyPluginStartDependencies } from './plugin'; - -// @ts-ignore -const VisComponent = lazy(() => import('./vis_component')); - -function shouldShowNoResultsMessage(visData: any, visType: XyVisType): boolean { - const rows: object[] | undefined = visData?.rows; - const isZeroHits = visData?.hits === 0 || (rows && !rows.length); - - return Boolean(isZeroHits); -} - -/** @internal **/ -const extractContainerType = (context?: KibanaExecutionContext): string | undefined => { - if (context) { - const recursiveGet = (item: KibanaExecutionContext): KibanaExecutionContext | undefined => { - if (item.type) { - return item; - } else if (item.child) { - return recursiveGet(item.child); - } - }; - return recursiveGet(context)?.type; - } -}; - -export const getXYVisRenderer: (deps: { - getStartDeps: StartServicesGetter; -}) => ExpressionRenderDefinition = ({ getStartDeps }) => ({ - name: visName, - displayName: 'XY visualization', - reuseDomNode: true, - render: async (domNode, { visData, visConfig, visType, syncColors, syncTooltips }, handlers) => { - const { core, plugins } = getStartDeps(); - const showNoResult = shouldShowNoResultsMessage(visData, visType); - - const renderComplete = () => { - // Renaming according to business requirements - const visTypeTelemetryMap: Record = { - histogram: 'vertical_bar', - }; - const containerType = extractContainerType(handlers.getExecutionContext()); - const visualizationType = 'agg_based'; - - if (plugins.usageCollection && containerType) { - const hasMixedXY = new Set(visConfig.seriesParams.map((item) => item.type)); - const counterEvents = [ - `render_${visualizationType}_${visTypeTelemetryMap[visType] ?? visType}`, - hasMixedXY.size > 1 ? `render_${visualizationType}_mixed_xy` : undefined, - ].filter(Boolean) as string[]; - - plugins.usageCollection.reportUiCounter(containerType, METRIC_TYPE.COUNT, counterEvents); - } - - handlers.done(); - }; - - handlers.onDestroy(() => unmountComponentAtNode(domNode)); - - render( - - - - - - - , - domNode - ); - }, -}); diff --git a/src/plugins/vis_types/xy/tsconfig.json b/src/plugins/vis_types/xy/tsconfig.json index ab3f3d1252ed84..7cc6e60099cbfd 100644 --- a/src/plugins/vis_types/xy/tsconfig.json +++ b/src/plugins/vis_types/xy/tsconfig.json @@ -15,10 +15,7 @@ "references": [ { "path": "../../../core/tsconfig.json" }, { "path": "../../charts/tsconfig.json" }, - { "path": "../../data/tsconfig.json" }, - { "path": "../../expressions/tsconfig.json" }, { "path": "../../visualizations/tsconfig.json" }, - { "path": "../../usage_collection/tsconfig.json" }, { "path": "../../kibana_utils/tsconfig.json" }, { "path": "../../vis_default_editor/tsconfig.json" }, ] diff --git a/src/plugins/visualizations/public/embeddable/visualize_embeddable.tsx b/src/plugins/visualizations/public/embeddable/visualize_embeddable.tsx index f0aab3b880ae34..3af553fdd56b72 100644 --- a/src/plugins/visualizations/public/embeddable/visualize_embeddable.tsx +++ b/src/plugins/visualizations/public/embeddable/visualize_embeddable.tsx @@ -192,6 +192,10 @@ export class VisualizeEmbeddable return this.vis.description; } + public getVis() { + return this.vis; + } + /** * Gets the Visualize embeddable's local filters * @returns Local/panel-level array of filters for Visualize embeddable diff --git a/src/plugins/visualizations/public/index.ts b/src/plugins/visualizations/public/index.ts index 67b13c8236708c..78ba1d19a982f8 100644 --- a/src/plugins/visualizations/public/index.ts +++ b/src/plugins/visualizations/public/index.ts @@ -37,6 +37,7 @@ export type { Vis, SerializedVis, SerializedVisData, VisData } from './vis'; export type VisualizeEmbeddableFactoryContract = PublicContract; export type VisualizeEmbeddableContract = PublicContract; export type { VisualizeInput } from './embeddable'; +export type { VisualizeEmbeddable } from './embeddable'; export type { SchemaConfig } from './vis_schemas'; export { updateOldState } from './legacy/vis_update_state'; export type { PersistedState } from './persisted_state'; diff --git a/src/plugins/visualizations/public/legacy/vis_update_state.js b/src/plugins/visualizations/public/legacy/vis_update_state.js index db6a9f2beb776d..00853a2af8c6ea 100644 --- a/src/plugins/visualizations/public/legacy/vis_update_state.js +++ b/src/plugins/visualizations/public/legacy/vis_update_state.js @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import { set } from '@elastic/safer-lodash-set'; +import { set } from '@kbn/safer-lodash-set'; import _ from 'lodash'; /** diff --git a/src/plugins/visualizations/public/persisted_state/persisted_state.ts b/src/plugins/visualizations/public/persisted_state/persisted_state.ts index dcc86228031fa4..74b23081c4ace8 100644 --- a/src/plugins/visualizations/public/persisted_state/persisted_state.ts +++ b/src/plugins/visualizations/public/persisted_state/persisted_state.ts @@ -8,7 +8,7 @@ import { EventEmitter } from 'events'; -import { set } from '@elastic/safer-lodash-set'; +import { set } from '@kbn/safer-lodash-set'; import { isPlainObject, cloneDeep, get, isEqual, isString, merge, mergeWith, toPath } from 'lodash'; function prepSetParams(key: PersistedStateKey, value: any, path: PersistedStatePath) { diff --git a/src/plugins/visualizations/public/vis_types/types.ts b/src/plugins/visualizations/public/vis_types/types.ts index 4267e6a0d8aef4..ebcdcf594fdfda 100644 --- a/src/plugins/visualizations/public/vis_types/types.ts +++ b/src/plugins/visualizations/public/vis_types/types.ts @@ -10,6 +10,7 @@ import type { IconType } from '@elastic/eui'; import type { ReactNode } from 'react'; import type { PaletteOutput } from '@kbn/coloring'; import type { Adapters } from '@kbn/inspector-plugin/common'; +import { TimeRange } from '@kbn/data-plugin/common'; import type { Query } from '@kbn/es-query'; import type { AggGroupNames, AggParam, AggGroupName } from '@kbn/data-plugin/public'; import type { DataView } from '@kbn/data-views-plugin/public'; @@ -92,7 +93,8 @@ interface VisualizeEditorMetricContext { export interface VisualizeEditorLayersContext { indexPatternId: string; splitWithDateHistogram?: boolean; - timeFieldName?: string; + xFieldName?: string; + xMode?: string; chartType?: string; axisPosition?: string; termsParams?: Record; @@ -134,7 +136,18 @@ export interface NavigateToLensContext { yLeft: boolean; yRight: boolean; }; - extents: { + tickLabelsVisibility?: { + x: boolean; + yLeft: boolean; + yRight: boolean; + }; + axisTitlesVisibility?: { + x: boolean; + yLeft: boolean; + yRight: boolean; + }; + valueLabels?: boolean; + extents?: { yLeftExtent: AxisExtents; yRightExtent: AxisExtents; }; @@ -173,7 +186,8 @@ export interface VisTypeDefinition { * in order to be displayed in the Lens editor. */ readonly navigateToLens?: ( - params?: VisParams + params?: VisParams, + timeRange?: TimeRange ) => Promise | undefined; /** diff --git a/src/plugins/visualizations/public/visualize_app/components/visualize_top_nav.tsx b/src/plugins/visualizations/public/visualize_app/components/visualize_top_nav.tsx index ca373b31b60207..c80492b45c5cb5 100644 --- a/src/plugins/visualizations/public/visualize_app/components/visualize_top_nav.tsx +++ b/src/plugins/visualizations/public/visualize_app/components/visualize_top_nav.tsx @@ -99,12 +99,15 @@ const TopNav = ({ useEffect(() => { const asyncGetTriggerContext = async () => { if (vis.type.navigateToLens) { - const triggerConfig = await vis.type.navigateToLens(vis.params); + const triggerConfig = await vis.type.navigateToLens( + vis.params, + services.data.query.timefilter.timefilter.getAbsoluteTime() + ); setEditInLensConfig(triggerConfig); } }; asyncGetTriggerContext(); - }, [vis.params, vis.type]); + }, [services.data.query.timefilter.timefilter, vis.params, vis.type]); const displayEditInLensItem = Boolean(vis.type.navigateToLens && editInLensConfig); const config = useMemo(() => { diff --git a/test/api_integration/apis/index.ts b/test/api_integration/apis/index.ts index f7801f4d42e71c..3b8a182308e778 100644 --- a/test/api_integration/apis/index.ts +++ b/test/api_integration/apis/index.ts @@ -28,6 +28,7 @@ export default function ({ loadTestFile }: FtrProviderContext) { loadTestFile(require.resolve('./stats')); loadTestFile(require.resolve('./ui_metric')); loadTestFile(require.resolve('./ui_counters')); + loadTestFile(require.resolve('./unified_field_list')); loadTestFile(require.resolve('./telemetry')); }); } diff --git a/test/api_integration/apis/telemetry/utils/schema_to_config_schema.ts b/test/api_integration/apis/telemetry/utils/schema_to_config_schema.ts index deb6218e145af8..b80a42e1012848 100644 --- a/test/api_integration/apis/telemetry/utils/schema_to_config_schema.ts +++ b/test/api_integration/apis/telemetry/utils/schema_to_config_schema.ts @@ -8,7 +8,7 @@ import type { ObjectType, Type } from '@kbn/config-schema'; import { schema } from '@kbn/config-schema'; -import { set } from '@elastic/safer-lodash-set'; +import { set } from '@kbn/safer-lodash-set'; import { get, merge } from 'lodash'; import type { AllowedSchemaTypes } from '@kbn/usage-collection-plugin/server'; diff --git a/x-pack/test/api_integration/apis/lens/field_stats.ts b/test/api_integration/apis/unified_field_list/field_stats.ts similarity index 92% rename from x-pack/test/api_integration/apis/lens/field_stats.ts rename to test/api_integration/apis/unified_field_list/field_stats.ts index 4d38b54b022527..b489dea50d740d 100644 --- a/x-pack/test/api_integration/apis/lens/field_stats.ts +++ b/test/api_integration/apis/unified_field_list/field_stats.ts @@ -1,8 +1,9 @@ /* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. */ import expect from '@kbn/expect'; @@ -19,8 +20,9 @@ export default ({ getService }: FtrProviderContext) => { const esArchiver = getService('esArchiver'); const kibanaServer = getService('kibanaServer'); const supertest = getService('supertest'); + const API_PATH = '/api/unified_field_list/field_stats'; - describe('index stats apis', () => { + describe('field stats apis', () => { before(async () => { await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/logstash_functional'); }); @@ -41,13 +43,13 @@ export default ({ getService }: FtrProviderContext) => { it('should return a 404 for missing index patterns', async () => { await supertest - .post('/api/lens/index_stats/123/field') + .post(API_PATH) .set(COMMON_HEADERS) .send({ + dataViewId: '123', dslQuery: { match_all: {} }, fromDate: TEST_START_TIME, toDate: TEST_END_TIME, - timeFieldName: '@timestamp', fieldName: 'bytes', }) .expect(404); @@ -55,9 +57,10 @@ export default ({ getService }: FtrProviderContext) => { it('should also work without specifying a time field', async () => { const { body } = await supertest - .post('/api/lens/index_stats/logstash-2015.09.22/field') + .post(API_PATH) .set(COMMON_HEADERS) .send({ + dataViewId: 'logstash-2015.09.22', dslQuery: { match_all: {} }, fromDate: TEST_START_TIME, toDate: TEST_END_TIME, @@ -70,9 +73,10 @@ export default ({ getService }: FtrProviderContext) => { it('should return an auto histogram for numbers and top values', async () => { const { body } = await supertest - .post('/api/lens/index_stats/logstash-2015.09.22/field') + .post(API_PATH) .set(COMMON_HEADERS) .send({ + dataViewId: 'logstash-2015.09.22', dslQuery: { match_all: {} }, fromDate: TEST_START_TIME, toDate: TEST_END_TIME, @@ -177,9 +181,10 @@ export default ({ getService }: FtrProviderContext) => { it('should return an auto histogram for dates', async () => { const { body } = await supertest - .post('/api/lens/index_stats/logstash-2015.09.22/field') + .post(API_PATH) .set(COMMON_HEADERS) .send({ + dataViewId: 'logstash-2015.09.22', dslQuery: { match_all: {} }, fromDate: TEST_START_TIME, toDate: TEST_END_TIME, @@ -210,9 +215,10 @@ export default ({ getService }: FtrProviderContext) => { it('should return top values for strings', async () => { const { body } = await supertest - .post('/api/lens/index_stats/logstash-2015.09.22/field') + .post(API_PATH) .set(COMMON_HEADERS) .send({ + dataViewId: 'logstash-2015.09.22', dslQuery: { match_all: {} }, fromDate: TEST_START_TIME, toDate: TEST_END_TIME, @@ -273,9 +279,10 @@ export default ({ getService }: FtrProviderContext) => { it('should return top values for ip fields', async () => { const { body } = await supertest - .post('/api/lens/index_stats/logstash-2015.09.22/field') + .post(API_PATH) .set(COMMON_HEADERS) .send({ + dataViewId: 'logstash-2015.09.22', dslQuery: { match_all: {} }, fromDate: TEST_START_TIME, toDate: TEST_END_TIME, @@ -336,9 +343,10 @@ export default ({ getService }: FtrProviderContext) => { it('should return histograms for scripted date fields', async () => { const { body } = await supertest - .post('/api/lens/index_stats/logstash-2015.09.22/field') + .post(API_PATH) .set(COMMON_HEADERS) .send({ + dataViewId: 'logstash-2015.09.22', dslQuery: { match_all: {} }, fromDate: TEST_START_TIME, toDate: TEST_END_TIME, @@ -361,9 +369,10 @@ export default ({ getService }: FtrProviderContext) => { it('should return top values for scripted string fields', async () => { const { body } = await supertest - .post('/api/lens/index_stats/logstash-2015.09.22/field') + .post(API_PATH) .set(COMMON_HEADERS) .send({ + dataViewId: 'logstash-2015.09.22', dslQuery: { match_all: {} }, fromDate: TEST_START_TIME, toDate: TEST_END_TIME, @@ -388,9 +397,10 @@ export default ({ getService }: FtrProviderContext) => { it('should return top values for index pattern runtime string fields', async () => { const { body } = await supertest - .post('/api/lens/index_stats/logstash-2015.09.22/field') + .post(API_PATH) .set(COMMON_HEADERS) .send({ + dataViewId: 'logstash-2015.09.22', dslQuery: { match_all: {} }, fromDate: TEST_START_TIME, toDate: TEST_END_TIME, @@ -415,9 +425,10 @@ export default ({ getService }: FtrProviderContext) => { it('should apply filters and queries', async () => { const { body } = await supertest - .post('/api/lens/index_stats/logstash-2015.09.22/field') + .post(API_PATH) .set(COMMON_HEADERS) .send({ + dataViewId: 'logstash-2015.09.22', dslQuery: { bool: { filter: [{ match: { 'geo.src': 'US' } }], @@ -434,9 +445,10 @@ export default ({ getService }: FtrProviderContext) => { it('should allow filtering on a runtime field other than the field in use', async () => { const { body } = await supertest - .post('/api/lens/index_stats/logstash-2015.09.22/field') + .post(API_PATH) .set(COMMON_HEADERS) .send({ + dataViewId: 'logstash-2015.09.22', dslQuery: { bool: { filter: [{ exists: { field: 'runtime_string_field' } }], @@ -477,9 +489,10 @@ export default ({ getService }: FtrProviderContext) => { it('should return an auto histogram for precalculated histograms', async () => { const { body } = await supertest - .post('/api/lens/index_stats/histogram-test/field') + .post(API_PATH) .set(COMMON_HEADERS) .send({ + dataViewId: 'histogram-test', dslQuery: { match_all: {} }, fromDate: TEST_START_TIME, toDate: TEST_END_TIME, @@ -545,9 +558,10 @@ export default ({ getService }: FtrProviderContext) => { it('should return a single-value histogram when filtering a precalculated histogram', async () => { const { body } = await supertest - .post('/api/lens/index_stats/histogram-test/field') + .post(API_PATH) .set(COMMON_HEADERS) .send({ + dataViewId: 'histogram-test', dslQuery: { match: { 'histogram-title': 'single value' } }, fromDate: TEST_START_TIME, toDate: TEST_END_TIME, diff --git a/src/plugins/vis_types/xy/public/config/get_rotation.ts b/test/api_integration/apis/unified_field_list/index.ts similarity index 59% rename from src/plugins/vis_types/xy/public/config/get_rotation.ts rename to test/api_integration/apis/unified_field_list/index.ts index 44c6a46357eb18..da0a6098e0a427 100644 --- a/src/plugins/vis_types/xy/public/config/get_rotation.ts +++ b/test/api_integration/apis/unified_field_list/index.ts @@ -6,14 +6,10 @@ * Side Public License, v 1. */ -import { Rotation } from '@elastic/charts'; +import { FtrProviderContext } from '../../ftr_provider_context'; -import { CategoryAxis } from '../types'; - -export function getRotation({ position }: CategoryAxis): Rotation { - if (position === 'left' || position === 'right') { - return 90; - } - - return 0; +export default function lensApiIntegrationTests({ loadTestFile }: FtrProviderContext) { + describe('UnifiedFieldList', () => { + loadTestFile(require.resolve('./field_stats')); + }); } diff --git a/test/functional/apps/console/_comments.ts b/test/functional/apps/console/_comments.ts index fe0fd882c607f3..9132e0f04b0c8d 100644 --- a/test/functional/apps/console/_comments.ts +++ b/test/functional/apps/console/_comments.ts @@ -15,7 +15,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const retry = getService('retry'); const PageObjects = getPageObjects(['common', 'console', 'header']); - describe('console app', function testComments() { + // Failing: See https://github.com/elastic/kibana/issues/139295 + describe.skip('console app', function testComments() { this.tags('includeFirefox'); before(async () => { log.debug('navigateTo console'); @@ -46,7 +47,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { }); } - describe('with single line comments', async () => { + // FLAKY: https://github.com/elastic/kibana/issues/138160 + describe.skip('with single line comments', async () => { await runTests( [ { diff --git a/test/functional/apps/dashboard/group1/url_field_formatter.ts b/test/functional/apps/dashboard/group1/url_field_formatter.ts index ec6b39d7dc6593..9cdebca739635a 100644 --- a/test/functional/apps/dashboard/group1/url_field_formatter.ts +++ b/test/functional/apps/dashboard/group1/url_field_formatter.ts @@ -24,6 +24,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const fieldName = 'clientip'; const deployment = getService('deployment'); const retry = getService('retry'); + const security = getService('security'); const clickFieldAndCheckUrl = async (fieldLink: WebElementWrapper) => { const fieldValue = await fieldLink.getVisibleText(); @@ -38,6 +39,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { describe('Changing field formatter to Url', () => { before(async function () { + await security.testUser.setRoles(['kibana_admin', 'test_logstash_reader', 'animals']); await kibanaServer.savedObjects.cleanStandardList(); await kibanaServer.importExport.load( 'test/functional/fixtures/kbn_archiver/dashboard/current/kibana' @@ -57,6 +59,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { after(async () => { await kibanaServer.savedObjects.cleanStandardList(); + await security.testUser.restoreDefaults(); }); it('applied on dashboard', async () => { diff --git a/test/functional/apps/dashboard/group6/dashboard_query_bar.ts b/test/functional/apps/dashboard/group6/dashboard_query_bar.ts index 6890ba5bed24f5..010aec96078169 100644 --- a/test/functional/apps/dashboard/group6/dashboard_query_bar.ts +++ b/test/functional/apps/dashboard/group6/dashboard_query_bar.ts @@ -16,10 +16,12 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const pieChart = getService('pieChart'); const queryBar = getService('queryBar'); const retry = getService('retry'); + const security = getService('security'); const PageObjects = getPageObjects(['common', 'dashboard', 'discover']); describe('dashboard query bar', () => { before(async () => { + await security.testUser.setRoles(['kibana_admin', 'test_logstash_reader', 'animals']); await kibanaServer.savedObjects.cleanStandardList(); await kibanaServer.importExport.load( 'test/functional/fixtures/kbn_archiver/dashboard/current/kibana' @@ -34,6 +36,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { after(async () => { await kibanaServer.savedObjects.cleanStandardList(); + await security.testUser.restoreDefaults(); }); it('causes panels to reload when refresh is clicked', async () => { diff --git a/test/functional/apps/dashboard_elements/controls/control_group_chaining.ts b/test/functional/apps/dashboard_elements/controls/control_group_chaining.ts index ba25fcfce98e20..a27a1a4814cfb2 100644 --- a/test/functional/apps/dashboard_elements/controls/control_group_chaining.ts +++ b/test/functional/apps/dashboard_elements/controls/control_group_chaining.ts @@ -13,6 +13,7 @@ import { FtrProviderContext } from '../../../ftr_provider_context'; export default function ({ getService, getPageObjects }: FtrProviderContext) { const retry = getService('retry'); + const security = getService('security'); const { dashboardControls, common, dashboard, timePicker } = getPageObjects([ 'dashboardControls', 'timePicker', @@ -32,6 +33,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { }; before(async () => { + await security.testUser.setRoles(['kibana_admin', 'test_logstash_reader', 'animals']); await common.navigateToApp('dashboard'); await dashboard.gotoDashboardLandingPage(); await dashboard.clickNewDashboard(); @@ -62,6 +64,10 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { controlIds = await dashboardControls.getAllControlIds(); }); + after(async () => { + await security.testUser.restoreDefaults(); + }); + it('Shows all available options in first Options List control', async () => { await dashboardControls.optionsListOpenPopover(controlIds[0]); await retry.try(async () => { diff --git a/test/functional/apps/dashboard_elements/controls/options_list.ts b/test/functional/apps/dashboard_elements/controls/options_list.ts index c6847d2ab618ca..d6f49b9b435e8f 100644 --- a/test/functional/apps/dashboard_elements/controls/options_list.ts +++ b/test/functional/apps/dashboard_elements/controls/options_list.ts @@ -15,6 +15,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const retry = getService('retry'); const queryBar = getService('queryBar'); const pieChart = getService('pieChart'); + const security = getService('security'); const elasticChart = getService('elasticChart'); const filterBar = getService('filterBar'); const testSubjects = getService('testSubjects'); @@ -32,6 +33,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { describe('Dashboard options list integration', () => { before(async () => { + await security.testUser.setRoles(['kibana_admin', 'test_logstash_reader', 'animals']); await common.navigateToApp('dashboard'); await dashboard.gotoDashboardLandingPage(); await dashboard.clickNewDashboard(); @@ -422,6 +424,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await filterBar.removeAllFilters(); await queryBar.clickQuerySubmitButton(); await dashboardControls.clearAllControls(); + await security.testUser.restoreDefaults(); }); }); }); diff --git a/test/functional/apps/dashboard_elements/controls/replace_controls.ts b/test/functional/apps/dashboard_elements/controls/replace_controls.ts index e81788a1946a95..ff4efebf9cac96 100644 --- a/test/functional/apps/dashboard_elements/controls/replace_controls.ts +++ b/test/functional/apps/dashboard_elements/controls/replace_controls.ts @@ -6,17 +6,14 @@ * Side Public License, v 1. */ -import { - OPTIONS_LIST_CONTROL, - RANGE_SLIDER_CONTROL, - TIME_SLIDER_CONTROL, -} from '@kbn/controls-plugin/common'; +import { OPTIONS_LIST_CONTROL, RANGE_SLIDER_CONTROL } from '@kbn/controls-plugin/common'; import { FtrProviderContext } from '../../../ftr_provider_context'; export default function ({ getService, getPageObjects }: FtrProviderContext) { const testSubjects = getService('testSubjects'); const retry = getService('retry'); + const security = getService('security'); const { dashboardControls, timePicker, common, dashboard } = getPageObjects([ 'dashboardControls', @@ -48,23 +45,22 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { }); }; - const replaceWithTimeSlider = async (controlId: string) => { - await changeFieldType(controlId, '@timestamp', TIME_SLIDER_CONTROL); - await testSubjects.waitForDeleted('timeSlider-loading-spinner'); - await dashboardControls.verifyControlType(controlId, 'timeSlider'); - }; - describe('Replacing controls', async () => { let controlId: string; before(async () => { await common.navigateToApp('dashboard'); + await security.testUser.setRoles(['kibana_admin', 'test_logstash_reader', 'animals']); await dashboard.gotoDashboardLandingPage(); await dashboard.clickNewDashboard(); await timePicker.setDefaultDataRange(); await dashboard.saveDashboard(DASHBOARD_NAME, { exitFromEditMode: false }); }); + after(async () => { + await security.testUser.restoreDefaults(); + }); + describe('Replace options list', async () => { beforeEach(async () => { await dashboardControls.clearAllControls(); @@ -83,12 +79,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { it('with range slider', async () => { await replaceWithRangeSlider(controlId); }); - - /** Because the time slider is temporarily disabled as of https://github.com/elastic/kibana/pull/130978, - ** I simply skipped all time slider tests for now :) **/ - it.skip('with time slider', async () => { - await replaceWithTimeSlider(controlId); - }); }); describe('Replace range slider', async () => { @@ -110,35 +100,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { it('with options list', async () => { await replaceWithOptionsList(controlId); }); - - it.skip('with time slider', async () => { - await replaceWithTimeSlider(controlId); - }); - }); - - describe.skip('Replace time slider', async () => { - beforeEach(async () => { - await dashboardControls.clearAllControls(); - await dashboardControls.createControl({ - controlType: TIME_SLIDER_CONTROL, - dataViewTitle: 'animals-*', - fieldName: '@timestamp', - }); - await testSubjects.waitForDeleted('timeSlider-loading-spinner'); - controlId = (await dashboardControls.getAllControlIds())[0]; - }); - - afterEach(async () => { - await dashboard.clearUnsavedChanges(); - }); - - it('with options list', async () => { - await replaceWithOptionsList(controlId); - }); - - it('with range slider', async () => { - await replaceWithRangeSlider(controlId); - }); }); }); } diff --git a/test/functional/apps/discover/group2/_data_grid_context.ts b/test/functional/apps/discover/group2/_data_grid_context.ts index 549e02f60137fc..4903cd446dfc91 100644 --- a/test/functional/apps/discover/group2/_data_grid_context.ts +++ b/test/functional/apps/discover/group2/_data_grid_context.ts @@ -16,6 +16,7 @@ const TEST_FILTER_COLUMN_NAMES = [ ]; export default function ({ getService, getPageObjects }: FtrProviderContext) { + const log = getService('log'); const retry = getService('retry'); const filterBar = getService('filterBar'); const dataGrid = getService('dataGrid'); @@ -114,6 +115,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.header.waitUntilLoadingHasFinished(); await retry.waitFor('document table has a length of 6', async () => { const nrOfDocs = (await dataGrid.getBodyRows()).length; + log.debug('document table length', nrOfDocs); return nrOfDocs === 6; }); }); diff --git a/test/functional/apps/management/_data_view_relationships.ts b/test/functional/apps/management/_data_view_relationships.ts index c8e78eab4ce645..680500f58a60c6 100644 --- a/test/functional/apps/management/_data_view_relationships.ts +++ b/test/functional/apps/management/_data_view_relationships.ts @@ -29,6 +29,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.settings.clickKibanaIndexPatterns(); await PageObjects.settings.clickIndexPatternLogstash(); await PageObjects.settings.clickRelationshipsTab(); + await PageObjects.header.waitUntilLoadingHasFinished(); expect(parseInt(await PageObjects.settings.getRelationshipsTabCount(), 10)).to.be(1); }); }); diff --git a/test/functional/apps/management/ccs_compatibility/_data_views_ccs.ts b/test/functional/apps/management/ccs_compatibility/_data_views_ccs.ts new file mode 100644 index 00000000000000..d2ab2b64bf7385 --- /dev/null +++ b/test/functional/apps/management/ccs_compatibility/_data_views_ccs.ts @@ -0,0 +1,95 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import expect from '@kbn/expect'; +import { FtrProviderContext } from '../../../ftr_provider_context'; + +export default function ({ getService, getPageObjects }: FtrProviderContext) { + const kibanaServer = getService('kibanaServer'); + const testSubjects = getService('testSubjects'); + const es = getService('es'); + const PageObjects = getPageObjects(['settings', 'common', 'header']); + const security = getService('security'); + + describe('data views ccs', function () { + before(async function () { + await security.testUser.setRoles(['kibana_admin']); + }); + + describe('index pattern wizard ccs', () => { + describe('remote cluster only', async () => { + beforeEach(async function () { + await kibanaServer.uiSettings.replace({}); + await PageObjects.settings.navigateTo(); + await PageObjects.settings.clickKibanaIndexPatterns(); + }); + it('create index pattern using remote name', async () => { + await PageObjects.settings.createIndexPattern('ftr-remote:logstash*', null); + await PageObjects.settings.clickKibanaIndexPatterns(); + const indexPatternList = await PageObjects.settings.getIndexPatternList(); + expect(indexPatternList.length).to.eql(1); + }); + it('create index pattern with wildcards in remote name', async () => { + await PageObjects.settings.createIndexPattern('*t*-remo*:log*', null); + await PageObjects.settings.clickKibanaIndexPatterns(); + const indexPatternList = await PageObjects.settings.getIndexPatternList(); + expect(indexPatternList.length).to.eql(1); + }); + + afterEach(async () => { + await PageObjects.header.waitUntilLoadingHasFinished(); + await testSubjects.exists('indexPatternTable'); + await kibanaServer.savedObjects.cleanStandardList(); + }); + }); + describe('remote and local clusters', async () => { + before(async () => { + await es.transport.request({ + path: '/blogs/_doc', + method: 'POST', + body: { user: 'cuffs', message: 20 }, + }); + }); + + beforeEach(async function () { + // delete .kibana index and then wait for Kibana to re-create it + await kibanaServer.uiSettings.replace({}); + await PageObjects.settings.navigateTo(); + await PageObjects.settings.clickKibanaIndexPatterns(); + }); + it('combined remote cluster and local cluster data view without wildcards', async () => { + await PageObjects.settings.createIndexPattern('blog*, ftr-remote:log*', null); + await PageObjects.settings.clickKibanaIndexPatterns(); + const indexPatternList = await PageObjects.settings.getIndexPatternList(); + expect(indexPatternList.length).to.eql(1); + }); + it('combined remote cluster and local cluster data view with wildcards', async () => { + await PageObjects.settings.createIndexPattern('blog*, *t*-remo*:lo*', null); + await PageObjects.settings.clickKibanaIndexPatterns(); + const indexPatternList = await PageObjects.settings.getIndexPatternList(); + expect(indexPatternList.length).to.eql(1); + }); + + afterEach(async () => { + await PageObjects.header.waitUntilLoadingHasFinished(); + await testSubjects.exists('indexPatternTable'); + await kibanaServer.savedObjects.cleanStandardList(); + }); + after(async () => { + await es.transport.request({ + path: '/blogs', + method: 'DELETE', + }); + }); + }); + after(async () => { + await security.testUser.restoreDefaults(); + }); + }); + }); +} diff --git a/test/functional/apps/management/ccs_compatibility/index.ts b/test/functional/apps/management/ccs_compatibility/index.ts new file mode 100644 index 00000000000000..14c0c90e7b9516 --- /dev/null +++ b/test/functional/apps/management/ccs_compatibility/index.ts @@ -0,0 +1,30 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { FtrProviderContext } from '../../../ftr_provider_context'; + +export default function ({ getService, loadTestFile }: FtrProviderContext) { + const remoteEsArchiver = getService('remoteEsArchiver' as 'esArchiver'); + const esArchiver = getService('esArchiver'); + + describe('management', function () { + before(async () => { + await remoteEsArchiver.loadIfNeeded( + 'test/functional/fixtures/es_archiver/logstash_functional' + ); + await esArchiver.loadIfNeeded('test/functional/fixtures/es_archiver/makelogs'); + }); + + after(async () => { + await remoteEsArchiver.unload('test/functional/fixtures/es_archiver/logstash_functional'); + await esArchiver.unload('test/functional/fixtures/es_archiver/makelogs'); + }); + + loadTestFile(require.resolve('./_data_views_ccs')); + }); +} diff --git a/test/functional/apps/visualize/group1/index.ts b/test/functional/apps/visualize/group1/index.ts index aee4595d8f0a0c..7aa4f5517fd308 100644 --- a/test/functional/apps/visualize/group1/index.ts +++ b/test/functional/apps/visualize/group1/index.ts @@ -12,12 +12,13 @@ export default function ({ getService, loadTestFile }: FtrProviderContext) { const browser = getService('browser'); const log = getService('log'); const esArchiver = getService('esArchiver'); + const kibanaServer = getService('kibanaServer'); describe('visualize app - group1', () => { before(async () => { log.debug('Starting visualize before method'); await browser.setWindowSize(1280, 800); - await esArchiver.load('test/functional/fixtures/es_archiver/empty_kibana'); + await kibanaServer.savedObjects.cleanStandardList(); await esArchiver.loadIfNeeded('test/functional/fixtures/es_archiver/logstash_functional'); await esArchiver.loadIfNeeded('test/functional/fixtures/es_archiver/long_window_logstash'); diff --git a/test/functional/apps/visualize/group2/_histogram_request_start.ts b/test/functional/apps/visualize/group2/_histogram_request_start.ts index a12474d9ebc2ee..d01f7ee95f4871 100644 --- a/test/functional/apps/visualize/group2/_histogram_request_start.ts +++ b/test/functional/apps/visualize/group2/_histogram_request_start.ts @@ -14,7 +14,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const log = getService('log'); const retry = getService('retry'); const esArchiver = getService('esArchiver'); - + const kibanaServer = getService('kibanaServer'); const PageObjects = getPageObjects([ 'common', 'visualize', @@ -26,7 +26,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { describe('histogram agg onSearchRequestStart', function () { before(async function () { // loading back default data - await esArchiver.load('test/functional/fixtures/es_archiver/empty_kibana'); + await kibanaServer.savedObjects.cleanStandardList(); await esArchiver.loadIfNeeded('test/functional/fixtures/es_archiver/logstash_functional'); await esArchiver.loadIfNeeded('test/functional/fixtures/es_archiver/long_window_logstash'); diff --git a/test/functional/apps/visualize/group2/index.ts b/test/functional/apps/visualize/group2/index.ts index ea5ad24e2f8733..4925c3ef73598c 100644 --- a/test/functional/apps/visualize/group2/index.ts +++ b/test/functional/apps/visualize/group2/index.ts @@ -12,12 +12,13 @@ export default function ({ getService, loadTestFile }: FtrProviderContext) { const browser = getService('browser'); const log = getService('log'); const esArchiver = getService('esArchiver'); + const kibanaServer = getService('kibanaServer'); describe('visualize app', () => { before(async () => { log.debug('Starting visualize before method'); await browser.setWindowSize(1280, 800); - await esArchiver.load('test/functional/fixtures/es_archiver/empty_kibana'); + await kibanaServer.savedObjects.cleanStandardList(); await esArchiver.loadIfNeeded('test/functional/fixtures/es_archiver/logstash_functional'); await esArchiver.loadIfNeeded('test/functional/fixtures/es_archiver/long_window_logstash'); diff --git a/test/functional/apps/visualize/group3/index.ts b/test/functional/apps/visualize/group3/index.ts index e1f86ca1798a61..4ce3def5c52e12 100644 --- a/test/functional/apps/visualize/group3/index.ts +++ b/test/functional/apps/visualize/group3/index.ts @@ -18,7 +18,7 @@ export default function ({ getService, loadTestFile }: FtrProviderContext) { before(async () => { log.debug('Starting visualize before method'); await browser.setWindowSize(1280, 800); - await esArchiver.load('test/functional/fixtures/es_archiver/empty_kibana'); + await kibanaServer.savedObjects.cleanStandardList(); await esArchiver.loadIfNeeded('test/functional/fixtures/es_archiver/logstash_functional'); await esArchiver.loadIfNeeded('test/functional/fixtures/es_archiver/long_window_logstash'); diff --git a/test/functional/apps/visualize/group4/index.ts b/test/functional/apps/visualize/group4/index.ts index 34764897064152..00270952245709 100644 --- a/test/functional/apps/visualize/group4/index.ts +++ b/test/functional/apps/visualize/group4/index.ts @@ -12,12 +12,13 @@ export default function ({ getService, loadTestFile }: FtrProviderContext) { const browser = getService('browser'); const log = getService('log'); const esArchiver = getService('esArchiver'); + const kibanaServer = getService('kibanaServer'); describe('visualize app', () => { before(async () => { log.debug('Starting visualize before method'); await browser.setWindowSize(1280, 800); - await esArchiver.load('test/functional/fixtures/es_archiver/empty_kibana'); + await kibanaServer.savedObjects.cleanStandardList(); await esArchiver.loadIfNeeded('test/functional/fixtures/es_archiver/logstash_functional'); await esArchiver.loadIfNeeded('test/functional/fixtures/es_archiver/long_window_logstash'); diff --git a/test/functional/apps/visualize/group5/_tsvb_time_series.ts b/test/functional/apps/visualize/group5/_tsvb_time_series.ts index 409b2b3610f5c7..f9e016ff1f6354 100644 --- a/test/functional/apps/visualize/group5/_tsvb_time_series.ts +++ b/test/functional/apps/visualize/group5/_tsvb_time_series.ts @@ -193,6 +193,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { }); await testSubjects.click('applyFiltersPopoverButton'); + await dashboard.waitForRenderComplete(); }; const cleanup = async () => { diff --git a/test/functional/apps/visualize/group5/index.ts b/test/functional/apps/visualize/group5/index.ts index eafa39962ff568..cabdda79c207b1 100644 --- a/test/functional/apps/visualize/group5/index.ts +++ b/test/functional/apps/visualize/group5/index.ts @@ -12,12 +12,13 @@ export default function ({ getService, loadTestFile }: FtrProviderContext) { const browser = getService('browser'); const log = getService('log'); const esArchiver = getService('esArchiver'); + const kibanaServer = getService('kibanaServer'); describe('visualize app', () => { before(async () => { log.debug('Starting visualize before method'); await browser.setWindowSize(1280, 800); - await esArchiver.load('test/functional/fixtures/es_archiver/empty_kibana'); + await kibanaServer.savedObjects.cleanStandardList(); await esArchiver.loadIfNeeded('test/functional/fixtures/es_archiver/logstash_functional'); await esArchiver.loadIfNeeded('test/functional/fixtures/es_archiver/long_window_logstash'); diff --git a/test/functional/apps/visualize/group6/index.ts b/test/functional/apps/visualize/group6/index.ts index 05fe3b232d3708..03027c7a31a8ad 100644 --- a/test/functional/apps/visualize/group6/index.ts +++ b/test/functional/apps/visualize/group6/index.ts @@ -12,12 +12,13 @@ export default function ({ getService, loadTestFile }: FtrProviderContext) { const browser = getService('browser'); const log = getService('log'); const esArchiver = getService('esArchiver'); + const kibanaServer = getService('kibanaServer'); describe('visualize app', () => { before(async () => { log.debug('Starting visualize before method'); await browser.setWindowSize(1280, 800); - await esArchiver.load('test/functional/fixtures/es_archiver/empty_kibana'); + await kibanaServer.savedObjects.cleanStandardList(); await esArchiver.loadIfNeeded('test/functional/fixtures/es_archiver/logstash_functional'); await esArchiver.loadIfNeeded('test/functional/fixtures/es_archiver/long_window_logstash'); diff --git a/test/functional/apps/visualize/replaced_vislib_chart_types/index.ts b/test/functional/apps/visualize/replaced_vislib_chart_types/index.ts index d7f674753058d8..8ee970693b7a92 100644 --- a/test/functional/apps/visualize/replaced_vislib_chart_types/index.ts +++ b/test/functional/apps/visualize/replaced_vislib_chart_types/index.ts @@ -19,7 +19,7 @@ export default function ({ getService, loadTestFile }: FtrProviderContext) { before(async () => { log.debug('Starting visualize before method'); await browser.setWindowSize(1280, 800); - await esArchiver.load('test/functional/fixtures/es_archiver/empty_kibana'); + await kibanaServer.savedObjects.cleanStandardList(); await esArchiver.loadIfNeeded('test/functional/fixtures/es_archiver/logstash_functional'); await esArchiver.loadIfNeeded('test/functional/fixtures/es_archiver/long_window_logstash'); diff --git a/test/functional/config.ccs.ts b/test/functional/config.ccs.ts index 6e3f92ac37b8e6..c5c303cdf22c55 100644 --- a/test/functional/config.ccs.ts +++ b/test/functional/config.ccs.ts @@ -21,6 +21,7 @@ export default async function ({ readConfigFile }: FtrConfigProviderContext) { require.resolve('./apps/dashboard/group3'), require.resolve('./apps/discover/ccs_compatibility'), require.resolve('./apps/console/_console_ccs'), + require.resolve('./apps/management/ccs_compatibility'), ], services: { diff --git a/test/functional/fixtures/es_archiver/deprecations_service/mappings.json b/test/functional/fixtures/es_archiver/deprecations_service/mappings.json index 2d86b863d47dca..47bd39ebf8bcf6 100644 --- a/test/functional/fixtures/es_archiver/deprecations_service/mappings.json +++ b/test/functional/fixtures/es_archiver/deprecations_service/mappings.json @@ -423,7 +423,10 @@ "number_of_shards": "1", "priority": "10", "refresh_interval": "1s", - "routing_partition_size": "1" + "routing_partition_size": "1", + "mapping": { + "total_fields": { "limit": 1500 } + } } } } diff --git a/test/functional/fixtures/es_archiver/saved_objects_management/export_transform/mappings.json b/test/functional/fixtures/es_archiver/saved_objects_management/export_transform/mappings.json index 9562b381a40f86..84628ef0366faa 100644 --- a/test/functional/fixtures/es_archiver/saved_objects_management/export_transform/mappings.json +++ b/test/functional/fixtures/es_archiver/saved_objects_management/export_transform/mappings.json @@ -462,7 +462,10 @@ "number_of_shards": "1", "priority": "10", "refresh_interval": "1s", - "routing_partition_size": "1" + "routing_partition_size": "1", + "mapping": { + "total_fields": { "limit": 1500 } + } } } } diff --git a/test/functional/fixtures/es_archiver/saved_objects_management/hidden_saved_objects/mappings.json b/test/functional/fixtures/es_archiver/saved_objects_management/hidden_saved_objects/mappings.json index 780fdda5f7cbea..43711680a1f129 100644 --- a/test/functional/fixtures/es_archiver/saved_objects_management/hidden_saved_objects/mappings.json +++ b/test/functional/fixtures/es_archiver/saved_objects_management/hidden_saved_objects/mappings.json @@ -470,7 +470,10 @@ "number_of_shards": "1", "priority": "10", "refresh_interval": "1s", - "routing_partition_size": "1" + "routing_partition_size": "1", + "mapping": { + "total_fields": { "limit": 1500 } + } } } } diff --git a/test/functional/fixtures/es_archiver/saved_objects_management/nested_export_transform/mappings.json b/test/functional/fixtures/es_archiver/saved_objects_management/nested_export_transform/mappings.json index 9562b381a40f86..84628ef0366faa 100644 --- a/test/functional/fixtures/es_archiver/saved_objects_management/nested_export_transform/mappings.json +++ b/test/functional/fixtures/es_archiver/saved_objects_management/nested_export_transform/mappings.json @@ -462,7 +462,10 @@ "number_of_shards": "1", "priority": "10", "refresh_interval": "1s", - "routing_partition_size": "1" + "routing_partition_size": "1", + "mapping": { + "total_fields": { "limit": 1500 } + } } } } diff --git a/test/functional/fixtures/es_archiver/saved_objects_management/visible_in_management/mappings.json b/test/functional/fixtures/es_archiver/saved_objects_management/visible_in_management/mappings.json index 3c0a975a30be0a..6ffcd71f29e505 100644 --- a/test/functional/fixtures/es_archiver/saved_objects_management/visible_in_management/mappings.json +++ b/test/functional/fixtures/es_archiver/saved_objects_management/visible_in_management/mappings.json @@ -470,7 +470,10 @@ "number_of_shards": "1", "priority": "10", "refresh_interval": "1s", - "routing_partition_size": "1" + "routing_partition_size": "1", + "mapping": { + "total_fields": { "limit": 1500 } + } } } } diff --git a/test/functional/page_objects/common_page.ts b/test/functional/page_objects/common_page.ts index b3c0f7deda9822..91b852849c0cea 100644 --- a/test/functional/page_objects/common_page.ts +++ b/test/functional/page_objects/common_page.ts @@ -177,8 +177,8 @@ export class CommonPageObject extends FtrService { ) { const appConfig = { // subUrl following the basePath, assumes no hashes. Ex: 'app/endpoint/management' - pathname: `${basePath}${this.config.get(['apps', appName]).pathname}${subUrl}`, - search, + pathname: `${basePath}${this.config.get(['apps', appName]).pathname}${subUrl || ''}`, + search: search || '', }; await this.navigate({ diff --git a/test/functional/page_objects/discover_page.ts b/test/functional/page_objects/discover_page.ts index 8700cc734d8093..ab453fc2378ed4 100644 --- a/test/functional/page_objects/discover_page.ts +++ b/test/functional/page_objects/discover_page.ts @@ -505,6 +505,15 @@ export class DiscoverPageObject extends FtrService { await this.header.waitUntilLoadingHasFinished(); } + public async getIndexPatterns() { + await this.testSubjects.click('discover-dataView-switch-link'); + const indexPatternSwitcher = await this.testSubjects.find('indexPattern-switcher'); + const li = await indexPatternSwitcher.findAllByTagName('li'); + const items = await Promise.all(li.map((lis) => lis.getVisibleText())); + await this.testSubjects.click('discover-dataView-switch-link'); + return items; + } + public async selectTextBaseLang(lang: 'SQL') { await this.testSubjects.click('discover-dataView-switch-link'); await this.find.clickByCssSelector( diff --git a/test/functional/services/dashboard/panel_actions.ts b/test/functional/services/dashboard/panel_actions.ts index c7e786f4b123a4..efffdaf1e77823 100644 --- a/test/functional/services/dashboard/panel_actions.ts +++ b/test/functional/services/dashboard/panel_actions.ts @@ -18,8 +18,8 @@ const CUSTOMIZE_PANEL_DATA_TEST_SUBJ = 'embeddablePanelAction-ACTION_CUSTOMIZE_P const OPEN_CONTEXT_MENU_ICON_DATA_TEST_SUBJ = 'embeddablePanelToggleMenuIcon'; const OPEN_INSPECTOR_TEST_SUBJ = 'embeddablePanelAction-openInspector'; const COPY_PANEL_TO_DATA_TEST_SUBJ = 'embeddablePanelAction-copyToDashboard'; -const LIBRARY_NOTIFICATION_TEST_SUBJ = 'embeddablePanelNotification-ACTION_LIBRARY_NOTIFICATION'; const SAVE_TO_LIBRARY_TEST_SUBJ = 'embeddablePanelAction-saveToLibrary'; +const UNLINK_FROM_LIBRARY_TEST_SUBJ = 'embeddablePanelAction-unlinkFromLibrary'; export class DashboardPanelActionsService extends FtrService { private readonly log = this.ctx.getService('log'); @@ -190,11 +190,12 @@ export class DashboardPanelActionsService extends FtrService { async unlinkFromLibary(parent?: WebElementWrapper) { this.log.debug('unlinkFromLibrary'); - const libraryNotification = parent - ? await this.testSubjects.findDescendant(LIBRARY_NOTIFICATION_TEST_SUBJ, parent) - : await this.testSubjects.find(LIBRARY_NOTIFICATION_TEST_SUBJ); - await libraryNotification.click(); - await this.testSubjects.click('libraryNotificationUnlinkButton'); + await this.openContextMenu(parent); + const exists = await this.testSubjects.exists(UNLINK_FROM_LIBRARY_TEST_SUBJ); + if (!exists) { + await this.clickContextMenuMoreItem(); + } + await this.testSubjects.click(UNLINK_FROM_LIBRARY_TEST_SUBJ); } async saveToLibrary(newTitle: string, parent?: WebElementWrapper) { diff --git a/test/functional/services/filter_bar.ts b/test/functional/services/filter_bar.ts index ab020a1ae943d8..16ce34d446d1cc 100644 --- a/test/functional/services/filter_bar.ts +++ b/test/functional/services/filter_bar.ts @@ -56,8 +56,10 @@ export class FilterBarService extends FtrService { * @param key field name */ public async removeFilter(key: string): Promise { - await this.testSubjects.click(`~filter & ~filter-key-${key}`); - await this.testSubjects.click(`deleteFilter`); + await this.retry.try(async () => { + await this.testSubjects.click(`~filter & ~filter-key-${key}`); + await this.testSubjects.click(`deleteFilter`); + }); await this.header.awaitGlobalLoadingIndicatorHidden(); } diff --git a/test/harden/child_process.js b/test/harden/child_process.js index cd1c54aa5db2d3..f15f5aceb39e75 100644 --- a/test/harden/child_process.js +++ b/test/harden/child_process.js @@ -25,10 +25,7 @@ test('test setup ok', (t) => { t.end(); }); -// TODO: fork() has been omitted as it doesn't validate its arguments in -// Node.js 10 and will throw an internal error asynchronously. This is fixed in -// newer versions. See https://github.com/elastic/kibana/issues/59628 -const functions = ['exec', 'execFile', 'spawn', 'execFileSync', 'execSync', 'spawnSync']; +const functions = ['exec', 'execFile', 'fork', 'spawn', 'execFileSync', 'execSync', 'spawnSync']; for (const name of functions) { test(`${name}()`, (t) => { t.throws(() => cp[name](), /argument must be of type string/); diff --git a/tsconfig.base.json b/tsconfig.base.json index 36988b9e4e9f01..22aeada1359fa4 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -151,8 +151,6 @@ "@kbn/screenshot-mode-plugin/*": ["src/plugins/screenshot_mode/*"], "@kbn/share-plugin": ["src/plugins/share"], "@kbn/share-plugin/*": ["src/plugins/share/*"], - "@kbn/shared-ux-plugin": ["src/plugins/shared_ux"], - "@kbn/shared-ux-plugin/*": ["src/plugins/shared_ux/*"], "@kbn/telemetry-collection-manager-plugin": ["src/plugins/telemetry_collection_manager"], "@kbn/telemetry-collection-manager-plugin/*": ["src/plugins/telemetry_collection_manager/*"], "@kbn/telemetry-management-section-plugin": ["src/plugins/telemetry_management_section"], @@ -163,6 +161,8 @@ "@kbn/ui-actions-enhanced-plugin/*": ["src/plugins/ui_actions_enhanced/*"], "@kbn/ui-actions-plugin": ["src/plugins/ui_actions"], "@kbn/ui-actions-plugin/*": ["src/plugins/ui_actions/*"], + "@kbn/unified-field-list-plugin": ["src/plugins/unified_field_list"], + "@kbn/unified-field-list-plugin/*": ["src/plugins/unified_field_list/*"], "@kbn/unified-search-plugin": ["src/plugins/unified_search"], "@kbn/unified-search-plugin/*": ["src/plugins/unified_search/*"], "@kbn/url-forwarding-plugin": ["src/plugins/url_forwarding"], @@ -275,6 +275,8 @@ "@kbn/embedded-lens-example-plugin/*": ["x-pack/examples/embedded_lens_example/*"], "@kbn/exploratory-view-example-plugin": ["x-pack/examples/exploratory_view_example"], "@kbn/exploratory-view-example-plugin/*": ["x-pack/examples/exploratory_view_example/*"], + "@kbn/files-example-plugin": ["x-pack/examples/files_example"], + "@kbn/files-example-plugin/*": ["x-pack/examples/files_example/*"], "@kbn/reporting-example-plugin": ["x-pack/examples/reporting_example"], "@kbn/reporting-example-plugin/*": ["x-pack/examples/reporting_example/*"], "@kbn/screenshotting-example-plugin": ["x-pack/examples/screenshotting_example"], diff --git a/x-pack/examples/files_example/.i18nrc.json b/x-pack/examples/files_example/.i18nrc.json new file mode 100644 index 00000000000000..79fdf5a24917ca --- /dev/null +++ b/x-pack/examples/files_example/.i18nrc.json @@ -0,0 +1,7 @@ +{ + "prefix": "filesExample", + "paths": { + "filesExample": "." + }, + "translations": ["translations/ja-JP.json"] +} diff --git a/x-pack/examples/files_example/README.md b/x-pack/examples/files_example/README.md new file mode 100644 index 00000000000000..6db1391df5873a --- /dev/null +++ b/x-pack/examples/files_example/README.md @@ -0,0 +1,4 @@ +# filesExample + +An example plugin that integrates with the Kibana "files" plugin. + diff --git a/x-pack/examples/files_example/common/index.ts b/x-pack/examples/files_example/common/index.ts new file mode 100644 index 00000000000000..a58065ad7fd986 --- /dev/null +++ b/x-pack/examples/files_example/common/index.ts @@ -0,0 +1,28 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { FileKind } from '@kbn/files-plugin/common'; + +export const PLUGIN_ID = 'filesExample'; +export const PLUGIN_NAME = 'filesExample'; + +const httpTags = { + tags: [`access:${PLUGIN_ID}`], +}; + +export const exampleFileKind: FileKind = { + id: 'filesExample', + http: { + create: httpTags, + delete: httpTags, + download: httpTags, + getById: httpTags, + list: httpTags, + share: httpTags, + update: httpTags, + }, +}; diff --git a/x-pack/examples/files_example/kibana.json b/x-pack/examples/files_example/kibana.json new file mode 100644 index 00000000000000..5df1141929c415 --- /dev/null +++ b/x-pack/examples/files_example/kibana.json @@ -0,0 +1,14 @@ +{ + "id": "filesExample", + "version": "1.0.0", + "kibanaVersion": "kibana", + "owner": { + "name": "kibana-app-services", + "githubTeam": "kibana-app-services" + }, + "description": "Example plugin integrating with files plugin", + "server": true, + "ui": true, + "requiredPlugins": ["files"], + "optionalPlugins": [] +} diff --git a/x-pack/examples/files_example/public/application.tsx b/x-pack/examples/files_example/public/application.tsx new file mode 100644 index 00000000000000..7f599ded82b6f9 --- /dev/null +++ b/x-pack/examples/files_example/public/application.tsx @@ -0,0 +1,30 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import ReactDOM from 'react-dom'; +import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; +import { AppMountParameters, CoreStart } from '@kbn/core/public'; +import { AppPluginStartDependencies } from './types'; +import { FilesExampleApp } from './components/app'; + +const queryClient = new QueryClient(); + +export const renderApp = ( + { notifications }: CoreStart, + { files }: AppPluginStartDependencies, + { element }: AppMountParameters +) => { + ReactDOM.render( + + + , + element + ); + + return () => ReactDOM.unmountComponentAtNode(element); +}; diff --git a/x-pack/examples/files_example/public/assets/image.png.base64 b/x-pack/examples/files_example/public/assets/image.png.base64 new file mode 100644 index 00000000000000..e85f2ccf1626e6 --- /dev/null +++ b/x-pack/examples/files_example/public/assets/image.png.base64 @@ -0,0 +1 @@ +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 diff --git a/x-pack/examples/files_example/public/components/app.tsx b/x-pack/examples/files_example/public/components/app.tsx new file mode 100644 index 00000000000000..f25494bf3e3ba1 --- /dev/null +++ b/x-pack/examples/files_example/public/components/app.tsx @@ -0,0 +1,169 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { useState } from 'react'; +import { useQuery } from '@tanstack/react-query'; +import type { FileJSON } from '@kbn/files-plugin/common'; +import type { FilesClientResponses } from '@kbn/files-plugin/public'; + +const names = ['foo', 'bar', 'baz']; + +import { + EuiPageTemplate, + EuiInMemoryTable, + EuiInMemoryTableProps, + EuiButton, + EuiIcon, + EuiButtonIcon, + EuiLink, +} from '@elastic/eui'; + +import { CoreStart } from '@kbn/core/public'; +import { DetailsFlyout } from './details_flyout'; +import type { FileClients } from '../types'; +import { ConfirmButtonIcon } from './confirm_button'; +// @ts-ignore +import imageBase64 from '!!raw-loader!../assets/image.png.base64'; + +interface FilesExampleAppDeps { + files: FileClients; + notifications: CoreStart['notifications']; +} + +type ListResponse = FilesClientResponses['list']; + +export const FilesExampleApp = ({ files, notifications }: FilesExampleAppDeps) => { + const { data, isLoading, error, refetch } = useQuery(['files'], () => + files.example.list() + ); + const [isUploadingImage, setIsUploadingImage] = useState(false); + const [isDeletingFile, setIsDeletingFile] = useState(false); + const [selectedItem, setSelectedItem] = useState(); + + const uploadImage = async () => { + try { + setIsUploadingImage(true); + const { file } = await files.example.create({ + name: names[Math.floor(Math.random() * names.length)], + alt: 'My image', + meta: { myValue: 'test' }, + mimeType: 'image/png', + }); + await refetch(); + const blob = new Blob([Uint8Array.from(atob(imageBase64), (c) => c.charCodeAt(0))], { + type: 'image/png', + }); + await files.example.upload({ id: file.id, body: blob }); + await refetch(); + notifications.toasts.addSuccess('Sucessfully uploaded image'); + } finally { + setIsUploadingImage(false); + } + }; + + const renderToolsRight = () => { + return [ + + Upload image + , + ]; + }; + + const items = [...(data?.files ?? [])].reverse(); + + const columns: EuiInMemoryTableProps['columns'] = [ + { + field: 'name', + name: 'Name', + render: (name, item) => setSelectedItem(item)}>{name}, + }, + { + field: 'status', + name: 'Status', + render: (status: FileJSON['status']) => + status === 'READY' ? ( + + ) : status === 'AWAITING_UPLOAD' ? ( + + ) : ( + + ), + }, + { + name: 'Actions', + actions: [ + { + name: 'View', + description: 'View file', + isPrimary: true, + render: (item) => ( + setSelectedItem(item)} + /> + ), + }, + { + name: 'Delete', + description: 'Delete this file', + render: (item) => ( + { + try { + setIsDeletingFile(true); + await files.example.delete({ id: item.id }); + await refetch(); + } finally { + setIsDeletingFile(false); + } + }} + /> + ), + }, + ], + }, + ]; + + return ( + <> + + + + {selectedItem && ( + setSelectedItem(undefined)} + /> + )} + + ); +}; diff --git a/x-pack/examples/files_example/public/components/confirm_button.tsx b/x-pack/examples/files_example/public/components/confirm_button.tsx new file mode 100644 index 00000000000000..05e64243bb374f --- /dev/null +++ b/x-pack/examples/files_example/public/components/confirm_button.tsx @@ -0,0 +1,49 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { useState, FunctionComponent } from 'react'; +import { EuiButtonIcon, EuiToolTip } from '@elastic/eui'; + +interface Props { + label: string; + confirmationText: string; + onConfirm: () => void; + disabled: boolean; +} + +export const ConfirmButtonIcon: FunctionComponent = ({ + label, + confirmationText, + onConfirm, + disabled, +}) => { + const [showConfirm, setShowConfirm] = useState(false); + + return showConfirm ? ( + + + + ) : ( + void }) => { + e.stopPropagation(); + setShowConfirm(true); + setTimeout(() => setShowConfirm(false), 3000); + }} + /> + ); +}; diff --git a/x-pack/examples/files_example/public/components/details_flyout.tsx b/x-pack/examples/files_example/public/components/details_flyout.tsx new file mode 100644 index 00000000000000..64db3fc851006b --- /dev/null +++ b/x-pack/examples/files_example/public/components/details_flyout.tsx @@ -0,0 +1,100 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import moment from 'moment'; +import type { FunctionComponent } from 'react'; +import React from 'react'; +import { css } from '@emotion/react'; +import { + EuiFlyout, + EuiFlyoutHeader, + EuiFlyoutBody, + EuiFlyoutFooter, + EuiFlexGroup, + EuiFlexItem, + EuiButtonEmpty, + EuiButton, + EuiTitle, + EuiDescriptionList, + EuiSpacer, +} from '@elastic/eui'; +import type { FileJSON } from '@kbn/files-plugin/common'; +import { FileClients } from '../types'; + +interface Props { + file: FileJSON; + files: FileClients; + onDismiss: () => void; +} + +export const DetailsFlyout: FunctionComponent = ({ files, file, onDismiss }) => { + return ( + + + +

{file.name}

+
+
+ + + + {file.alt + + + + + + Download + + + + + Close + + + + +
+ ); +}; diff --git a/x-pack/examples/files_example/public/index.ts b/x-pack/examples/files_example/public/index.ts new file mode 100644 index 00000000000000..15e472c4f4cc63 --- /dev/null +++ b/x-pack/examples/files_example/public/index.ts @@ -0,0 +1,14 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { FilesExamplePlugin } from './plugin'; + +// This exports static code and TypeScript types, +// as well as, Kibana Platform `plugin()` initializer. +export function plugin() { + return new FilesExamplePlugin(); +} diff --git a/x-pack/examples/files_example/public/plugin.ts b/x-pack/examples/files_example/public/plugin.ts new file mode 100644 index 00000000000000..ad41c3ce2d44aa --- /dev/null +++ b/x-pack/examples/files_example/public/plugin.ts @@ -0,0 +1,47 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { AppMountParameters, CoreSetup, CoreStart, Plugin } from '@kbn/core/public'; +import { PLUGIN_ID, PLUGIN_NAME, exampleFileKind } from '../common'; +import { FilesExamplePluginsStart, FilesExamplePluginsSetup } from './types'; + +export class FilesExamplePlugin + implements Plugin +{ + public setup(core: CoreSetup) { + // Register an application into the side navigation menu + core.application.register({ + id: PLUGIN_ID, + title: PLUGIN_NAME, + async mount(params: AppMountParameters) { + // Load application bundle + const { renderApp } = await import('./application'); + // Get start services as specified in kibana.json + const [coreStart, { files }] = await core.getStartServices(); + // Render the application + return renderApp( + coreStart, + { + files: { + example: files.filesClientFactory.asScoped(exampleFileKind.id), + }, + }, + params + ); + }, + }); + + // Return methods that should be available to other plugins + return {}; + } + + public start(core: CoreStart) { + return {}; + } + + public stop() {} +} diff --git a/x-pack/examples/files_example/public/types.ts b/x-pack/examples/files_example/public/types.ts new file mode 100644 index 00000000000000..2d450fbdad111c --- /dev/null +++ b/x-pack/examples/files_example/public/types.ts @@ -0,0 +1,25 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { FilesSetup, FilesStart, FilesClient } from '@kbn/files-plugin/public'; + +export interface FilesExamplePluginsSetup { + files: FilesSetup; +} + +export interface FilesExamplePluginsStart { + files: FilesStart; +} + +export interface FileClients { + // Example file kind + example: FilesClient; +} + +export interface AppPluginStartDependencies { + files: FileClients; +} diff --git a/x-pack/examples/files_example/server/index.ts b/x-pack/examples/files_example/server/index.ts new file mode 100644 index 00000000000000..5b6de87308e5e6 --- /dev/null +++ b/x-pack/examples/files_example/server/index.ts @@ -0,0 +1,16 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { PluginInitializerContext } from '@kbn/core/server'; +import { FilesExamplePlugin } from './plugin'; + +// This exports static code and TypeScript types, +// as well as, Kibana Platform `plugin()` initializer. + +export function plugin(initializerContext: PluginInitializerContext) { + return new FilesExamplePlugin(initializerContext); +} diff --git a/x-pack/examples/files_example/server/plugin.ts b/x-pack/examples/files_example/server/plugin.ts new file mode 100644 index 00000000000000..2b077d6f3e88ae --- /dev/null +++ b/x-pack/examples/files_example/server/plugin.ts @@ -0,0 +1,35 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { PluginInitializerContext, CoreSetup, CoreStart, Plugin, Logger } from '@kbn/core/server'; +import { exampleFileKind } from '../common'; +import type { FilesExamplePluginsSetup, FilesExamplePluginsStart } from './types'; + +export class FilesExamplePlugin + implements Plugin +{ + private readonly logger: Logger; + + constructor(initializerContext: PluginInitializerContext) { + this.logger = initializerContext.logger.get(); + } + + public setup(core: CoreSetup, { files }: FilesExamplePluginsSetup) { + this.logger.debug('filesExample: Setup'); + + files.registerFileKind(exampleFileKind); + + return {}; + } + + public start(core: CoreStart) { + this.logger.debug('filesExample: Started'); + return {}; + } + + public stop() {} +} diff --git a/x-pack/examples/files_example/server/types.ts b/x-pack/examples/files_example/server/types.ts new file mode 100644 index 00000000000000..b1cef58620ca52 --- /dev/null +++ b/x-pack/examples/files_example/server/types.ts @@ -0,0 +1,16 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { FilesSetup, FilesStart } from '@kbn/files-plugin/server'; + +export interface FilesExamplePluginsSetup { + files: FilesSetup; +} + +export interface FilesExamplePluginsStart { + files: FilesStart; +} diff --git a/x-pack/examples/files_example/tsconfig.json b/x-pack/examples/files_example/tsconfig.json new file mode 100644 index 00000000000000..caeb25650a142a --- /dev/null +++ b/x-pack/examples/files_example/tsconfig.json @@ -0,0 +1,25 @@ +{ + "extends": "../../../tsconfig.base.json", + "compilerOptions": { + "outDir": "./target/types" + }, + "include": [ + "index.ts", + "common/**/*", + "public/**/*", + "server/**/*", + "public/**/*.ts", + "public/**/*.tsx", + "server/**/*.ts", + "../../../typings/**/*" + ], + "exclude": [], + "references": [ + { + "path": "../../../src/core/tsconfig.json" + }, + { + "path": "../../plugins/files/tsconfig.json" + } + ] +} diff --git a/x-pack/plugins/actions/server/action_type_registry.test.ts b/x-pack/plugins/actions/server/action_type_registry.test.ts index f8425063de0473..bad09ce70207d8 100644 --- a/x-pack/plugins/actions/server/action_type_registry.test.ts +++ b/x-pack/plugins/actions/server/action_type_registry.test.ts @@ -169,6 +169,24 @@ describe('register()', () => { expect(getRetry(0, new ExecutorError('my message', {}, retryTime))).toEqual(retryTime); }); + test('provides a getRetry function that handles errors based on maxAttempts', () => { + const actionTypeRegistry = new ActionTypeRegistry(actionTypeRegistryParams); + actionTypeRegistry.register({ + id: 'my-action-type', + name: 'My action type', + minimumLicenseRequired: 'basic', + supportedFeatureIds: ['alerting'], + executor, + maxAttempts: 2, + }); + expect(mockTaskManager.registerTaskDefinitions).toHaveBeenCalledTimes(1); + const registerTaskDefinitionsCall = mockTaskManager.registerTaskDefinitions.mock.calls[0][0]; + const getRetry = registerTaskDefinitionsCall['actions:my-action-type'].getRetry!; + + expect(getRetry(1, new Error())).toEqual(true); + expect(getRetry(2, new Error())).toEqual(false); + }); + test('registers gold+ action types to the licensing feature usage API', () => { const actionTypeRegistry = new ActionTypeRegistry(actionTypeRegistryParams); actionTypeRegistry.register({ diff --git a/x-pack/plugins/actions/server/action_type_registry.ts b/x-pack/plugins/actions/server/action_type_registry.ts index ed5f731452c457..c105034c7f687f 100644 --- a/x-pack/plugins/actions/server/action_type_registry.ts +++ b/x-pack/plugins/actions/server/action_type_registry.ts @@ -156,8 +156,8 @@ export class ActionTypeRegistry { if (error instanceof ExecutorError) { return error.retry == null ? false : error.retry; } - // Don't retry other kinds of errors - return false; + // Only retry other kinds of errors based on attempts + return attempts < (actionType.maxAttempts ?? 0); }, createTaskRunner: (context: RunContext) => this.taskRunnerFactory.create(context, actionType.maxAttempts), diff --git a/x-pack/plugins/actions/server/actions_client.test.ts b/x-pack/plugins/actions/server/actions_client.test.ts index 4576a301a5f2f7..44276a604896f3 100644 --- a/x-pack/plugins/actions/server/actions_client.test.ts +++ b/x-pack/plugins/actions/server/actions_client.test.ts @@ -45,11 +45,15 @@ import { getOAuthJwtAccessToken } from './builtin_action_types/lib/get_oauth_jwt import { getOAuthClientCredentialsAccessToken } from './builtin_action_types/lib/get_oauth_client_credentials_access_token'; import { OAuthParams } from './routes/get_oauth_access_token'; -jest.mock('@kbn/core/server/saved_objects/service/lib/utils', () => ({ - SavedObjectsUtils: { - generateId: () => 'mock-saved-object-id', - }, -})); +jest.mock('@kbn/core-saved-objects-utils-server', () => { + const actual = jest.requireActual('@kbn/core-saved-objects-utils-server'); + return { + ...actual, + SavedObjectsUtils: { + generateId: () => 'mock-saved-object-id', + }, + }; +}); jest.mock('./lib/track_legacy_rbac_exemption', () => ({ trackLegacyRBACExemption: jest.fn(), diff --git a/x-pack/plugins/actions/server/builtin_action_types/lib/connector_token_client.test.ts b/x-pack/plugins/actions/server/builtin_action_types/lib/connector_token_client.test.ts index dfa307ca3cd91b..1aa8bbb3da9a7d 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/lib/connector_token_client.test.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/lib/connector_token_client.test.ts @@ -13,11 +13,15 @@ import { Logger } from '@kbn/core/server'; import { ConnectorToken } from '../../types'; const logger = loggingSystemMock.create().get() as jest.Mocked; -jest.mock('@kbn/core/server/saved_objects/service/lib/utils', () => ({ - SavedObjectsUtils: { - generateId: () => 'mock-saved-object-id', - }, -})); +jest.mock('@kbn/core-saved-objects-utils-server', () => { + const actual = jest.requireActual('@kbn/core-saved-objects-utils-server'); + return { + ...actual, + SavedObjectsUtils: { + generateId: () => 'mock-saved-object-id', + }, + }; +}); const unsecuredSavedObjectsClient = savedObjectsClientMock.create(); const encryptedSavedObjectsClient = encryptedSavedObjectsMock.createClient(); diff --git a/x-pack/plugins/alerting/server/rules_client/tests/create.test.ts b/x-pack/plugins/alerting/server/rules_client/tests/create.test.ts index 53f9c595455263..b29d41f183b735 100644 --- a/x-pack/plugins/alerting/server/rules_client/tests/create.test.ts +++ b/x-pack/plugins/alerting/server/rules_client/tests/create.test.ts @@ -26,11 +26,15 @@ jest.mock('../../invalidate_pending_api_keys/bulk_mark_api_keys_for_invalidation bulkMarkApiKeysForInvalidation: jest.fn(), })); -jest.mock('@kbn/core/server/saved_objects/service/lib/utils', () => ({ - SavedObjectsUtils: { - generateId: () => 'mock-saved-object-id', - }, -})); +jest.mock('@kbn/core-saved-objects-utils-server', () => { + const actual = jest.requireActual('@kbn/core-saved-objects-utils-server'); + return { + ...actual, + SavedObjectsUtils: { + generateId: () => 'mock-saved-object-id', + }, + }; +}); const taskManager = taskManagerMock.createStart(); const ruleTypeRegistry = ruleTypeRegistryMock.create(); diff --git a/x-pack/plugins/alerting/server/rules_client/tests/update.test.ts b/x-pack/plugins/alerting/server/rules_client/tests/update.test.ts index 219ee35756f075..9071099ed3aaf3 100644 --- a/x-pack/plugins/alerting/server/rules_client/tests/update.test.ts +++ b/x-pack/plugins/alerting/server/rules_client/tests/update.test.ts @@ -23,11 +23,15 @@ import { auditLoggerMock } from '@kbn/security-plugin/server/audit/mocks'; import { getBeforeSetup, setGlobalDate } from './lib'; import { bulkMarkApiKeysForInvalidation } from '../../invalidate_pending_api_keys/bulk_mark_api_keys_for_invalidation'; -jest.mock('@kbn/core/server/saved_objects/service/lib/utils', () => ({ - SavedObjectsUtils: { - generateId: () => 'mock-saved-object-id', - }, -})); +jest.mock('@kbn/core-saved-objects-utils-server', () => { + const actual = jest.requireActual('@kbn/core-saved-objects-utils-server'); + return { + ...actual, + SavedObjectsUtils: { + generateId: () => 'mock-saved-object-id', + }, + }; +}); jest.mock('../../invalidate_pending_api_keys/bulk_mark_api_keys_for_invalidation', () => ({ bulkMarkApiKeysForInvalidation: jest.fn(), diff --git a/x-pack/plugins/alerting/server/saved_objects/migrations.ts b/x-pack/plugins/alerting/server/saved_objects/migrations.ts index ddae200ae8fa6e..0873ba3e5c936f 100644 --- a/x-pack/plugins/alerting/server/saved_objects/migrations.ts +++ b/x-pack/plugins/alerting/server/saved_objects/migrations.ts @@ -7,7 +7,7 @@ import { isRuleType, ruleTypeMappings } from '@kbn/securitysolution-rules'; import { isString } from 'lodash/fp'; -import { omit } from 'lodash'; +import { omit, pick } from 'lodash'; import moment from 'moment-timezone'; import { gte } from 'semver'; import { @@ -40,7 +40,8 @@ interface AlertLogMeta extends LogMeta { } type AlertMigration = ( - doc: SavedObjectUnsanitizedDoc + doc: SavedObjectUnsanitizedDoc, + context: SavedObjectMigrationContext ) => SavedObjectUnsanitizedDoc; function createEsoMigration( @@ -169,6 +170,12 @@ export function getMigrations( pipeMigrations(addSearchType, removeInternalTags, convertSnoozes) ); + const migrationRules850 = createEsoMigration( + encryptedSavedObjects, + (doc): doc is SavedObjectUnsanitizedDoc => isEsQueryRuleType(doc), + pipeMigrations(stripOutRuntimeFieldsInOldESQuery) + ); + return mergeSavedObjectMigrationMaps( { '7.10.0': executeMigrationWithErrorHandling(migrationWhenRBACWasIntroduced, '7.10.0'), @@ -182,6 +189,7 @@ export function getMigrations( '8.0.1': executeMigrationWithErrorHandling(migrationRules801, '8.0.1'), '8.2.0': executeMigrationWithErrorHandling(migrationRules820, '8.2.0'), '8.3.0': executeMigrationWithErrorHandling(migrationRules830, '8.3.0'), + '8.5.0': executeMigrationWithErrorHandling(migrationRules850, '8.5.0'), }, getSearchSourceMigrations(encryptedSavedObjects, searchSourceMigrations) ); @@ -750,6 +758,47 @@ function addSecuritySolutionAADRuleTypeTags( : doc; } +function stripOutRuntimeFieldsInOldESQuery( + doc: SavedObjectUnsanitizedDoc, + context: SavedObjectMigrationContext +): SavedObjectUnsanitizedDoc { + const isESDSLrule = + isEsQueryRuleType(doc) && !isSerializedSearchSource(doc.attributes.params.searchConfiguration); + + if (isESDSLrule) { + try { + const parsedQuery = JSON.parse(doc.attributes.params.esQuery as string); + // parsing and restringifying will cause us to lose the formatting so we only do so if this rule has + // fields other than `query` which is the only valid field at this stage + const hasFieldsOtherThanQuery = Object.keys(parsedQuery).some((key) => key !== 'query'); + return hasFieldsOtherThanQuery + ? { + ...doc, + attributes: { + ...doc.attributes, + params: { + ...doc.attributes.params, + esQuery: JSON.stringify(pick(parsedQuery, 'query'), null, 4), + }, + }, + } + : doc; + } catch (err) { + // Instead of failing the upgrade when an unparsable rule is encountered, we log that the rule caouldn't be migrated and + // as a result legacy parameters might cause the rule to behave differently if it is, in fact, still running at all + context.log.error( + `unable to migrate and remove legacy runtime fields in rule ${doc.id} due to invalid query: "${doc.attributes.params.esQuery}" - query must be JSON`, + { + migrations: { + alertDocument: doc, + }, + } + ); + } + } + return doc; +} + function addThreatIndicatorPathToThreatMatchRules( doc: SavedObjectUnsanitizedDoc ): SavedObjectUnsanitizedDoc { @@ -957,8 +1006,8 @@ function removeInternalTags( } function pipeMigrations(...migrations: AlertMigration[]): AlertMigration { - return (doc: SavedObjectUnsanitizedDoc) => - migrations.reduce((migratedDoc, nextMigration) => nextMigration(migratedDoc), doc); + return (doc: SavedObjectUnsanitizedDoc, context: SavedObjectMigrationContext) => + migrations.reduce((migratedDoc, nextMigration) => nextMigration(migratedDoc, context), doc); } function mapSearchSourceMigrationFunc( diff --git a/x-pack/plugins/alerting/server/task_runner/schedule_actions_for_alerts.test.ts b/x-pack/plugins/alerting/server/task_runner/schedule_actions_for_alerts.test.ts new file mode 100644 index 00000000000000..cdd16289c7a1ae --- /dev/null +++ b/x-pack/plugins/alerting/server/task_runner/schedule_actions_for_alerts.test.ts @@ -0,0 +1,207 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { RuleRunMetricsStore } from '../lib/rule_run_metrics_store'; +import { RecoveredActionGroup } from '../types'; +import { RULE_NAME } from './fixtures'; +import { loggingSystemMock } from '@kbn/core/server/mocks'; +import { scheduleActionsForAlerts } from './schedule_actions_for_alerts'; +import { Alert } from '../alert'; +import { AlertInstanceState, AlertInstanceContext, DefaultActionGroupId } from '../../common'; +import sinon from 'sinon'; + +describe('Schedule Actions For Alerts', () => { + const ruleRunMetricsStore = new RuleRunMetricsStore(); + const executionHandler = jest.fn(); + const recoveryActionGroup = RecoveredActionGroup; + const mutedAlertIdsSet = new Set('2'); + const logger: ReturnType = + loggingSystemMock.createLogger(); + const notifyWhen = 'onActiveAlert'; + const throttle = null; + let clock: sinon.SinonFakeTimers; + + beforeEach(() => { + jest.resetAllMocks(); + clock.reset(); + }); + beforeAll(() => { + clock = sinon.useFakeTimers(); + }); + afterAll(() => clock.restore()); + + test('schedules alerts with executable actions', async () => { + const alert = new Alert('1', { + state: { test: true }, + meta: { + lastScheduledActions: { + date: new Date(), + group: 'default', + }, + }, + }); + alert.scheduleActions('default'); + const alerts = { '1': alert }; + const recoveredAlerts = {}; + + await scheduleActionsForAlerts({ + activeAlerts: alerts, + recoveryActionGroup, + recoveredAlerts, + executionHandler, + mutedAlertIdsSet, + logger, + ruleLabel: RULE_NAME, + ruleRunMetricsStore, + throttle, + notifyWhen, + }); + + expect(executionHandler).toBeCalledWith({ + actionGroup: 'default', + context: {}, + state: { test: true }, + alertId: '1', + ruleRunMetricsStore, + }); + }); + + test('schedules alerts with recovered actions', async () => { + const alert = new Alert('1', { + state: { test: true }, + meta: { + lastScheduledActions: { + date: new Date(), + group: 'default', + }, + }, + }); + const alerts = {}; + const recoveredAlerts = { '1': alert }; + + await scheduleActionsForAlerts({ + activeAlerts: alerts, + recoveryActionGroup, + recoveredAlerts, + executionHandler, + mutedAlertIdsSet, + logger, + ruleLabel: RULE_NAME, + ruleRunMetricsStore, + throttle, + notifyWhen, + }); + + expect(executionHandler).toHaveBeenNthCalledWith(1, { + actionGroup: 'recovered', + context: {}, + state: {}, + alertId: '1', + ruleRunMetricsStore, + }); + }); + + test('does not schedule alerts with recovered actions that are muted', async () => { + const alert = new Alert('2', { + state: { test: true }, + meta: { + lastScheduledActions: { + date: new Date(), + group: 'default', + }, + }, + }); + const alerts = {}; + const recoveredAlerts = { '2': alert }; + + await scheduleActionsForAlerts({ + activeAlerts: alerts, + recoveryActionGroup, + recoveredAlerts, + executionHandler, + mutedAlertIdsSet, + logger, + ruleLabel: RULE_NAME, + ruleRunMetricsStore, + throttle, + notifyWhen, + }); + + expect(executionHandler).not.toBeCalled(); + expect(logger.debug).nthCalledWith( + 1, + `skipping scheduling of actions for '2' in rule ${RULE_NAME}: instance is muted` + ); + }); + + test('does not schedule active alerts that are throttled', async () => { + const alert = new Alert('1', { + state: { test: true }, + meta: { + lastScheduledActions: { + date: new Date(), + group: 'default', + }, + }, + }); + clock.tick(30000); + alert.scheduleActions('default'); + const alerts = { '1': alert }; + const recoveredAlerts = {}; + + await scheduleActionsForAlerts({ + activeAlerts: alerts, + recoveryActionGroup, + recoveredAlerts, + executionHandler, + mutedAlertIdsSet, + logger, + ruleLabel: RULE_NAME, + ruleRunMetricsStore, + throttle: '1m', + notifyWhen, + }); + expect(executionHandler).not.toBeCalled(); + expect(logger.debug).nthCalledWith( + 1, + `skipping scheduling of actions for '1' in rule ${RULE_NAME}: rule is throttled` + ); + }); + + test('does not schedule active alerts that are muted', async () => { + const alert = new Alert('2', { + state: { test: true }, + meta: { + lastScheduledActions: { + date: new Date(), + group: 'default', + }, + }, + }); + const alerts = { '2': alert }; + const recoveredAlerts = {}; + + await scheduleActionsForAlerts({ + activeAlerts: alerts, + recoveryActionGroup, + recoveredAlerts, + executionHandler, + mutedAlertIdsSet, + logger, + ruleLabel: RULE_NAME, + ruleRunMetricsStore, + throttle, + notifyWhen, + }); + + expect(executionHandler).not.toBeCalled(); + expect(logger.debug).nthCalledWith( + 1, + `skipping scheduling of actions for '2' in rule ${RULE_NAME}: rule is muted` + ); + }); +}); diff --git a/x-pack/plugins/alerting/server/task_runner/schedule_actions_for_alerts.ts b/x-pack/plugins/alerting/server/task_runner/schedule_actions_for_alerts.ts new file mode 100644 index 00000000000000..e0cc6d5b81c3ae --- /dev/null +++ b/x-pack/plugins/alerting/server/task_runner/schedule_actions_for_alerts.ts @@ -0,0 +1,147 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { Logger } from '@kbn/core/server'; +import { ExecutionHandler } from './create_execution_handler'; +import { ScheduleActionsForAlertsParams } from './types'; +import { AlertInstanceState, AlertInstanceContext } from '../types'; +import { Alert } from '../alert'; +import { RuleRunMetricsStore } from '../lib/rule_run_metrics_store'; + +export async function scheduleActionsForAlerts< + InstanceState extends AlertInstanceState, + InstanceContext extends AlertInstanceContext, + ActionGroupIds extends string, + RecoveryActionGroupId extends string +>( + params: ScheduleActionsForAlertsParams< + InstanceState, + InstanceContext, + ActionGroupIds, + RecoveryActionGroupId + > +): Promise { + const { + logger, + activeAlerts, + recoveryActionGroup, + recoveredAlerts, + executionHandler, + mutedAlertIdsSet, + ruleLabel, + ruleRunMetricsStore, + throttle, + notifyWhen, + } = params; + // execute alerts with executable actions + for (const [alertId, alert] of Object.entries(activeAlerts)) { + const executeAction: boolean = shouldExecuteAction( + alertId, + alert, + mutedAlertIdsSet, + ruleLabel, + logger, + throttle, + notifyWhen + ); + if (executeAction && alert.hasScheduledActions()) { + const { actionGroup, subgroup: actionSubgroup, state } = alert.getScheduledActionOptions()!; + await executeAlert( + alertId, + alert, + executionHandler, + ruleRunMetricsStore, + actionGroup, + state, + actionSubgroup + ); + } + } + + // execute recovered alerts + for (const alertId of Object.keys(recoveredAlerts)) { + if (mutedAlertIdsSet.has(alertId)) { + logger.debug( + `skipping scheduling of actions for '${alertId}' in rule ${ruleLabel}: instance is muted` + ); + } else { + const alert = recoveredAlerts[alertId]; + await executeAlert( + alertId, + alert, + executionHandler, + ruleRunMetricsStore, + recoveryActionGroup.id, + {} as InstanceState + ); + alert.scheduleActions(recoveryActionGroup.id); + } + } +} + +async function executeAlert< + InstanceState extends AlertInstanceState, + InstanceContext extends AlertInstanceContext, + ActionGroupIds extends string, + RecoveryActionGroupId extends string +>( + alertId: string, + alert: Alert, + executionHandler: ExecutionHandler, + ruleRunMetricsStore: RuleRunMetricsStore, + actionGroup: ActionGroupIds | RecoveryActionGroupId, + state: InstanceState, + actionSubgroup?: string +) { + alert.updateLastScheduledActions(actionGroup, actionSubgroup); + alert.unscheduleActions(); + return executionHandler({ + actionGroup, + actionSubgroup, + context: alert.getContext(), + state, + alertId, + ruleRunMetricsStore, + }); +} + +function shouldExecuteAction< + InstanceState extends AlertInstanceState, + InstanceContext extends AlertInstanceContext, + ActionGroupIds extends string +>( + alertId: string, + alert: Alert, + mutedAlertIdsSet: Set, + ruleLabel: string, + logger: Logger, + throttle: string | null, + notifyWhen: string | null +) { + const throttled = alert.isThrottled(throttle); + const muted = mutedAlertIdsSet.has(alertId); + let executeAction = true; + + if (throttled || muted) { + executeAction = false; + logger.debug( + `skipping scheduling of actions for '${alertId}' in rule ${ruleLabel}: rule is ${ + muted ? 'muted' : 'throttled' + }` + ); + } else if ( + notifyWhen === 'onActionGroupChange' && + !alert.scheduledActionGroupOrSubgroupHasChanged() + ) { + executeAction = false; + logger.debug( + `skipping scheduling of actions for '${alertId}' in rule ${ruleLabel}: alert is active but action group has not changed` + ); + } + + return executeAction; +} diff --git a/x-pack/plugins/alerting/server/task_runner/task_runner.ts b/x-pack/plugins/alerting/server/task_runner/task_runner.ts index d5aaacbacc16a3..340ef186b2730d 100644 --- a/x-pack/plugins/alerting/server/task_runner/task_runner.ts +++ b/x-pack/plugins/alerting/server/task_runner/task_runner.ts @@ -13,7 +13,7 @@ import { KibanaRequest, Logger } from '@kbn/core/server'; import { ConcreteTaskInstance, throwUnrecoverableError } from '@kbn/task-manager-plugin/server'; import { nanosToMillis } from '@kbn/event-log-plugin/server'; import { TaskRunnerContext } from './task_runner_factory'; -import { createExecutionHandler, ExecutionHandler } from './create_execution_handler'; +import { createExecutionHandler } from './create_execution_handler'; import { Alert, createAlertFactory } from '../alert'; import { ElasticsearchError, @@ -58,7 +58,6 @@ import { InMemoryMetrics, IN_MEMORY_METRICS } from '../monitoring'; import { RuleTaskInstance, RuleTaskRunResult, - ScheduleActionsForRecoveredAlertsParams, RuleRunResult, RuleTaskStateAndMetrics, } from './types'; @@ -70,6 +69,7 @@ import { AlertingEventLogger } from '../lib/alerting_event_logger/alerting_event import { SearchMetrics } from '../lib/types'; import { loadRule } from './rule_loader'; import { logAlerts } from './log_alerts'; +import { scheduleActionsForAlerts } from './schedule_actions_for_alerts'; const FALLBACK_RETRY_INTERVAL = '5m'; const CONNECTIVITY_RETRY_INTERVAL = '5m'; @@ -224,34 +224,6 @@ export class TaskRunner< } } - private async executeAlert( - alertId: string, - alert: Alert, - executionHandler: ExecutionHandler, - ruleRunMetricsStore: RuleRunMetricsStore - ) { - if (alert.hasScheduledActions()) { - const { - actionGroup, - subgroup: actionSubgroup, - context, - state, - } = alert.getScheduledActionOptions()!; - alert.updateLastScheduledActions(actionGroup, actionSubgroup); - alert.unscheduleActions(); - return executionHandler({ - actionGroup, - actionSubgroup, - context, - state, - alertId, - ruleRunMetricsStore, - }); - } - - return Promise.resolve(); - } - private async executeRule( fakeRequest: KibanaRequest, rulesClient: RulesClientApi, @@ -468,41 +440,8 @@ export class TaskRunner< if (!ruleIsSnoozed && this.shouldLogAndScheduleActionsForAlerts()) { const mutedAlertIdsSet = new Set(mutedInstanceIds); - const alertsWithExecutableActions = Object.entries(activeAlerts).filter( - ([alertName, alert]: [string, Alert]) => { - const throttled = alert.isThrottled(throttle); - const muted = mutedAlertIdsSet.has(alertName); - let shouldExecuteAction = true; - - if (throttled || muted) { - shouldExecuteAction = false; - this.logger.debug( - `skipping scheduling of actions for '${alertName}' in rule ${ruleLabel}: rule is ${ - muted ? 'muted' : 'throttled' - }` - ); - } else if ( - notifyWhen === 'onActionGroupChange' && - !alert.scheduledActionGroupOrSubgroupHasChanged() - ) { - shouldExecuteAction = false; - this.logger.debug( - `skipping scheduling of actions for '${alertName}' in rule ${ruleLabel}: alert is active but action group has not changed` - ); - } - - return shouldExecuteAction; - } - ); - - await Promise.all( - alertsWithExecutableActions.map( - ([alertId, alert]: [string, Alert]) => - this.executeAlert(alertId, alert, executionHandler, ruleRunMetricsStore) - ) - ); - - await scheduleActionsForRecoveredAlerts({ + await scheduleActionsForAlerts({ + activeAlerts, recoveryActionGroup: this.ruleType.recoveryActionGroup, recoveredAlerts, executionHandler, @@ -510,6 +449,8 @@ export class TaskRunner< logger: this.logger, ruleLabel, ruleRunMetricsStore, + throttle, + notifyWhen, }); } else { if (ruleIsSnoozed) { @@ -809,49 +750,6 @@ export class TaskRunner< } } -async function scheduleActionsForRecoveredAlerts< - InstanceState extends AlertInstanceState, - InstanceContext extends AlertInstanceContext, - RecoveryActionGroupId extends string ->( - params: ScheduleActionsForRecoveredAlertsParams< - InstanceState, - InstanceContext, - RecoveryActionGroupId - > -): Promise { - const { - logger, - recoveryActionGroup, - recoveredAlerts, - executionHandler, - mutedAlertIdsSet, - ruleLabel, - ruleRunMetricsStore, - } = params; - const recoveredIds = Object.keys(recoveredAlerts); - - for (const id of recoveredIds) { - if (mutedAlertIdsSet.has(id)) { - logger.debug( - `skipping scheduling of actions for '${id}' in rule ${ruleLabel}: instance is muted` - ); - } else { - const alert = recoveredAlerts[id]; - alert.updateLastScheduledActions(recoveryActionGroup.id); - alert.unscheduleActions(); - await executionHandler({ - actionGroup: recoveryActionGroup.id, - context: alert.getContext(), - state: {}, - alertId: id, - ruleRunMetricsStore, - }); - alert.scheduleActions(recoveryActionGroup.id); - } - } -} - /** * If an error is thrown, wrap it in an RuleTaskRunResult * so that we can treat each field independantly diff --git a/x-pack/plugins/alerting/server/task_runner/types.ts b/x-pack/plugins/alerting/server/task_runner/types.ts index 839e0ca2290526..9538b3e20a9d9f 100644 --- a/x-pack/plugins/alerting/server/task_runner/types.ts +++ b/x-pack/plugins/alerting/server/task_runner/types.ts @@ -48,18 +48,22 @@ export interface RuleTaskInstance extends ConcreteTaskInstance { state: RuleTaskState; } -export interface ScheduleActionsForRecoveredAlertsParams< +export interface ScheduleActionsForAlertsParams< InstanceState extends AlertInstanceState, InstanceContext extends AlertInstanceContext, + ActionGroupIds extends string, RecoveryActionGroupId extends string > { logger: Logger; recoveryActionGroup: ActionGroup; recoveredAlerts: Record>; - executionHandler: ExecutionHandler; + executionHandler: ExecutionHandler; mutedAlertIdsSet: Set; ruleLabel: string; ruleRunMetricsStore: RuleRunMetricsStore; + activeAlerts: Record>; + throttle: string | null; + notifyWhen: string | null; } // / ExecutionHandler diff --git a/x-pack/plugins/apm/dev_docs/local_setup.md b/x-pack/plugins/apm/dev_docs/local_setup.md index 24a8db44a3cce0..9f3553f3c680c0 100644 --- a/x-pack/plugins/apm/dev_docs/local_setup.md +++ b/x-pack/plugins/apm/dev_docs/local_setup.md @@ -44,7 +44,7 @@ elasticsearch.username: kibana_system elasticsearch.password: changeme ``` -Documentation for [Synthtrace](https://github.com/elastic/kibana/blob/main/packages/elastic-apm-synthtrace/README.md) +Documentation for [Synthtrace](https://github.com/elastic/kibana/blob/main/packages/kbn-apm-synthtrace/README.md) ## 2. Cloud-based ES Cluster (internal devs only) diff --git a/x-pack/plugins/apm/dev_docs/testing.md b/x-pack/plugins/apm/dev_docs/testing.md index b3eabc27a515b6..c204a3922139fe 100644 --- a/x-pack/plugins/apm/dev_docs/testing.md +++ b/x-pack/plugins/apm/dev_docs/testing.md @@ -63,7 +63,7 @@ node scripts/test/api --runner --basic --updateSnapshots **API Test tips** -- For data generation in API tests have a look at the [elastic-apm-synthtrace](../../../../packages/elastic-apm-synthtrace/README.md) package +- For data generation in API tests have a look at the [kbn-apm-synthtrace](../../../../packages/kbn-apm-synthtrace/README.md) package - For debugging access Elasticsearch on http://localhost:9220 and Kibana on http://localhost:5620 (`elastic` / `changeme`) --- @@ -124,4 +124,4 @@ All files with a .stories.tsx extension will be loaded. You can access the devel For end-to-end (e.g. agent -> apm server -> elasticsearch <- kibana) development and testing of Elastic APM please check the the [APM Integration Testing repository](https://github.com/elastic/apm-integration-testing). -Data can also be generated using the [elastic-apm-synthtrace](../../../../packages/elastic-apm-synthtrace/README.md) CLI. +Data can also be generated using the [kbn-apm-synthtrace](../../../../packages/kbn-apm-synthtrace/README.md) CLI. diff --git a/x-pack/plugins/apm/ftr_e2e/cypress.json b/x-pack/plugins/apm/ftr_e2e/cypress.json index 1791baaa5aae49..848a10efed6682 100644 --- a/x-pack/plugins/apm/ftr_e2e/cypress.json +++ b/x-pack/plugins/apm/ftr_e2e/cypress.json @@ -6,11 +6,14 @@ "screenshotsFolder": "./cypress/screenshots", "supportFile": "./cypress/support/index.ts", "videosFolder": "./cypress/videos", + "requestTimeout": 10000, + "responseTimeout": 40000, "defaultCommandTimeout": 30000, "execTimeout": 120000, "pageLoadTimeout": 120000, "viewportHeight": 900, "viewportWidth": 1440, "video": false, - "screenshotOnRunFailure": false + "screenshotOnRunFailure": false, + "experimentalSessionAndOrigin": true } diff --git a/x-pack/plugins/apm/ftr_e2e/cypress/fixtures/synthtrace/opbeans.ts b/x-pack/plugins/apm/ftr_e2e/cypress/fixtures/synthtrace/opbeans.ts index 1d0155bf9b4347..1be9873d25c4f5 100644 --- a/x-pack/plugins/apm/ftr_e2e/cypress/fixtures/synthtrace/opbeans.ts +++ b/x-pack/plugins/apm/ftr_e2e/cypress/fixtures/synthtrace/opbeans.ts @@ -4,7 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { apm, timerange } from '@elastic/apm-synthtrace'; +import { apm, timerange } from '@kbn/apm-synthtrace'; export function opbeans({ from, to }: { from: number; to: number }) { const range = timerange(from, to); diff --git a/x-pack/plugins/apm/ftr_e2e/cypress/integration/power_user/feature_flag/comparison.spec.ts b/x-pack/plugins/apm/ftr_e2e/cypress/integration/power_user/feature_flag/comparison.spec.ts index d3ac4cc0e095f3..d1159efd0fc90c 100644 --- a/x-pack/plugins/apm/ftr_e2e/cypress/integration/power_user/feature_flag/comparison.spec.ts +++ b/x-pack/plugins/apm/ftr_e2e/cypress/integration/power_user/feature_flag/comparison.spec.ts @@ -11,8 +11,8 @@ import { opbeans } from '../../../fixtures/synthtrace/opbeans'; const start = '2021-10-10T00:00:00.000Z'; const end = '2021-10-10T00:15:00.000Z'; describe('Comparison feature flag', () => { - before(async () => { - await synthtrace.index( + before(() => { + synthtrace.index( opbeans({ from: new Date(start).getTime(), to: new Date(end).getTime(), @@ -20,29 +20,33 @@ describe('Comparison feature flag', () => { ); }); - after(async () => { - await synthtrace.clean(); + after(() => { + synthtrace.clean(); }); describe('when comparison feature is enabled', () => { beforeEach(() => { cy.loginAsEditorUser(); + + cy.updateAdvancedSettings({ + 'observability:enableComparisonByDefault': true, + }); }); it('shows the comparison feature enabled in services overview', () => { - cy.visit('/app/apm/services'); + cy.visitKibana('/app/apm/services'); cy.get('input[type="checkbox"]#comparison').should('be.checked'); cy.get('[data-test-subj="comparisonSelect"]').should('not.be.disabled'); }); - it('shows the comparison feature enabled in services overview', () => { - cy.visit('/app/apm/dependencies'); + it('shows the comparison feature enabled in dependencies overview', () => { + cy.visitKibana('/app/apm/dependencies'); cy.get('input[type="checkbox"]#comparison').should('be.checked'); cy.get('[data-test-subj="comparisonSelect"]').should('not.be.disabled'); }); it('shows the comparison feature disabled in service map overview page', () => { - cy.visit('/app/apm/service-map'); + cy.visitKibana('/app/apm/service-map'); cy.get('input[type="checkbox"]#comparison').should('be.checked'); cy.get('[data-test-subj="comparisonSelect"]').should('not.be.disabled'); }); @@ -50,11 +54,11 @@ describe('Comparison feature flag', () => { describe('when comparison feature is disabled', () => { beforeEach(() => { - cy.loginAsEditorUser().then(() => { - // Disables comparison feature on advanced settings - cy.updateAdvancedSettings({ - 'observability:enableComparisonByDefault': false, - }); + cy.loginAsEditorUser(); + + // Disables comparison feature on advanced settings + cy.updateAdvancedSettings({ + 'observability:enableComparisonByDefault': false, }); }); @@ -65,7 +69,7 @@ describe('Comparison feature flag', () => { }); it('shows the comparison feature disabled in services overview', () => { - cy.visit('/app/apm/services'); + cy.visitKibana('/app/apm/services'); cy.get('input[type="checkbox"]#comparison').should('not.be.checked'); cy.get('[data-test-subj="comparisonSelect"]').should('be.disabled'); }); @@ -74,14 +78,14 @@ describe('Comparison feature flag', () => { cy.intercept('GET', '/internal/apm/dependencies/top_dependencies?*').as( 'topDependenciesRequest' ); - cy.visit('/app/apm/dependencies'); - cy.wait('@topDependenciesRequest', { requestTimeout: 10000 }); + cy.visitKibana('/app/apm/dependencies'); + cy.wait('@topDependenciesRequest'); cy.get('input[type="checkbox"]#comparison').should('not.be.checked'); cy.get('[data-test-subj="comparisonSelect"]').should('be.disabled'); }); it('shows the comparison feature disabled in service map overview page', () => { - cy.visit('/app/apm/service-map'); + cy.visitKibana('/app/apm/service-map'); cy.get('input[type="checkbox"]#comparison').should('not.be.checked'); cy.get('[data-test-subj="comparisonSelect"]').should('be.disabled'); }); diff --git a/x-pack/plugins/apm/ftr_e2e/cypress/integration/power_user/feature_flag/infrastructure.spec.ts b/x-pack/plugins/apm/ftr_e2e/cypress/integration/power_user/feature_flag/infrastructure.spec.ts deleted file mode 100644 index 99178c810067ef..00000000000000 --- a/x-pack/plugins/apm/ftr_e2e/cypress/integration/power_user/feature_flag/infrastructure.spec.ts +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { synthtrace } from '../../../../synthtrace'; -import { opbeans } from '../../../fixtures/synthtrace/opbeans'; - -const serviceOverviewPath = '/app/apm/services/opbeans-python/overview'; - -const start = '2021-10-10T00:00:00.000Z'; -const end = '2021-10-10T00:15:00.000Z'; - -describe('Infrastracture feature flag', () => { - before(async () => { - await synthtrace.index( - opbeans({ - from: new Date(start).getTime(), - to: new Date(end).getTime(), - }) - ); - }); - - after(async () => { - await synthtrace.clean(); - }); - - describe('when infrastracture feature is enabled', () => { - beforeEach(() => { - cy.loginAsEditorUser().then(() => { - // enables infrastructure view feature on advanced settings - cy.updateAdvancedSettings({ - 'observability:enableInfrastructureView': true, - }); - }); - }); - - it('shows infrastructure tab in service overview page', () => { - cy.visit(serviceOverviewPath); - cy.contains('a[role="tab"]', 'Infrastructure'); - }); - }); - - describe('when infrastracture feature is disabled', () => { - beforeEach(() => { - cy.loginAsEditorUser().then(() => { - // enables infrastructure view feature on advanced settings - cy.updateAdvancedSettings({ - 'observability:enableInfrastructureView': false, - }); - }); - }); - - it('hides infrastructure tab in service overview page', () => { - cy.visit(serviceOverviewPath); - cy.contains('a[role="tab"]', 'Infrastructure').should('not.exist'); - }); - }); -}); diff --git a/x-pack/plugins/apm/ftr_e2e/cypress/integration/power_user/infrastructure/generate_data.ts b/x-pack/plugins/apm/ftr_e2e/cypress/integration/power_user/infrastructure/generate_data.ts index 13998757914179..52cf6b988f1a1d 100644 --- a/x-pack/plugins/apm/ftr_e2e/cypress/integration/power_user/infrastructure/generate_data.ts +++ b/x-pack/plugins/apm/ftr_e2e/cypress/integration/power_user/infrastructure/generate_data.ts @@ -4,7 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { apm, timerange } from '@elastic/apm-synthtrace'; +import { apm, timerange } from '@kbn/apm-synthtrace'; export function generateData({ from, to }: { from: number; to: number }) { const range = timerange(from, to); diff --git a/x-pack/plugins/apm/ftr_e2e/cypress/integration/power_user/infrastructure/infrastructure_page.spec.ts b/x-pack/plugins/apm/ftr_e2e/cypress/integration/power_user/infrastructure/infrastructure_page.spec.ts index 65f76f7cfd95ce..439b95a796b712 100644 --- a/x-pack/plugins/apm/ftr_e2e/cypress/integration/power_user/infrastructure/infrastructure_page.spec.ts +++ b/x-pack/plugins/apm/ftr_e2e/cypress/integration/power_user/infrastructure/infrastructure_page.spec.ts @@ -28,8 +28,8 @@ const nodeServiceInfraPageHref = url.format({ }); describe('Infrastructure page', () => { - before(async () => { - await synthtrace.index( + before(() => { + synthtrace.index( generateData({ from: new Date(start).getTime(), to: new Date(end).getTime(), @@ -37,8 +37,8 @@ describe('Infrastructure page', () => { ); }); - after(async () => { - await synthtrace.clean(); + after(() => { + synthtrace.clean(); }); beforeEach(() => { @@ -47,7 +47,7 @@ describe('Infrastructure page', () => { describe('when data is loaded', () => { it('has no detectable a11y violations on load', () => { - cy.visit(goServiceInfraPageHref); + cy.visitKibana(goServiceInfraPageHref); cy.contains('Infrastructure'); // set skipFailures to true to not fail the test when there are accessibility failures checkA11y({ skipFailures: true }); @@ -55,7 +55,7 @@ describe('Infrastructure page', () => { describe('when container ids, pod names and host names are returned by the api call', () => { it('shows all tabs', () => { - cy.visit(goServiceInfraPageHref); + cy.visitKibana(goServiceInfraPageHref); cy.contains('Containers'); cy.contains('Pods'); cy.contains('Hosts'); @@ -64,14 +64,14 @@ describe('Infrastructure page', () => { describe('when only host names are returned by the api call', () => { it('shows only Hosts tab', () => { - cy.visit(javaServiceInfraPageHref); + cy.visitKibana(javaServiceInfraPageHref); cy.contains('Hosts'); }); }); describe('when none infrastructure attributes are returned by the api call', () => { it('shows no data message', () => { - cy.visit(nodeServiceInfraPageHref); + cy.visitKibana(nodeServiceInfraPageHref); cy.contains('No results match your search criteria.'); }); }); diff --git a/x-pack/plugins/apm/ftr_e2e/cypress/integration/power_user/integration_settings/integration_policy.spec.ts b/x-pack/plugins/apm/ftr_e2e/cypress/integration/power_user/integration_settings/integration_policy.spec.ts index 655376eb3eb634..7b97813cb12195 100644 --- a/x-pack/plugins/apm/ftr_e2e/cypress/integration/power_user/integration_settings/integration_policy.spec.ts +++ b/x-pack/plugins/apm/ftr_e2e/cypress/integration/power_user/integration_settings/integration_policy.spec.ts @@ -57,7 +57,7 @@ describe.skip('when navigating to integration page', () => { const integrationsPath = '/app/integrations/browse'; cy.loginAsEditorUser(); - cy.visit(integrationsPath); + cy.visitKibana(integrationsPath); // open integration policy form cy.get('[data-test-subj="integration-card:epr:apm:featured').click(); @@ -79,17 +79,17 @@ describe.skip('when navigating to integration page', () => { }); it('should display Tail-based section on latest version', () => { - cy.visit('/app/fleet/integrations/apm/add-integration'); + cy.visitKibana('/app/fleet/integrations/apm/add-integration'); cy.contains('Tail-based sampling').should('exist'); }); it('should hide Tail-based section for 8.0.0 apm package', () => { - cy.visit('/app/fleet/integrations/apm-8.0.0/add-integration'); + cy.visitKibana('/app/fleet/integrations/apm-8.0.0/add-integration'); cy.contains('Tail-based sampling').should('not.exist'); }); it('should Display Debug section', () => { - cy.visit('/app/fleet/integrations/apm-8.0.0/add-integration'); + cy.visitKibana('/app/fleet/integrations/apm-8.0.0/add-integration'); cy.contains('Debug settings').should('exist'); }); }); diff --git a/x-pack/plugins/apm/ftr_e2e/cypress/integration/power_user/no_data_screen.ts b/x-pack/plugins/apm/ftr_e2e/cypress/integration/power_user/no_data_screen.ts index c7f33301a5dfc3..ae08bc1ea9b63e 100644 --- a/x-pack/plugins/apm/ftr_e2e/cypress/integration/power_user/no_data_screen.ts +++ b/x-pack/plugins/apm/ftr_e2e/cypress/integration/power_user/no_data_screen.ts @@ -5,60 +5,55 @@ * 2.0. */ -const apmIndicesSaveURL = '/internal/apm/settings/apm-indices/save'; - describe('No data screen', () => { describe('bypass no data screen on settings pages', () => { - beforeEach(() => { - cy.loginAsEditorUser(); - }); - before(() => { - // Change default indices - cy.request({ - url: apmIndicesSaveURL, - method: 'POST', - body: { - sourcemap: 'foo-*', - error: 'foo-*', - onboarding: 'foo-*', - span: 'foo-*', - transaction: 'foo-*', - metric: 'foo-*', - }, - headers: { - 'kbn-xsrf': true, - }, - auth: { user: 'editor', pass: 'changeme' }, + // Change indices + setApmIndices({ + sourcemap: 'foo-*', + error: 'foo-*', + onboarding: 'foo-*', + span: 'foo-*', + transaction: 'foo-*', + metric: 'foo-*', }); }); + beforeEach(() => { + cy.loginAsEditorUser(); + }); + it('shows no data screen instead of service inventory', () => { - cy.visit('/app/apm/'); + cy.visitKibana('/app/apm/'); cy.contains('Welcome to Elastic Observability!'); }); + it('shows settings page', () => { - cy.visit('/app/apm/settings'); + cy.visitKibana('/app/apm/settings'); cy.contains('Welcome to Elastic Observability!').should('not.exist'); cy.get('h1').contains('Settings'); }); after(() => { // reset to default indices - cy.request({ - url: apmIndicesSaveURL, - method: 'POST', - body: { - sourcemap: '', - error: '', - onboarding: '', - span: '', - transaction: '', - metric: '', - }, - headers: { 'kbn-xsrf': true }, - auth: { user: 'editor', pass: 'changeme' }, + setApmIndices({ + sourcemap: '', + error: '', + onboarding: '', + span: '', + transaction: '', + metric: '', }); }); }); }); + +function setApmIndices(body: Record) { + cy.request({ + url: '/internal/apm/settings/apm-indices/save', + method: 'POST', + body, + headers: { 'kbn-xsrf': true }, + auth: { user: 'editor', pass: 'changeme' }, + }); +} diff --git a/x-pack/plugins/apm/ftr_e2e/cypress/integration/power_user/rules/error_count.spec.ts b/x-pack/plugins/apm/ftr_e2e/cypress/integration/power_user/rules/error_count.spec.ts index b145369535225c..ec01fc2df2da30 100644 --- a/x-pack/plugins/apm/ftr_e2e/cypress/integration/power_user/rules/error_count.spec.ts +++ b/x-pack/plugins/apm/ftr_e2e/cypress/integration/power_user/rules/error_count.spec.ts @@ -6,10 +6,12 @@ */ function deleteAllRules() { + cy.log('Delete all rules'); cy.request({ log: false, method: 'GET', url: '/api/alerting/rules/_find', + auth: { user: 'editor', pass: 'changeme' }, }).then(({ body }) => { if (body.data.length > 0) { cy.log(`Deleting rules`); @@ -21,12 +23,21 @@ function deleteAllRules() { log: false, method: 'DELETE', url: `/api/alerting/rule/${id}`, + auth: { user: 'editor', pass: 'changeme' }, }); }); }); } describe('Rules', () => { + beforeEach(() => { + deleteAllRules(); + }); + + after(() => { + deleteAllRules(); + }); + describe('Error count', () => { const ruleName = 'Error count threshold'; const comboBoxInputSelector = @@ -36,18 +47,11 @@ describe('Rules', () => { describe('when created from APM', () => { describe('when created from Service Inventory', () => { - before(() => { + it('creates a rule', () => { cy.loginAsEditorUser(); - deleteAllRules(); - }); - - after(() => { - deleteAllRules(); - }); - it('creates a rule', () => { // Create a rule in APM - cy.visit('/app/apm/services'); + cy.visitKibana('/app/apm/services'); cy.contains('Alerts and rules').click(); cy.contains('Create error count rule').click(); @@ -67,18 +71,13 @@ describe('Rules', () => { }); describe('when created from Stack management', () => { - before(() => { + it('creates a rule', () => { cy.loginAsEditorUser(); - deleteAllRules(); - }); - after(() => { - deleteAllRules(); - }); - - it('creates a rule', () => { // Go to stack management - cy.visit('/app/management/insightsAndAlerting/triggersActions/rules'); + cy.visitKibana( + '/app/management/insightsAndAlerting/triggersActions/rules' + ); // Create a rule cy.contains('button', 'Create rule').click(); diff --git a/x-pack/plugins/apm/ftr_e2e/cypress/integration/power_user/settings/agent_configurations.spec.ts b/x-pack/plugins/apm/ftr_e2e/cypress/integration/power_user/settings/agent_configurations.spec.ts index 4661ea67ae2ab4..23154492c9f441 100644 --- a/x-pack/plugins/apm/ftr_e2e/cypress/integration/power_user/settings/agent_configurations.spec.ts +++ b/x-pack/plugins/apm/ftr_e2e/cypress/integration/power_user/settings/agent_configurations.spec.ts @@ -4,7 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { apm, timerange } from '@elastic/apm-synthtrace'; +import { apm, timerange } from '@kbn/apm-synthtrace'; import url from 'url'; import { synthtrace } from '../../../../synthtrace'; @@ -55,10 +55,10 @@ function generateData({ } describe('Agent configuration', () => { - before(async () => { + before(() => { const { rangeFrom, rangeTo } = timeRange; - await synthtrace.index( + synthtrace.index( generateData({ from: new Date(rangeFrom).getTime(), to: new Date(rangeTo).getTime(), @@ -67,13 +67,13 @@ describe('Agent configuration', () => { ); }); - after(async () => { - await synthtrace.clean(); + after(() => { + synthtrace.clean(); }); beforeEach(() => { cy.loginAsEditorUser(); - cy.visit(agentConfigHref); + cy.visitKibana(agentConfigHref); }); it('persists service enviroment when clicking on edit button', () => { diff --git a/x-pack/plugins/apm/ftr_e2e/cypress/integration/power_user/settings/custom_links.spec.ts b/x-pack/plugins/apm/ftr_e2e/cypress/integration/power_user/settings/custom_links.spec.ts index e5c409cb6da0d2..53dbb82c1c6ae2 100644 --- a/x-pack/plugins/apm/ftr_e2e/cypress/integration/power_user/settings/custom_links.spec.ts +++ b/x-pack/plugins/apm/ftr_e2e/cypress/integration/power_user/settings/custom_links.spec.ts @@ -13,13 +13,13 @@ describe('Custom links', () => { }); it('shows empty message and create button', () => { - cy.visit(basePath); + cy.visitKibana(basePath); cy.contains('No links found'); cy.contains('Create custom link'); }); it('creates custom link', () => { - cy.visit(basePath); + cy.visitKibana(basePath); const emptyPrompt = cy.get('[data-test-subj="customLinksEmptyPrompt"]'); cy.contains('Create custom link').click(); cy.contains('Create link'); @@ -36,7 +36,7 @@ describe('Custom links', () => { }); it('clears filter values when field is selected', () => { - cy.visit(basePath); + cy.visitKibana(basePath); cy.contains('Create custom link').click(); cy.get('[data-test-subj="filter-0"]').select('service.name'); cy.get( diff --git a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/deep_links.spec.ts b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/deep_links.spec.ts index 76c43ef03f3322..cfcabe85b5b2a7 100644 --- a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/deep_links.spec.ts +++ b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/deep_links.spec.ts @@ -6,11 +6,11 @@ */ describe('APM deep links', () => { - before(() => { + beforeEach(() => { cy.loginAsViewerUser(); }); it('navigates to apm links on search elastic', () => { - cy.visit('/'); + cy.visitKibana('/'); cy.get('[data-test-subj="nav-search-input"]').type('APM'); cy.contains('APM'); cy.contains('APM / Services'); diff --git a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/dependencies.spec.ts b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/dependencies.spec.ts index 8042a1a07f8a2e..e3746489936ab8 100644 --- a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/dependencies.spec.ts +++ b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/dependencies.spec.ts @@ -17,8 +17,8 @@ const timeRange = { }; describe.skip('Dependencies', () => { - before(async () => { - await synthtrace.index( + before(() => { + synthtrace.index( opbeans({ from: new Date(start).getTime(), to: new Date(end).getTime(), @@ -26,8 +26,8 @@ describe.skip('Dependencies', () => { ); }); - after(async () => { - await synthtrace.clean(); + after(() => { + synthtrace.clean(); }); beforeEach(() => { @@ -36,7 +36,7 @@ describe.skip('Dependencies', () => { describe('top-level dependencies page', () => { it('has a list of dependencies and you can navigate to the page for one', () => { - cy.visit(`/app/apm/services?${new URLSearchParams(timeRange)}`); + cy.visitKibana(`/app/apm/services?${new URLSearchParams(timeRange)}`); cy.contains('nav a', 'Dependencies').click(); // `force: true` because Cypress says the element is 0x0 @@ -46,7 +46,7 @@ describe.skip('Dependencies', () => { }); it('has no detectable a11y violations on load', () => { - cy.visit( + cy.visitKibana( `/app/apm/services/opbeans-java/dependencies?${new URLSearchParams( timeRange )}` @@ -59,7 +59,7 @@ describe.skip('Dependencies', () => { describe.skip('dependency overview page', () => { it('shows dependency information and you can navigate to a page for an upstream service', () => { - cy.visit( + cy.visitKibana( `/app/apm/dependencies/overview?${new URLSearchParams({ ...timeRange, dependencyName: 'postgresql', @@ -76,7 +76,7 @@ describe.skip('Dependencies', () => { }); it('has no detectable a11y violations on load', () => { - cy.visit( + cy.visitKibana( `/app/apm/dependencies/overview?${new URLSearchParams({ ...timeRange, dependencyName: 'postgresql', @@ -90,7 +90,7 @@ describe.skip('Dependencies', () => { describe('service overview page', () => { it('shows dependency information and you can navigate to a page for a dependency', () => { - cy.visit( + cy.visitKibana( `/app/apm/services/opbeans-java/overview?${new URLSearchParams( timeRange )}` @@ -104,7 +104,7 @@ describe.skip('Dependencies', () => { describe('service dependencies tab', () => { it('shows dependency information and you can navigate to a page for a dependency', () => { - cy.visit( + cy.visitKibana( `/app/apm/services/opbeans-java/overview?${new URLSearchParams( timeRange )}` diff --git a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/errors/error_details.spec.ts b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/errors/error_details.spec.ts index 59c0d870295179..28b3068503644b 100644 --- a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/errors/error_details.spec.ts +++ b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/errors/error_details.spec.ts @@ -27,8 +27,8 @@ describe('Error details', () => { }); describe('when data is loaded', () => { - before(async () => { - await synthtrace.index( + before(() => { + synthtrace.index( generateData({ from: new Date(start).getTime(), to: new Date(end).getTime(), @@ -36,12 +36,12 @@ describe('Error details', () => { ); }); - after(async () => { - await synthtrace.clean(); + after(() => { + synthtrace.clean(); }); it('has no detectable a11y violations on load', () => { - cy.visit(errorDetailsPageHref); + cy.visitKibana(errorDetailsPageHref); cy.contains('Error group 00000'); // set skipFailures to true to not fail the test when there are accessibility failures checkA11y({ skipFailures: true }); @@ -49,7 +49,7 @@ describe('Error details', () => { describe('when error has no occurrences', () => { it('shows an empty message', () => { - cy.visit( + cy.visitKibana( url.format({ pathname: '/app/apm/services/opbeans-java/errors/0000000000000000000000000Error%201', @@ -66,13 +66,13 @@ describe('Error details', () => { describe('when error has data', () => { it('shows errors distribution chart', () => { - cy.visit(errorDetailsPageHref); + cy.visitKibana(errorDetailsPageHref); cy.contains('Error group 00000'); cy.get('[data-test-subj="errorDistribution"]').contains('Occurrences'); }); it('shows top erroneous transactions table', () => { - cy.visit(errorDetailsPageHref); + cy.visitKibana(errorDetailsPageHref); cy.contains('Top 5 affected transactions'); cy.get('[data-test-subj="topErroneousTransactionsTable"]') .contains('a', 'GET /apple 🍎') @@ -81,14 +81,14 @@ describe('Error details', () => { }); it('shows a Stacktrace and Metadata tabs', () => { - cy.visit(errorDetailsPageHref); + cy.visitKibana(errorDetailsPageHref); cy.contains('button', 'Exception stack trace'); cy.contains('button', 'Metadata'); }); describe('when clicking on related transaction sample', () => { it('should redirects to the transaction details page', () => { - cy.visit(errorDetailsPageHref); + cy.visitKibana(errorDetailsPageHref); cy.contains('Error group 00000'); cy.contains('a', 'GET /apple 🍎').click(); cy.url().should('include', 'opbeans-java/transactions/view'); @@ -97,7 +97,7 @@ describe('Error details', () => { describe('when clicking on View x occurences in discover', () => { it.skip('should redirects the user to discover', () => { - cy.visit(errorDetailsPageHref); + cy.visitKibana(errorDetailsPageHref); cy.contains('View 1 occurrence in Discover').click(); cy.url().should('include', 'app/discover'); }); diff --git a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/errors/errors_page.spec.ts b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/errors/errors_page.spec.ts index b000a3a8c2f3f4..301b3384ee2eb8 100644 --- a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/errors/errors_page.spec.ts +++ b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/errors/errors_page.spec.ts @@ -29,8 +29,8 @@ describe('Errors page', () => { }); describe('when data is loaded', () => { - before(async () => { - await synthtrace.index( + before(() => { + synthtrace.index( generateData({ from: new Date(start).getTime(), to: new Date(end).getTime(), @@ -38,12 +38,12 @@ describe('Errors page', () => { ); }); - after(async () => { - await synthtrace.clean(); + after(() => { + synthtrace.clean(); }); it('has no detectable a11y violations on load', () => { - cy.visit(javaServiceErrorsPageHref); + cy.visitKibana(javaServiceErrorsPageHref); cy.contains('Error occurrences'); // set skipFailures to true to not fail the test when there are accessibility failures checkA11y({ skipFailures: true }); @@ -51,7 +51,7 @@ describe('Errors page', () => { describe('when service has no errors', () => { it('shows empty message', () => { - cy.visit(nodeServiceErrorsPageHref); + cy.visitKibana(nodeServiceErrorsPageHref); cy.contains('opbeans-node'); cy.contains('No errors found'); }); @@ -59,28 +59,28 @@ describe('Errors page', () => { describe('when service has errors', () => { it('shows errors distribution chart', () => { - cy.visit(javaServiceErrorsPageHref); + cy.visitKibana(javaServiceErrorsPageHref); cy.contains('Error occurrences'); }); it('shows failed transaction rate chart', () => { - cy.visit(javaServiceErrorsPageHref); + cy.visitKibana(javaServiceErrorsPageHref); cy.contains('Failed transaction rate'); }); it('errors table is populated', () => { - cy.visit(javaServiceErrorsPageHref); + cy.visitKibana(javaServiceErrorsPageHref); cy.contains('Error 0'); }); it('clicking on an error in the list navigates to error detail page', () => { - cy.visit(javaServiceErrorsPageHref); + cy.visitKibana(javaServiceErrorsPageHref); cy.contains('a', 'Error 1').click(); cy.contains('div', 'Error 1'); }); it('clicking on type adds a filter in the kuerybar', () => { - cy.visit(javaServiceErrorsPageHref); + cy.visitKibana(javaServiceErrorsPageHref); cy.get('[data-test-subj="headerFilterKuerybar"]') .invoke('val') .should('be.empty'); @@ -97,13 +97,13 @@ describe('Errors page', () => { }); it('sorts by ocurrences', () => { - cy.visit(javaServiceErrorsPageHref); + cy.visitKibana(javaServiceErrorsPageHref); cy.contains('span', 'Occurrences').click(); cy.url().should('include', '&sortField=occurrences&sortDirection=asc'); }); it('sorts by latest occurrences', () => { - cy.visit(javaServiceErrorsPageHref); + cy.visitKibana(javaServiceErrorsPageHref); cy.contains('span', 'Last seen').click(); cy.url().should('include', '&sortField=lastSeen&sortDirection=asc'); }); @@ -112,9 +112,8 @@ describe('Errors page', () => { }); describe('Check detailed statistics API with multiple errors', () => { - before(async () => { - cy.loginAsViewerUser(); - await synthtrace.index( + before(() => { + synthtrace.index( generateErrors({ from: new Date(start).getTime(), to: new Date(end).getTime(), @@ -123,8 +122,12 @@ describe('Check detailed statistics API with multiple errors', () => { ); }); - after(async () => { - await synthtrace.clean(); + beforeEach(() => { + cy.loginAsViewerUser(); + }); + + after(() => { + synthtrace.clean(); }); it('calls detailed API with visible items only', () => { @@ -136,7 +139,7 @@ describe('Check detailed statistics API with multiple errors', () => { 'POST', '/internal/apm/services/opbeans-java/errors/groups/detailed_statistics?*' ).as('errorsDetailedStatistics'); - cy.visit(`${javaServiceErrorsPageHref}&pageSize=10`); + cy.visitKibana(`${javaServiceErrorsPageHref}&pageSize=10`); cy.wait('@errorsMainStatistics'); cy.get('.euiPagination__list').children().should('have.length', 5); cy.wait('@errorsDetailedStatistics').then((payload) => { diff --git a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/errors/generate_data.ts b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/errors/generate_data.ts index 66a70428b22758..56978f03123a81 100644 --- a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/errors/generate_data.ts +++ b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/errors/generate_data.ts @@ -4,7 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { apm, timerange } from '@elastic/apm-synthtrace'; +import { apm, timerange } from '@kbn/apm-synthtrace'; export function generateData({ from, to }: { from: number; to: number }) { const range = timerange(from, to); diff --git a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/home.spec.ts b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/home.spec.ts index 42ca9319b4ea34..be09ae3f06122a 100644 --- a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/home.spec.ts +++ b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/home.spec.ts @@ -24,8 +24,8 @@ const serviceInventoryHref = url.format({ }); describe.skip('Home page', () => { - before(async () => { - await synthtrace.index( + before(() => { + synthtrace.index( opbeans({ from: new Date(start).getTime(), to: new Date(end).getTime(), @@ -33,8 +33,8 @@ describe.skip('Home page', () => { ); }); - after(async () => { - await synthtrace.clean(); + after(() => { + synthtrace.clean(); }); beforeEach(() => { @@ -42,7 +42,7 @@ describe.skip('Home page', () => { }); it('Redirects to service page with comparisonEnabled, environment, rangeFrom, rangeTo and offset added to the URL', () => { - cy.visit('/app/apm'); + cy.visitKibana('/app/apm'); cy.url().should( 'include', @@ -51,7 +51,7 @@ describe.skip('Home page', () => { }); it('includes services with only metric documents', () => { - cy.visit( + cy.visitKibana( `${serviceInventoryHref}&kuery=not%20(processor.event%3A%22transaction%22)` ); cy.contains('opbeans-java'); @@ -60,7 +60,7 @@ describe.skip('Home page', () => { describe('navigations', () => { it('navigates to service overview page with transaction type', () => { - cy.visit(serviceInventoryHref); + cy.visitKibana(serviceInventoryHref); cy.contains('Services'); cy.contains('opbeans-rum').click({ force: true }); diff --git a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_inventory/generate_data.ts b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_inventory/generate_data.ts index 4fc94d2305b57a..e3cdf7e8bbce88 100644 --- a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_inventory/generate_data.ts +++ b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_inventory/generate_data.ts @@ -4,7 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { apm, timerange } from '@elastic/apm-synthtrace'; +import { apm, timerange } from '@kbn/apm-synthtrace'; export function generateMultipleServicesData({ from, diff --git a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_inventory/header_filters/generate_data.ts b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_inventory/header_filters/generate_data.ts index 94b7ab52f6f702..243f1df257a4f9 100644 --- a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_inventory/header_filters/generate_data.ts +++ b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_inventory/header_filters/generate_data.ts @@ -4,7 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { apm, timerange } from '@elastic/apm-synthtrace'; +import { apm, timerange } from '@kbn/apm-synthtrace'; export function generateData({ from, diff --git a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_inventory/header_filters/header_filters.spec.ts b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_inventory/header_filters/header_filters.spec.ts index 03972eb0d0f207..c4e87ac15fbe19 100644 --- a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_inventory/header_filters/header_filters.spec.ts +++ b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_inventory/header_filters/header_filters.spec.ts @@ -20,8 +20,8 @@ const specialServiceName = 'service 1 / ? # [ ] @ ! $ & ( ) * + , ; = < > % {} | ^ ` <>'; describe('Service inventory - header filters', () => { - before(async () => { - await synthtrace.index( + before(() => { + synthtrace.index( generateData({ from: new Date(start).getTime(), to: new Date(end).getTime(), @@ -30,8 +30,8 @@ describe('Service inventory - header filters', () => { ); }); - after(async () => { - await synthtrace.clean(); + after(() => { + synthtrace.clean(); }); beforeEach(() => { @@ -40,7 +40,7 @@ describe('Service inventory - header filters', () => { describe('Filtering by kuerybar', () => { it('filters by service.name with special characters', () => { - cy.visit(serviceOverviewHref); + cy.visitKibana(serviceOverviewHref); cy.contains('Services'); cy.contains('opbeans-node'); cy.contains('service 1'); diff --git a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_inventory/service_inventory.spec.ts b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_inventory/service_inventory.spec.ts index 6575d015abde2e..5b98284cdf52a1 100644 --- a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_inventory/service_inventory.spec.ts +++ b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_inventory/service_inventory.spec.ts @@ -44,12 +44,9 @@ const mainAliasNames = mainApiRequestsToIntercept.map( ); describe('When navigating to the service inventory', () => { - before(async () => { - cy.loginAsViewerUser(); - cy.visit(serviceInventoryHref); - + before(() => { const { rangeFrom, rangeTo } = timeRange; - await synthtrace.index( + synthtrace.index( opbeans({ from: new Date(rangeFrom).getTime(), to: new Date(rangeTo).getTime(), @@ -57,8 +54,13 @@ describe('When navigating to the service inventory', () => { ); }); - after(async () => { - await synthtrace.clean(); + beforeEach(() => { + cy.loginAsViewerUser(); + cy.visitKibana(serviceInventoryHref); + }); + + after(() => { + synthtrace.clean(); }); it('has no detectable a11y violations on load', () => { @@ -92,7 +94,7 @@ describe('When navigating to the service inventory', () => { ); cy.loginAsViewerUser(); - cy.visit(serviceInventoryHref); + cy.visitKibana(serviceInventoryHref); }); it('with the correct environment when changing the environment', () => { @@ -135,11 +137,9 @@ describe('When navigating to the service inventory', () => { }); describe('Check detailed statistics API with multiple services', () => { - before(async () => { - cy.loginAsViewerUser(); + before(() => { const { rangeFrom, rangeTo } = timeRange; - - await synthtrace.index( + synthtrace.index( generateMultipleServicesData({ from: new Date(rangeFrom).getTime(), to: new Date(rangeTo).getTime(), @@ -147,8 +147,12 @@ describe('Check detailed statistics API with multiple services', () => { ); }); - after(async () => { - await synthtrace.clean(); + beforeEach(() => { + cy.loginAsViewerUser(); + }); + + after(() => { + synthtrace.clean(); }); it('calls detailed API with visible items only', () => { @@ -157,7 +161,7 @@ describe('Check detailed statistics API with multiple services', () => { ); cy.intercept('GET', '/internal/apm/services?*').as('mainStatisticsRequest'); - cy.visit( + cy.visitKibana( `${serviceInventoryHref}&pageSize=10&sortField=serviceName&sortDirection=asc` ); cy.wait('@mainStatisticsRequest'); diff --git a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_overview/aws_lambda/aws_lamba.spec.ts b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_overview/aws_lambda/aws_lamba.spec.ts index a2674d056e317c..a70620ee18f829 100644 --- a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_overview/aws_lambda/aws_lamba.spec.ts +++ b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_overview/aws_lambda/aws_lamba.spec.ts @@ -23,8 +23,8 @@ const apiToIntercept = { }; describe('Service overview - aws lambda', () => { - before(async () => { - await synthtrace.index( + before(() => { + synthtrace.index( generateData({ start: new Date(start).getTime(), end: new Date(end).getTime(), @@ -32,19 +32,16 @@ describe('Service overview - aws lambda', () => { ); }); - after(async () => { - await synthtrace.clean(); - }); - - beforeEach(() => { - cy.loginAsViewerUser(); + after(() => { + synthtrace.clean(); }); it('displays a cold start rate chart and not a transaction breakdown chart', () => { const { endpoint, name } = apiToIntercept; - cy.intercept('GET', endpoint).as(name); - cy.visit(serviceOverviewHref); + + cy.loginAsViewerUser(); + cy.visitKibana(serviceOverviewHref); cy.wait(`@${name}`); cy.contains('Cold start rate'); diff --git a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_overview/aws_lambda/generate_data.ts b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_overview/aws_lambda/generate_data.ts index 68dc3f62b5c125..bbd7553d1fa335 100644 --- a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_overview/aws_lambda/generate_data.ts +++ b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_overview/aws_lambda/generate_data.ts @@ -4,7 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { apm, timerange } from '@elastic/apm-synthtrace'; +import { apm, timerange } from '@kbn/apm-synthtrace'; const dataConfig = { serviceName: 'synth-python', diff --git a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_overview/errors_table.spec.ts b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_overview/errors_table.spec.ts index 8d7cfd4e65288a..b175eb0430ed4c 100644 --- a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_overview/errors_table.spec.ts +++ b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_overview/errors_table.spec.ts @@ -18,8 +18,8 @@ const serviceOverviewHref = url.format({ }); describe('Errors table', () => { - before(async () => { - await synthtrace.index( + before(() => { + synthtrace.index( opbeans({ from: new Date(start).getTime(), to: new Date(end).getTime(), @@ -27,8 +27,8 @@ describe('Errors table', () => { ); }); - after(async () => { - await synthtrace.clean(); + after(() => { + synthtrace.clean(); }); beforeEach(() => { @@ -36,20 +36,20 @@ describe('Errors table', () => { }); it('errors table is populated', () => { - cy.visit(serviceOverviewHref); + cy.visitKibana(serviceOverviewHref); cy.contains('opbeans-java'); cy.contains('[MockError] Foo'); }); it('navigates to the errors page', () => { - cy.visit(serviceOverviewHref); + cy.visitKibana(serviceOverviewHref); cy.contains('opbeans-java'); cy.contains('a', 'View errors').click(); cy.url().should('include', '/opbeans-java/errors'); }); it('clicking on type adds a filter in the kuerybar and navigates to errors page', () => { - cy.visit(serviceOverviewHref); + cy.visitKibana(serviceOverviewHref); cy.get('[data-test-subj="headerFilterKuerybar"]') .invoke('val') .should('be.empty'); @@ -64,7 +64,7 @@ describe('Errors table', () => { }); it('navigates to error detail page', () => { - cy.visit(serviceOverviewHref); + cy.visitKibana(serviceOverviewHref); cy.contains('a', '[MockError] Foo').click(); cy.contains('div', 'Exception message'); }); diff --git a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_overview/header_filters.spec.ts b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_overview/header_filters.spec.ts index 3b7b0c87a7f846..cf5102ee6e37e2 100644 --- a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_overview/header_filters.spec.ts +++ b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_overview/header_filters.spec.ts @@ -59,14 +59,14 @@ const apisToIntercept = [ ]; describe('Service overview - header filters', () => { - before(async () => { - await synthtrace.index( + before(() => { + synthtrace.index( opbeans({ from: new Date(start).getTime(), to: new Date(end).getTime() }) ); }); - after(async () => { - await synthtrace.clean(); + after(() => { + synthtrace.clean(); }); describe('Filtering by transaction type', () => { @@ -74,7 +74,7 @@ describe('Service overview - header filters', () => { cy.loginAsViewerUser(); }); it('changes url when selecting different value', () => { - cy.visit(serviceOverviewHref); + cy.visitKibana(serviceOverviewHref); cy.contains('opbeans-node'); cy.url().should('not.include', 'transactionType'); cy.get('[data-test-subj="headerFilterTransactionType"]').should( @@ -93,7 +93,7 @@ describe('Service overview - header filters', () => { apisToIntercept.map(({ endpoint, name }) => { cy.intercept('GET', endpoint).as(name); }); - cy.visit(serviceOverviewHref); + cy.visitKibana(serviceOverviewHref); cy.get('[data-test-subj="headerFilterTransactionType"]').should( 'have.value', 'request' @@ -122,7 +122,7 @@ describe('Service overview - header filters', () => { cy.loginAsViewerUser(); }); it('filters by transaction.name', () => { - cy.visit( + cy.visitKibana( url.format({ pathname: '/app/apm/services/opbeans-java/overview', query: { rangeFrom: start, rangeTo: end }, diff --git a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_overview/instances_table.spec.ts b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_overview/instances_table.spec.ts index 1fc83b3e2eb0ac..c3b5f37c32acc7 100644 --- a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_overview/instances_table.spec.ts +++ b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_overview/instances_table.spec.ts @@ -41,19 +41,19 @@ describe('Instances table', () => { cy.loginAsViewerUser(); }); - // describe('when data is not loaded', () => { - // it('shows empty message', () => { - // cy.visit(serviceOverviewHref); - // cy.contains('opbeans-java'); - // cy.get('[data-test-subj="serviceInstancesTableContainer"]').contains( - // 'No items found' - // ); - // }); - // }); + describe.skip('when data is not loaded', () => { + it('shows empty message', () => { + cy.visitKibana(serviceOverviewHref); + cy.contains('opbeans-java'); + cy.get('[data-test-subj="serviceInstancesTableContainer"]').contains( + 'No items found' + ); + }); + }); describe('when data is loaded', () => { - before(async () => { - await synthtrace.index( + before(() => { + synthtrace.index( opbeans({ from: new Date(start).getTime(), to: new Date(end).getTime(), @@ -61,12 +61,12 @@ describe('Instances table', () => { ); }); - after(async () => { - await synthtrace.clean(); + after(() => { + synthtrace.clean(); }); it('has data in the table', () => { - cy.visit(serviceOverviewHref); + cy.visitKibana(serviceOverviewHref); cy.contains('opbeans-java'); cy.contains(serviceNodeName); }); @@ -75,7 +75,7 @@ describe('Instances table', () => { cy.intercept('GET', endpoint).as(name); }); - cy.visit(serviceOverviewHref); + cy.visitKibana(serviceOverviewHref); cy.contains('opbeans-java'); cy.wait('@instancesMainRequest'); @@ -96,7 +96,7 @@ describe('Instances table', () => { cy.intercept('GET', endpoint).as(name); }); - cy.visit(serviceOverviewHref); + cy.visitKibana(serviceOverviewHref); cy.contains('opbeans-java'); cy.wait('@instancesMainRequest'); diff --git a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_overview/service_overview.spec.ts b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_overview/service_overview.spec.ts index f61ad0c0761c67..d73713290b4eff 100644 --- a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_overview/service_overview.spec.ts +++ b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_overview/service_overview.spec.ts @@ -86,8 +86,8 @@ const aliasNamesWithComparison = apiRequestsToInterceptWithComparison.map( const aliasNames = [...aliasNamesNoComparison, ...aliasNamesWithComparison]; describe('Service Overview', () => { - before(async () => { - await synthtrace.index( + before(() => { + synthtrace.index( opbeans({ from: new Date(start).getTime(), to: new Date(end).getTime(), @@ -95,14 +95,14 @@ describe('Service Overview', () => { ); }); - after(async () => { - await synthtrace.clean(); + after(() => { + synthtrace.clean(); }); describe('renders', () => { - before(() => { + beforeEach(() => { cy.loginAsViewerUser(); - cy.visit(baseUrl); + cy.visitKibana(baseUrl); }); it('renders all components on the page', () => { @@ -122,7 +122,6 @@ describe('Service Overview', () => { describe('transactions', () => { beforeEach(() => { cy.loginAsViewerUser(); - cy.visit(baseUrl); }); it('persists transaction type selected when clicking on Transactions tab', () => { @@ -130,6 +129,9 @@ describe('Service Overview', () => { 'GET', '/internal/apm/services/opbeans-node/transaction_types?*' ).as('transactionTypesRequest'); + + cy.visitKibana(baseUrl); + cy.wait('@transactionTypesRequest'); cy.get('[data-test-subj="headerFilterTransactionType"]').should( @@ -148,11 +150,14 @@ describe('Service Overview', () => { ); }); - it.skip('persists transaction type selected when clicking on View Transactions link', () => { + it('persists transaction type selected when clicking on View Transactions link', () => { cy.intercept( 'GET', '/internal/apm/services/opbeans-node/transaction_types?*' ).as('transactionTypesRequest'); + + cy.visitKibana(baseUrl); + cy.wait('@transactionTypesRequest'); cy.get('[data-test-subj="headerFilterTransactionType"]').should( 'have.value', @@ -173,20 +178,20 @@ describe('Service Overview', () => { }); describe('when RUM service', () => { - before(() => { + it('hides dependency tab when RUM service', () => { cy.loginAsViewerUser(); - cy.visit( + + cy.intercept('GET', '/internal/apm/services/opbeans-rum/agent?*').as( + 'agentRequest' + ); + + cy.visitKibana( url.format({ pathname: '/app/apm/services/opbeans-rum/overview', query: { rangeFrom: start, rangeTo: end }, }) ); - }); - it('hides dependency tab when RUM service', () => { - cy.intercept('GET', '/internal/apm/services/opbeans-rum/agent?*').as( - 'agentRequest' - ); cy.contains('Overview'); cy.contains('Transactions'); cy.contains('Error'); @@ -204,17 +209,18 @@ describe('Service Overview', () => { describe('Calls APIs', () => { beforeEach(() => { cy.loginAsViewerUser(); - cy.visit(baseUrl); + apiRequestsToIntercept.map(({ endpoint, aliasName }) => { cy.intercept('GET', endpoint).as(aliasName); }); apiRequestsToInterceptWithComparison.map(({ endpoint, aliasName }) => { cy.intercept('GET', endpoint).as(aliasName); }); + cy.visitKibana(baseUrl); }); it.skip('with the correct environment when changing the environment', () => { - cy.wait(aliasNames, { requestTimeout: 10000 }); + cy.wait(aliasNames); cy.intercept('GET', 'internal/apm/suggestions?*').as( 'suggestionsRequest' @@ -241,11 +247,11 @@ describe('Service Overview', () => { it('when clicking the refresh button', () => { cy.contains('Refresh').click(); - cy.wait(aliasNames, { requestTimeout: 10000 }); + cy.wait(aliasNames); }); it.skip('when selecting a different time range and clicking the update button', () => { - cy.wait(aliasNames, { requestTimeout: 10000 }); + cy.wait(aliasNames); const timeStart = moment(start).subtract(5, 'm').toISOString(); const timeEnd = moment(end).subtract(5, 'm').toISOString(); diff --git a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_overview/time_comparison.spec.ts b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_overview/time_comparison.spec.ts index 25591cd358bd54..611455163eca3a 100644 --- a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_overview/time_comparison.spec.ts +++ b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_overview/time_comparison.spec.ts @@ -51,8 +51,8 @@ const apisToIntercept = [ ]; describe.skip('Service overview: Time Comparison', () => { - before(async () => { - await synthtrace.index( + before(() => { + synthtrace.index( opbeans({ from: new Date(start).getTime(), to: new Date(end).getTime(), @@ -60,8 +60,8 @@ describe.skip('Service overview: Time Comparison', () => { ); }); - after(async () => { - await synthtrace.clean(); + after(() => { + synthtrace.clean(); }); beforeEach(() => { @@ -69,14 +69,14 @@ describe.skip('Service overview: Time Comparison', () => { }); it('enables by default the time comparison feature with Last 24 hours selected', () => { - cy.visit(serviceOverviewPath); + cy.visitKibana(serviceOverviewPath); cy.url().should('include', 'comparisonEnabled=true'); cy.url().should('include', 'offset=1d'); }); describe('when comparison is toggled off', () => { it('disables select box', () => { - cy.visit(serviceOverviewHref); + cy.visitKibana(serviceOverviewHref); cy.contains('opbeans-java'); // Comparison is enabled by default @@ -91,7 +91,7 @@ describe.skip('Service overview: Time Comparison', () => { apisToIntercept.map(({ endpoint, name }) => { cy.intercept('GET', endpoint).as(name); }); - cy.visit(serviceOverviewHref); + cy.visitKibana(serviceOverviewHref); cy.get('[data-test-subj="comparisonSelect"]').should('be.enabled'); const offset = `offset=1d`; @@ -125,7 +125,7 @@ describe.skip('Service overview: Time Comparison', () => { apisToIntercept.map(({ endpoint, name }) => { cy.intercept('GET', endpoint).as(name); }); - cy.visit(serviceOverviewPath); + cy.visitKibana(serviceOverviewPath); cy.contains('opbeans-java'); // opens the page with "Day before" selected cy.get('[data-test-subj="comparisonSelect"]').should('have.value', '1d'); @@ -136,7 +136,7 @@ describe.skip('Service overview: Time Comparison', () => { }); it('changes comparison type when a new time range is selected', () => { - cy.visit(serviceOverviewHref); + cy.visitKibana(serviceOverviewHref); cy.contains('opbeans-java'); // Time comparison default value cy.get('[data-test-subj="comparisonSelect"]').should('have.value', '1d'); @@ -189,7 +189,7 @@ describe.skip('Service overview: Time Comparison', () => { apisToIntercept.map(({ endpoint, name }) => { cy.intercept('GET', endpoint).as(name); }); - cy.visit( + cy.visitKibana( url.format({ pathname: serviceOverviewPath, query: { diff --git a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/transaction_details/generate_span_links_data.ts b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/transaction_details/generate_span_links_data.ts index 3905cf324c44ab..9fd2cfe6eab0b4 100644 --- a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/transaction_details/generate_span_links_data.ts +++ b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/transaction_details/generate_span_links_data.ts @@ -4,7 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { apm, EntityArrayIterable, timerange } from '@elastic/apm-synthtrace'; +import { apm, EntityArrayIterable, timerange } from '@kbn/apm-synthtrace'; import { synthtrace } from '../../../../synthtrace'; import { SpanLink } from '../../../../../typings/es_schemas/raw/fields/span_links'; @@ -296,7 +296,7 @@ function getConsumerMultiple({ * ----Span E * ------span.links= producer-external-only / Span B | producer-consumer / Transaction C */ -export async function generateSpanLinksData() { +export function generateSpanLinksData() { const producerInternalOnly = getProducerInternalOnly(); const producerExternalOnly = getProducerExternalOnly(); const producerConsumer = getProducerConsumer({ @@ -309,7 +309,7 @@ export async function generateSpanLinksData() { producerExternalOnlySpanBSpanLink: producerExternalOnly.spanBSpanLink, }); - await synthtrace.index( + synthtrace.index( new EntityArrayIterable(producerInternalOnly.apmFields).merge( new EntityArrayIterable(producerExternalOnly.apmFields), new EntityArrayIterable(producerConsumer.apmFields), diff --git a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/transaction_details/span_links.spec.ts b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/transaction_details/span_links.spec.ts index 3dff8f075f187c..cddba048e8a180 100644 --- a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/transaction_details/span_links.spec.ts +++ b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/transaction_details/span_links.spec.ts @@ -35,17 +35,17 @@ describe('Span links', () => { describe('when data is loaded', () => { let ids: Awaited>; - before(async () => { - ids = await generateSpanLinksData(); + before(() => { + ids = generateSpanLinksData(); }); - after(async () => { - await synthtrace.clean(); + after(() => { + synthtrace.clean(); }); describe('span links count on trace waterfall', () => { it('Shows two children and no parents on producer-internal-only Span A', () => { - cy.visit( + cy.visitKibana( getServiceInventoryUrl({ serviceName: 'producer-internal-only' }) ); cy.contains('Transaction A').click(); @@ -59,7 +59,7 @@ describe('Span links', () => { }); it('Shows one parent and one children on producer-external-only Span B', () => { - cy.visit( + cy.visitKibana( getServiceInventoryUrl({ serviceName: 'producer-external-only' }) ); cy.contains('Transaction B').click(); @@ -73,7 +73,9 @@ describe('Span links', () => { }); it('Shows one parent and one children on producer-consumer Transaction C', () => { - cy.visit(getServiceInventoryUrl({ serviceName: 'producer-consumer' })); + cy.visitKibana( + getServiceInventoryUrl({ serviceName: 'producer-consumer' }) + ); cy.contains('Transaction C').click(); cy.contains('2 Span links'); cy.get( @@ -85,7 +87,9 @@ describe('Span links', () => { }); it('Shows no parent and one children on producer-consumer Span C', () => { - cy.visit(getServiceInventoryUrl({ serviceName: 'producer-consumer' })); + cy.visitKibana( + getServiceInventoryUrl({ serviceName: 'producer-consumer' }) + ); cy.contains('Transaction C').click(); cy.contains('1 Span link'); cy.get( @@ -97,7 +101,9 @@ describe('Span links', () => { }); it('Shows two parents and one children on consumer-multiple Transaction D', () => { - cy.visit(getServiceInventoryUrl({ serviceName: 'consumer-multiple' })); + cy.visitKibana( + getServiceInventoryUrl({ serviceName: 'consumer-multiple' }) + ); cy.contains('Transaction D').click(); cy.contains('2 Span links'); cy.get( @@ -109,7 +115,9 @@ describe('Span links', () => { }); it('Shows two parents and one children on consumer-multiple Span E', () => { - cy.visit(getServiceInventoryUrl({ serviceName: 'consumer-multiple' })); + cy.visitKibana( + getServiceInventoryUrl({ serviceName: 'consumer-multiple' }) + ); cy.contains('Transaction D').click(); cy.contains('2 Span links'); cy.get( @@ -123,7 +131,7 @@ describe('Span links', () => { describe('span link flyout', () => { it('Shows children details on producer-internal-only Span A', () => { - cy.visit( + cy.visitKibana( getServiceInventoryUrl({ serviceName: 'producer-internal-only' }) ); cy.contains('Transaction A').click(); @@ -154,7 +162,7 @@ describe('Span links', () => { }); it('Shows children and parents details on producer-external-only Span B', () => { - cy.visit( + cy.visitKibana( getServiceInventoryUrl({ serviceName: 'producer-external-only' }) ); cy.contains('Transaction B').click(); @@ -178,7 +186,9 @@ describe('Span links', () => { }); it('Shows children and parents details on producer-consumer Transaction C', () => { - cy.visit(getServiceInventoryUrl({ serviceName: 'producer-consumer' })); + cy.visitKibana( + getServiceInventoryUrl({ serviceName: 'producer-consumer' }) + ); cy.contains('Transaction C').click(); cy.get( `[aria-controls="${ids.producerConsumerIds.transactionCId}"]` @@ -210,7 +220,9 @@ describe('Span links', () => { }); it('Shows children and parents details on producer-consumer Span C', () => { - cy.visit(getServiceInventoryUrl({ serviceName: 'producer-consumer' })); + cy.visitKibana( + getServiceInventoryUrl({ serviceName: 'producer-consumer' }) + ); cy.contains('Transaction C').click(); cy.contains('Span C').click(); cy.get('[data-test-subj="spanLinksTab"]').click(); @@ -232,7 +244,9 @@ describe('Span links', () => { }); it('Shows children and parents details on consumer-multiple Transaction D', () => { - cy.visit(getServiceInventoryUrl({ serviceName: 'consumer-multiple' })); + cy.visitKibana( + getServiceInventoryUrl({ serviceName: 'consumer-multiple' }) + ); cy.contains('Transaction D').click(); cy.get( `[aria-controls="${ids.producerMultipleIds.transactionDId}"]` @@ -266,7 +280,9 @@ describe('Span links', () => { }); it('Shows children and parents details on consumer-multiple Span E', () => { - cy.visit(getServiceInventoryUrl({ serviceName: 'consumer-multiple' })); + cy.visitKibana( + getServiceInventoryUrl({ serviceName: 'consumer-multiple' }) + ); cy.contains('Transaction D').click(); cy.contains('Span E').click(); cy.get('[data-test-subj="spanLinksTab"]').click(); diff --git a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/transaction_details/transaction_details.spec.ts b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/transaction_details/transaction_details.spec.ts index c5eeda6645ce81..ee2aade9ec1dff 100644 --- a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/transaction_details/transaction_details.spec.ts +++ b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/transaction_details/transaction_details.spec.ts @@ -17,8 +17,8 @@ const timeRange = { }; describe('Transaction details', () => { - before(async () => { - await synthtrace.index( + before(() => { + synthtrace.index( opbeans({ from: new Date(start).getTime(), to: new Date(end).getTime(), @@ -26,13 +26,13 @@ describe('Transaction details', () => { ); }); - after(async () => { - await synthtrace.clean(); + after(() => { + synthtrace.clean(); }); beforeEach(() => { cy.loginAsViewerUser(); - cy.visit( + cy.visitKibana( `/app/apm/services/opbeans-java/transactions/view?${new URLSearchParams({ ...timeRange, transactionName: 'GET /api/product', diff --git a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/transactions_overview/transactions_overview.spec.ts b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/transactions_overview/transactions_overview.spec.ts index 671b35741f91b3..83753b7fe25954 100644 --- a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/transactions_overview/transactions_overview.spec.ts +++ b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/transactions_overview/transactions_overview.spec.ts @@ -19,8 +19,8 @@ const serviceTransactionsHref = url.format({ }); describe('Transactions Overview', () => { - before(async () => { - await synthtrace.index( + before(() => { + synthtrace.index( opbeans({ from: new Date(start).getTime(), to: new Date(end).getTime(), @@ -28,8 +28,8 @@ describe('Transactions Overview', () => { ); }); - after(async () => { - await synthtrace.clean(); + after(() => { + synthtrace.clean(); }); beforeEach(() => { @@ -37,7 +37,7 @@ describe('Transactions Overview', () => { }); it('has no detectable a11y violations on load', () => { - cy.visit(serviceTransactionsHref); + cy.visitKibana(serviceTransactionsHref); cy.get('a:contains(Transactions)').should( 'have.attr', 'aria-selected', @@ -48,7 +48,7 @@ describe('Transactions Overview', () => { }); it('persists transaction type selected when navigating to Overview tab', () => { - cy.visit(serviceTransactionsHref); + cy.visitKibana(serviceTransactionsHref); cy.get('[data-test-subj="headerFilterTransactionType"]').should( 'have.value', 'request' diff --git a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/tutorial/tutorial.spec.ts b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/tutorial/tutorial.spec.ts index e2ebe9c2bdda81..cb8d9218b4ec1e 100644 --- a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/tutorial/tutorial.spec.ts +++ b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/tutorial/tutorial.spec.ts @@ -6,9 +6,9 @@ */ describe('APM tutorial', () => { - before(() => { + beforeEach(() => { cy.loginAsViewerUser(); - cy.visit('/app/home#/tutorial/apm'); + cy.visitKibana('/app/home#/tutorial/apm'); }); it('includes section for APM Server', () => { diff --git a/x-pack/plugins/apm/ftr_e2e/cypress/plugins/index.ts b/x-pack/plugins/apm/ftr_e2e/cypress/plugins/index.ts index 25b29e080b2c2a..54622cb59bd5eb 100644 --- a/x-pack/plugins/apm/ftr_e2e/cypress/plugins/index.ts +++ b/x-pack/plugins/apm/ftr_e2e/cypress/plugins/index.ts @@ -9,7 +9,7 @@ import { createLogger, EntityArrayIterable, LogLevel, -} from '@elastic/apm-synthtrace'; +} from '@kbn/apm-synthtrace'; import { createEsClientForTesting } from '@kbn/test'; // *********************************************************** diff --git a/x-pack/plugins/apm/ftr_e2e/cypress/support/commands.ts b/x-pack/plugins/apm/ftr_e2e/cypress/support/commands.ts index 0559b07b1cbf29..37182e328ebf37 100644 --- a/x-pack/plugins/apm/ftr_e2e/cypress/support/commands.ts +++ b/x-pack/plugins/apm/ftr_e2e/cypress/support/commands.ts @@ -21,21 +21,24 @@ Cypress.Commands.add('loginAsEditorUser', () => { Cypress.Commands.add( 'loginAs', ({ username, password }: { username: string; password: string }) => { - cy.log(`Logging in as ${username}`); - const kibanaUrl = Cypress.env('KIBANA_URL'); - return cy.request({ - log: false, - method: 'POST', - url: `${kibanaUrl}/internal/security/login`, - body: { - providerType: 'basic', - providerName: 'basic', - currentURL: `${kibanaUrl}/login`, - params: { username, password }, - }, - headers: { - 'kbn-xsrf': 'e2e_test', - }, + cy.log(`Calling 'loginAs'`); + cy.session([username, password], () => { + cy.log(`Logging in as ${username}`); + const kibanaUrl = Cypress.env('KIBANA_URL'); + cy.request({ + log: false, + method: 'POST', + url: `${kibanaUrl}/internal/security/login`, + body: { + providerType: 'basic', + providerName: 'basic', + currentURL: `${kibanaUrl}/login`, + params: { username, password }, + }, + headers: { + 'kbn-xsrf': 'e2e_test', + }, + }); }); } ); @@ -45,6 +48,14 @@ Cypress.Commands.add('changeTimeRange', (value: string) => { cy.contains(value).click(); }); +Cypress.Commands.add('visitKibana', (url: string) => { + cy.visit(url); + cy.get('[data-test-subj="kbnLoadingMessage"]').should('exist'); + cy.get('[data-test-subj="kbnLoadingMessage"]').should('not.exist', { + timeout: 50000, + }); +}); + Cypress.Commands.add( 'selectAbsoluteTimeRange', (start: string, end: string) => { @@ -96,6 +107,7 @@ Cypress.Commands.add( headers: { 'kbn-xsrf': 'e2e_test', }, + auth: { user: 'editor', pass: 'changeme' }, }); } ); diff --git a/x-pack/plugins/apm/ftr_e2e/cypress/support/types.d.ts b/x-pack/plugins/apm/ftr_e2e/cypress/support/types.d.ts index f46a54142de0ea..27720210b668aa 100644 --- a/x-pack/plugins/apm/ftr_e2e/cypress/support/types.d.ts +++ b/x-pack/plugins/apm/ftr_e2e/cypress/support/types.d.ts @@ -14,6 +14,7 @@ declare namespace Cypress { password: string; }): Cypress.Chainable>; changeTimeRange(value: string): void; + visitKibana(url: string): void; selectAbsoluteTimeRange(start: string, end: string): void; expectAPIsToHaveBeenCalledWith(params: { apisIntercepted: string[]; diff --git a/x-pack/plugins/apm/ftr_e2e/synthtrace.ts b/x-pack/plugins/apm/ftr_e2e/synthtrace.ts index de113c6c44c4db..a421edea04a6e9 100644 --- a/x-pack/plugins/apm/ftr_e2e/synthtrace.ts +++ b/x-pack/plugins/apm/ftr_e2e/synthtrace.ts @@ -4,15 +4,10 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import type { EntityIterable } from '@elastic/apm-synthtrace'; +import type { EntityIterable } from '@kbn/apm-synthtrace'; export const synthtrace = { index: (events: EntityIterable) => - new Promise((resolve) => { - cy.task('synthtrace:index', events.toArray()).then(resolve); - }), - clean: () => - new Promise((resolve) => { - cy.task('synthtrace:clean').then(resolve); - }), + cy.task('synthtrace:index', events.toArray()), + clean: () => cy.task('synthtrace:clean'), }; diff --git a/x-pack/plugins/apm/public/application/application.test.tsx b/x-pack/plugins/apm/public/application/application.test.tsx index 62adf0b2cb3556..3c2d46ef3a107a 100644 --- a/x-pack/plugins/apm/public/application/application.test.tsx +++ b/x-pack/plugins/apm/public/application/application.test.tsx @@ -122,7 +122,8 @@ describe('renderApp (APM)', () => { }; }; - it('renders the app', () => { + it('renders the app', async () => { + const promise = Promise.resolve(); const mountProps = getApmMountProps(); let unmount: () => void; @@ -131,6 +132,11 @@ describe('renderApp (APM)', () => { unmount = renderApmApp(mountProps); }); + // fake promise to wait for to ensure the app is mounted + await act(async () => { + await promise; + }); + expect(() => { unmount(); }).not.toThrowError(); diff --git a/x-pack/plugins/apm/public/components/routing/templates/apm_main_template.tsx b/x-pack/plugins/apm/public/components/routing/templates/apm_main_template.tsx index 55b486f5ae3667..ff8442016adc5a 100644 --- a/x-pack/plugins/apm/public/components/routing/templates/apm_main_template.tsx +++ b/x-pack/plugins/apm/public/components/routing/templates/apm_main_template.tsx @@ -9,7 +9,7 @@ import { EuiPageHeaderProps } from '@elastic/eui'; import React from 'react'; import { useLocation } from 'react-router-dom'; import { useKibana } from '@kbn/kibana-react-plugin/public'; -import { KibanaPageTemplateProps } from '@kbn/shared-ux-components'; +import type { KibanaPageTemplateProps } from '@kbn/shared-ux-page-kibana-template'; import { enableServiceGroups } from '@kbn/observability-plugin/public'; import { EnvironmentsContextProvider } from '../../../context/environments_context/environments_context'; import { useFetcher, FETCH_STATUS } from '../../../hooks/use_fetcher'; diff --git a/x-pack/plugins/apm/public/components/routing/templates/apm_service_template/index.test.tsx b/x-pack/plugins/apm/public/components/routing/templates/apm_service_template/index.test.tsx index 763d4cf0717a14..c8ab3acd1a0aff 100644 --- a/x-pack/plugins/apm/public/components/routing/templates/apm_service_template/index.test.tsx +++ b/x-pack/plugins/apm/public/components/routing/templates/apm_service_template/index.test.tsx @@ -4,7 +4,11 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { isMetricsTabHidden, isMetricsJVMsTabHidden } from '.'; +import { + isMetricsTabHidden, + isMetricsJVMsTabHidden, + isInfraTabHidden, +} from '.'; describe('APM service template', () => { describe('isMetricsTabHidden', () => { @@ -71,4 +75,38 @@ describe('APM service template', () => { }); }); }); + describe('isInfraTabHidden', () => { + describe('hides infra tab', () => { + [ + { agentName: undefined }, + { agentName: 'js-base' }, + { agentName: 'rum-js' }, + { agentName: 'opentelemetry/webjs' }, + { agentName: 'ios/swift' }, + { runtimeName: 'aws_lambda' }, + ].map((input) => { + it(`when input ${JSON.stringify(input)}`, () => { + expect(isInfraTabHidden(input)).toBeTruthy(); + }); + }); + }); + describe('shows infra tab', () => { + [ + { agentName: 'ruby', runtimeName: 'ruby' }, + { agentName: 'ruby', runtimeName: 'jruby' }, + { agentName: 'ruby' }, + { agentName: 'dotnet' }, + { agentName: 'go' }, + { agentName: 'nodejs' }, + { agentName: 'php' }, + { agentName: 'python' }, + { agentName: 'java' }, + { agentName: 'opentelemetry/java' }, + ].map((input) => { + it(`when input ${JSON.stringify(input)}`, () => { + expect(isInfraTabHidden(input)).toBeFalsy(); + }); + }); + }); + }); }); diff --git a/x-pack/plugins/apm/public/components/routing/templates/apm_service_template/index.tsx b/x-pack/plugins/apm/public/components/routing/templates/apm_service_template/index.tsx index 7acf14fc0bf014..2abfdba6f4124f 100644 --- a/x-pack/plugins/apm/public/components/routing/templates/apm_service_template/index.tsx +++ b/x-pack/plugins/apm/public/components/routing/templates/apm_service_template/index.tsx @@ -14,7 +14,6 @@ import { import { i18n } from '@kbn/i18n'; import { omit } from 'lodash'; import React from 'react'; -import { enableInfrastructureView } from '@kbn/observability-plugin/public'; import { isMobileAgentName, isJavaAgentName, @@ -168,6 +167,21 @@ export function isMetricsJVMsTabHidden({ ); } +export function isInfraTabHidden({ + agentName, + runtimeName, +}: { + agentName?: string; + runtimeName?: string; +}) { + return ( + !agentName || + isRumAgentName(agentName) || + isMobileAgentName(agentName) || + isServerlessAgent(runtimeName) + ); +} + function useTabs({ selectedTab }: { selectedTab: Tab['key'] }) { const { agentName, runtimeName } = useApmServiceContext(); const { config, core, plugins } = useApmPluginContext(); @@ -177,8 +191,6 @@ function useTabs({ selectedTab }: { selectedTab: Tab['key'] }) { capabilities ); - const showInfraTab = core.uiSettings.get(enableInfrastructureView); - const router = useApmRouter(); const { @@ -269,8 +281,7 @@ function useTabs({ selectedTab }: { selectedTab: Tab['key'] }) { label: i18n.translate('xpack.apm.home.infraTabLabel', { defaultMessage: 'Infrastructure', }), - - hidden: !showInfraTab, + hidden: isInfraTabHidden({ agentName, runtimeName }), }, { key: 'service-map', diff --git a/x-pack/plugins/apm/public/components/routing/templates/no_data_config.ts b/x-pack/plugins/apm/public/components/routing/templates/no_data_config.ts index 4e4c90b4cfeac4..9a36431b1f8256 100644 --- a/x-pack/plugins/apm/public/components/routing/templates/no_data_config.ts +++ b/x-pack/plugins/apm/public/components/routing/templates/no_data_config.ts @@ -6,7 +6,7 @@ */ import { i18n } from '@kbn/i18n'; -import { KibanaPageTemplateProps } from '@kbn/shared-ux-components'; +import type { NoDataConfig } from '@kbn/shared-ux-page-kibana-template'; export function getNoDataConfig({ docsLink, @@ -22,7 +22,7 @@ export function getNoDataConfig({ basePath?: string; hasApmData?: boolean; hasApmIntegrations?: boolean; -}): KibanaPageTemplateProps['noDataConfig'] { +}): NoDataConfig | undefined { // don't show "no data screen" when there is APM data or it should be bypassed if (hasApmData || shouldBypassNoDataScreen || loading) { return; diff --git a/x-pack/plugins/apm/public/components/routing/templates/service_group_template.tsx b/x-pack/plugins/apm/public/components/routing/templates/service_group_template.tsx index a891ab9bdcdced..1eece05eb88438 100644 --- a/x-pack/plugins/apm/public/components/routing/templates/service_group_template.tsx +++ b/x-pack/plugins/apm/public/components/routing/templates/service_group_template.tsx @@ -16,7 +16,7 @@ import { import React from 'react'; import { i18n } from '@kbn/i18n'; import { useKibana } from '@kbn/kibana-react-plugin/public'; -import { KibanaPageTemplateProps } from '@kbn/shared-ux-components'; +import type { KibanaPageTemplateProps } from '@kbn/shared-ux-page-kibana-template'; import { enableServiceGroups } from '@kbn/observability-plugin/public'; import { useFetcher, FETCH_STATUS } from '../../../hooks/use_fetcher'; import { ApmPluginStartDeps } from '../../../plugin'; diff --git a/x-pack/plugins/apm/readme.md b/x-pack/plugins/apm/readme.md index df7b641fbb2310..fb7cf20732bf34 100644 --- a/x-pack/plugins/apm/readme.md +++ b/x-pack/plugins/apm/readme.md @@ -13,7 +13,7 @@ ## Tooling - [VSCode setup instructions](./dev_docs/vscode_setup.md) - [Github PR commands](./dev_docs/github_commands.md) -- [Synthtrace (data generation)](https://github.com/elastic/kibana/blob/main/packages/elastic-apm-synthtrace/README.md) +- [Synthtrace (data generation)](https://github.com/elastic/kibana/blob/main/packages/kbn-apm-synthtrace/README.md) - [Query debugging in development and production](./dev_docs/query_debugging_in_development_and_production.md) ## Other resources diff --git a/x-pack/plugins/apm/scripts/aggregate_latency_metrics/index.ts b/x-pack/plugins/apm/scripts/aggregate_latency_metrics/index.ts index f9aa943b5eceb1..a48da0f4577ccb 100644 --- a/x-pack/plugins/apm/scripts/aggregate_latency_metrics/index.ts +++ b/x-pack/plugins/apm/scripts/aggregate_latency_metrics/index.ts @@ -8,7 +8,7 @@ import { argv } from 'yargs'; import pLimit from 'p-limit'; import pRetry from 'p-retry'; -import { set } from '@elastic/safer-lodash-set'; +import { set } from '@kbn/safer-lodash-set'; import { uniq, without, merge, flatten } from 'lodash'; import * as histogram from 'hdr-histogram-js'; import { diff --git a/x-pack/plugins/apm/server/deprecations/deprecations.test.ts b/x-pack/plugins/apm/server/deprecations/deprecations.test.ts index b57628a3f326b7..1843affb9bfc32 100644 --- a/x-pack/plugins/apm/server/deprecations/deprecations.test.ts +++ b/x-pack/plugins/apm/server/deprecations/deprecations.test.ts @@ -54,7 +54,7 @@ describe('getDeprecations', () => { get: () => ({ id: 'foo', - package_policies: [''], + package_policies: [{ package: { name: 'system' } }], } as AgentPolicy), }, }), diff --git a/x-pack/plugins/canvas/public/components/asset_manager/asset.tsx b/x-pack/plugins/canvas/public/components/asset_manager/asset.tsx index 9150b78f6000ad..256d33a8e7a787 100644 --- a/x-pack/plugins/canvas/public/components/asset_manager/asset.tsx +++ b/x-pack/plugins/canvas/public/components/asset_manager/asset.tsx @@ -7,7 +7,7 @@ import { Dispatch } from 'redux'; import { connect } from 'react-redux'; -import { set } from '@elastic/safer-lodash-set'; +import { set } from '@kbn/safer-lodash-set'; import { fromExpression, toExpression } from '@kbn/interpreter'; diff --git a/x-pack/plugins/canvas/public/components/workpad_app/workpad_app.component.tsx b/x-pack/plugins/canvas/public/components/workpad_app/workpad_app.component.tsx index d7eafc93ff1a25..5301c00f1f82b8 100644 --- a/x-pack/plugins/canvas/public/components/workpad_app/workpad_app.component.tsx +++ b/x-pack/plugins/canvas/public/components/workpad_app/workpad_app.component.tsx @@ -67,7 +67,6 @@ export const WorkpadApp: FC = ({ deselectElement, isWriteable, workpad })
`); - unmount(); + act(() => { + unmount(); + }); expect(docTitle.reset).toHaveBeenCalledTimes(1); diff --git a/x-pack/plugins/security/public/management/users/edit_user/edit_user_page.tsx b/x-pack/plugins/security/public/management/users/edit_user/edit_user_page.tsx index 231ef70fed5bf9..5fbb81bd7e106f 100644 --- a/x-pack/plugins/security/public/management/users/edit_user/edit_user_page.tsx +++ b/x-pack/plugins/security/public/management/users/edit_user/edit_user_page.tsx @@ -204,8 +204,7 @@ export const EditUserPage: FunctionComponent = ({ username }) diff --git a/x-pack/plugins/security/server/saved_objects/secure_saved_objects_client_wrapper.test.ts b/x-pack/plugins/security/server/saved_objects/secure_saved_objects_client_wrapper.test.ts index 96505d2b5f9638..52702c014f0cb5 100644 --- a/x-pack/plugins/security/server/saved_objects/secure_saved_objects_client_wrapper.test.ts +++ b/x-pack/plugins/security/server/saved_objects/secure_saved_objects_client_wrapper.test.ts @@ -23,11 +23,12 @@ import { Actions } from '../authorization'; import type { SavedObjectActions } from '../authorization/actions/saved_object'; import { SecureSavedObjectsClientWrapper } from './secure_saved_objects_client_wrapper'; -jest.mock('@kbn/core/server/saved_objects/service/lib/utils', () => { - const { SavedObjectsUtils } = jest.requireActual( - '@kbn/core/server/saved_objects/service/lib/utils' +jest.mock('@kbn/core-saved-objects-utils-server', () => { + const { SavedObjectsUtils, ...actual } = jest.requireActual( + '@kbn/core-saved-objects-utils-server' ); return { + ...actual, SavedObjectsUtils: { ...SavedObjectsUtils, createEmptyFindResponse: SavedObjectsUtils.createEmptyFindResponse, diff --git a/x-pack/plugins/security/server/user_profile/user_profile_service.test.ts b/x-pack/plugins/security/server/user_profile/user_profile_service.test.ts index 9254a46c0e8c53..53a8dea9ebb1aa 100644 --- a/x-pack/plugins/security/server/user_profile/user_profile_service.test.ts +++ b/x-pack/plugins/security/server/user_profile/user_profile_service.test.ts @@ -466,21 +466,17 @@ describe('UserProfileService', () => { type: 'accessToken', accessToken: 'some-token', }); - await nextTick(); - jest.runAllTimers(); - - // The first retry. - await nextTick(); - jest.runAllTimers(); - // The second retry. - await nextTick(); - jest.runAllTimers(); + // Re-try 9 more times. + for (const _ of Array.from({ length: 9 })) { + await nextTick(); + jest.runAllTimers(); + } await expect(activatePromise).rejects.toBe(failureReason); expect( mockStartParams.clusterClient.asInternalUser.security.activateUserProfile - ).toHaveBeenCalledTimes(3); + ).toHaveBeenCalledTimes(10); expect( mockStartParams.clusterClient.asInternalUser.security.activateUserProfile ).toHaveBeenCalledWith({ grant_type: 'access_token', access_token: 'some-token' }); diff --git a/x-pack/plugins/security/server/user_profile/user_profile_service.ts b/x-pack/plugins/security/server/user_profile/user_profile_service.ts index 7be2abe07a24a0..7abc9e41504fb5 100644 --- a/x-pack/plugins/security/server/user_profile/user_profile_service.ts +++ b/x-pack/plugins/security/server/user_profile/user_profile_service.ts @@ -28,7 +28,7 @@ import { getPrintableSessionId } from '../session_management'; import type { UserProfileGrant } from './user_profile_grant'; const KIBANA_DATA_ROOT = 'kibana'; -const ACTIVATION_MAX_RETRIES = 3; +const ACTIVATION_MAX_RETRIES = 10; const ACTIVATION_RETRY_SCALE_DURATION_MS = 150; const MAX_SUGGESTIONS_COUNT = 100; const DEFAULT_SUGGESTIONS_COUNT = 10; diff --git a/x-pack/plugins/security_solution/common/endpoint/data_generators/fleet_agent_policy_generator.ts b/x-pack/plugins/security_solution/common/endpoint/data_generators/fleet_agent_policy_generator.ts index 82294ac754fce3..5b99a28e96ee02 100644 --- a/x-pack/plugins/security_solution/common/endpoint/data_generators/fleet_agent_policy_generator.ts +++ b/x-pack/plugins/security_solution/common/endpoint/data_generators/fleet_agent_policy_generator.ts @@ -22,7 +22,6 @@ export class FleetAgentPolicyGenerator extends BaseDataGenerator { const initialNumberOfRules = rules.length; const expectedNumberOfRulesAfterDeletion = initialNumberOfRules - 1; - cy.get(SHOWING_RULES_TEXT).should('have.text', `Showing ${initialNumberOfRules} rules`); + cy.request({ url: '/api/detection_engine/rules/_find' }).then(({ body }) => { + const numberOfRules = body.data.length; + expect(numberOfRules).to.eql(initialNumberOfRules); + }); deleteFirstRule(); waitForRulesTableToBeRefreshed(); @@ -226,10 +228,10 @@ describe('Custom query rules', () => { cy.get(RULES_TABLE) .find(RULES_ROW) .should('have.length', expectedNumberOfRulesAfterDeletion); - cy.get(SHOWING_RULES_TEXT).should( - 'have.text', - `Showing ${expectedNumberOfRulesAfterDeletion} rules` - ); + cy.request({ url: '/api/detection_engine/rules/_find' }).then(({ body }) => { + const numberOfRules = body.data.length; + expect(numberOfRules).to.eql(expectedNumberOfRulesAfterDeletion); + }); cy.get(CUSTOM_RULES_BTN).should( 'have.text', `Custom rules (${expectedNumberOfRulesAfterDeletion})` @@ -253,10 +255,10 @@ describe('Custom query rules', () => { cy.get(RULES_TABLE) .find(RULES_ROW) .should('have.length', expectedNumberOfRulesAfterDeletion); - cy.get(SHOWING_RULES_TEXT).should( - 'have.text', - `Showing ${expectedNumberOfRulesAfterDeletion} rule` - ); + cy.request({ url: '/api/detection_engine/rules/_find' }).then(({ body }) => { + const numberOfRules = body.data.length; + expect(numberOfRules).to.eql(expectedNumberOfRulesAfterDeletion); + }); cy.get(CUSTOM_RULES_BTN).should( 'have.text', `Custom rules (${expectedNumberOfRulesAfterDeletion})` @@ -281,10 +283,10 @@ describe('Custom query rules', () => { cy.get(RULES_TABLE) .find(RULES_ROW) .should('have.length', expectedNumberOfRulesAfterDeletion); - cy.get(SHOWING_RULES_TEXT).should( - 'have.text', - `Showing ${expectedNumberOfRulesAfterDeletion} rules` - ); + cy.request({ url: '/api/detection_engine/rules/_find' }).then(({ body }) => { + const numberOfRules = body.data.length; + expect(numberOfRules).to.eql(expectedNumberOfRulesAfterDeletion); + }); cy.get(CUSTOM_RULES_BTN).should( 'have.text', `Custom rules (${expectedNumberOfRulesAfterDeletion})` diff --git a/x-pack/plugins/security_solution/cypress/integration/detection_rules/prebuilt_rules.spec.ts b/x-pack/plugins/security_solution/cypress/integration/detection_rules/prebuilt_rules.spec.ts index 397162f69d490a..ed5f5629985ae8 100644 --- a/x-pack/plugins/security_solution/cypress/integration/detection_rules/prebuilt_rules.spec.ts +++ b/x-pack/plugins/security_solution/cypress/integration/detection_rules/prebuilt_rules.spec.ts @@ -5,6 +5,7 @@ * 2.0. */ +import { rawRules } from '../../../server/lib/detection_engine/rules/prepackaged_rules'; import { COLLAPSED_ACTION_BTN, ELASTIC_RULES_BTN, @@ -12,11 +13,10 @@ import { RELOAD_PREBUILT_RULES_BTN, RULES_EMPTY_PROMPT, RULE_SWITCH, - SHOWING_RULES_TEXT, RULES_MONITORING_TABLE, SELECT_ALL_RULES_ON_PAGE_CHECKBOX, + RULE_NAME, } from '../../screens/alerts_detection_rules'; - import { deleteFirstRule, deleteSelectedRules, @@ -59,7 +59,16 @@ describe('Prebuilt rules', () => { changeRowsPerPageTo(rowsPerPage); - cy.get(SHOWING_RULES_TEXT).should('have.text', `Showing ${expectedNumberOfRules} rules`); + cy.request({ url: '/api/detection_engine/rules/_find' }).then(({ body }) => { + // Assert the total number of loaded rules equals the expected number of in-memory rules + expect(body.total).to.equal(rawRules.length); + // Assert the table was refreshed with the rules returned by the API request + const ruleNames = rawRules.map((rule) => rule.name); + cy.get(RULE_NAME).each(($item) => { + expect($item.text()).to.be.oneOf(ruleNames); + }); + }); + cy.get(pageSelector(expectedNumberOfPages)).should('exist'); }); diff --git a/x-pack/plugins/security_solution/public/app/home/global_header/index.test.tsx b/x-pack/plugins/security_solution/public/app/home/global_header/index.test.tsx index ff082a27e575ef..48f1109e334439 100644 --- a/x-pack/plugins/security_solution/public/app/home/global_header/index.test.tsx +++ b/x-pack/plugins/security_solution/public/app/home/global_header/index.test.tsx @@ -48,7 +48,7 @@ jest.mock('../../../common/containers/sourcerer/use_signal_helpers', () => ({ jest.mock('react-reverse-portal', () => ({ InPortal: ({ children }: { children: React.ReactNode }) => <>{children}, OutPortal: ({ children }: { children: React.ReactNode }) => <>{children}, - createPortalNode: () => ({ unmount: jest.fn() }), + createHtmlPortalNode: () => ({ unmount: jest.fn() }), })); describe('global header', () => { diff --git a/x-pack/plugins/security_solution/public/app/home/global_header/index.tsx b/x-pack/plugins/security_solution/public/app/home/global_header/index.tsx index e585cf18ca1566..08b3888130836f 100644 --- a/x-pack/plugins/security_solution/public/app/home/global_header/index.tsx +++ b/x-pack/plugins/security_solution/public/app/home/global_header/index.tsx @@ -12,7 +12,7 @@ import { } from '@elastic/eui'; import React, { useCallback, useEffect, useMemo } from 'react'; import { useLocation } from 'react-router-dom'; -import { createPortalNode, InPortal, OutPortal } from 'react-reverse-portal'; +import { createHtmlPortalNode, InPortal, OutPortal } from 'react-reverse-portal'; import { i18n } from '@kbn/i18n'; import type { AppMountParameters } from '@kbn/core/public'; @@ -39,7 +39,7 @@ const BUTTON_ADD_DATA = i18n.translate('xpack.securitySolution.globalHeader.butt */ export const GlobalHeader = React.memo( ({ setHeaderActionMenu }: { setHeaderActionMenu: AppMountParameters['setHeaderActionMenu'] }) => { - const portalNode = useMemo(() => createPortalNode(), []); + const portalNode = useMemo(() => createHtmlPortalNode(), []); const { theme, http: { diff --git a/x-pack/plugins/security_solution/public/app/home/template_wrapper/bottom_bar/index.tsx b/x-pack/plugins/security_solution/public/app/home/template_wrapper/bottom_bar/index.tsx index 407c0db35f49d0..123ae4563f756b 100644 --- a/x-pack/plugins/security_solution/public/app/home/template_wrapper/bottom_bar/index.tsx +++ b/x-pack/plugins/security_solution/public/app/home/template_wrapper/bottom_bar/index.tsx @@ -8,7 +8,7 @@ /* eslint-disable react/display-name */ import React from 'react'; -import type { KibanaPageTemplateProps } from '@kbn/shared-ux-components'; +import type { KibanaPageTemplateProps } from '@kbn/shared-ux-page-kibana-template'; import type { AppLeaveHandler } from '@kbn/core/public'; import { TimelineId } from '../../../../../common/types/timeline'; import { AutoSaveWarningMsg } from '../../../../timelines/components/timeline/auto_save_warning'; diff --git a/x-pack/plugins/security_solution/public/app/home/template_wrapper/index.tsx b/x-pack/plugins/security_solution/public/app/home/template_wrapper/index.tsx index 21db51173ca205..79c7a0899e9c60 100644 --- a/x-pack/plugins/security_solution/public/app/home/template_wrapper/index.tsx +++ b/x-pack/plugins/security_solution/public/app/home/template_wrapper/index.tsx @@ -10,7 +10,7 @@ import styled from 'styled-components'; import { EuiPanel, EuiThemeProvider, useEuiTheme } from '@elastic/eui'; import { IS_DRAGGING_CLASS_NAME } from '@kbn/securitysolution-t-grid'; import type { AppLeaveHandler } from '@kbn/core/public'; -import { KibanaPageTemplate } from '@kbn/shared-ux-components'; +import { KibanaPageTemplate } from '@kbn/shared-ux-page-kibana-template'; import { useSecuritySolutionNavigation } from '../../../common/components/navigation/use_security_solution_navigation'; import { TimelineId } from '../../../../common/types/timeline'; import { getTimelineShowStatusByIdSelector } from '../../../timelines/components/flyout/selectors'; diff --git a/x-pack/plugins/security_solution/public/common/components/event_details/cti_details/threat_summary_view.test.tsx b/x-pack/plugins/security_solution/public/common/components/event_details/cti_details/threat_summary_view.test.tsx index 94c2aa6bc9e8d3..b87c96c34632a6 100644 --- a/x-pack/plugins/security_solution/public/common/components/event_details/cti_details/threat_summary_view.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/event_details/cti_details/threat_summary_view.test.tsx @@ -24,7 +24,7 @@ jest.mock('../../../lib/kibana', () => ({ }), })); -jest.mock('../table/action_cell'); +jest.mock('../table/action_cell', () => ({ ActionCell: () => <> })); jest.mock('../table/field_name_cell'); describe('ThreatSummaryView', () => { diff --git a/x-pack/plugins/security_solution/public/common/components/event_details/event_details.test.tsx b/x-pack/plugins/security_solution/public/common/components/event_details/event_details.test.tsx index cb4affec563d53..eb034eca172dc7 100644 --- a/x-pack/plugins/security_solution/public/common/components/event_details/event_details.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/event_details/event_details.test.tsx @@ -6,6 +6,7 @@ */ import { waitFor } from '@testing-library/dom'; +import { mount } from 'enzyme'; import type { ReactWrapper } from 'enzyme'; import React from 'react'; @@ -15,7 +16,6 @@ import { mockDetailItemData, mockDetailItemDataId, rawEventData, TestProviders } import { EventDetails, EventsViewType } from './event_details'; import { mockBrowserFields } from '../../containers/source/mock'; -import { useMountAppended } from '../../utils/use_mount_appended'; import { mockAlertDetailsData } from './__mocks__'; import type { TimelineEventsDetailsItem } from '../../../../common/search_strategy'; import { TimelineTabs } from '../../../../common/types/timeline'; @@ -44,7 +44,6 @@ jest.mock('../../../detections/containers/detection_engine/rules/use_rule_with_f jest.mock('../link_to'); describe('EventDetails', () => { - const mount = useMountAppended(); const defaultProps = { browserFields: mockBrowserFields, data: mockDetailItemData, diff --git a/x-pack/plugins/security_solution/public/common/components/events_viewer/index.tsx b/x-pack/plugins/security_solution/public/common/components/events_viewer/index.tsx index 0556b3678d4dbc..14921512819eee 100644 --- a/x-pack/plugins/security_solution/public/common/components/events_viewer/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/events_viewer/index.tsx @@ -61,7 +61,6 @@ export interface Props { onRuleChange?: () => void; renderCellValue: (props: CellValueElementProps) => React.ReactNode; rowRenderers: RowRenderer[]; - utilityBar?: (refetch: inputsModel.Refetch, totalCount: number) => React.ReactNode; additionalFilters?: React.ReactNode; hasAlertsCrud?: boolean; unit?: (n: number) => string; @@ -86,7 +85,6 @@ const StatefulEventsViewerComponent: React.FC = ({ rowRenderers, start, scopeId, - utilityBar, additionalFilters, hasAlertsCrud = false, unit, diff --git a/x-pack/plugins/security_solution/public/common/components/events_viewer/selectors/mock_state.ts b/x-pack/plugins/security_solution/public/common/components/events_viewer/selectors/mock_state.ts index 4b51ae9f329a76..3d54f078e70870 100644 --- a/x-pack/plugins/security_solution/public/common/components/events_viewer/selectors/mock_state.ts +++ b/x-pack/plugins/security_solution/public/common/components/events_viewer/selectors/mock_state.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { set } from '@elastic/safer-lodash-set'; +import { set } from '@kbn/safer-lodash-set'; import { pipe } from 'lodash/fp'; import { mockGlobalState } from '../../../mock'; diff --git a/x-pack/plugins/security_solution/public/common/components/filters_global/__snapshots__/filters_global.test.tsx.snap b/x-pack/plugins/security_solution/public/common/components/filters_global/__snapshots__/filters_global.test.tsx.snap index 4dd14f56997ebf..f6734aa75add9e 100644 --- a/x-pack/plugins/security_solution/public/common/components/filters_global/__snapshots__/filters_global.test.tsx.snap +++ b/x-pack/plugins/security_solution/public/common/components/filters_global/__snapshots__/filters_global.test.tsx.snap @@ -2,7 +2,16 @@ exports[`rendering renders correctly 1`] = ` } + node={ + Object { + "element":
, + "elementType": "html", + "getInitialPortalProps": [Function], + "mount": [Function], + "setPortalProps": [Function], + "unmount": [Function], + } + } > ` export const MatrixHistogramComponent: React.FC = ({ chartHeight, defaultStackByOption, - docValueFields, endDate, errorMessage, filterQuery, @@ -176,7 +175,6 @@ export const MatrixHistogramComponent: React.FC = stackByField: selectedStackByOption.value, runtimeMappings, isPtrIncluded, - docValueFields, skip: querySkip, }; const [loading, { data, inspect, totalCount, refetch }] = diff --git a/x-pack/plugins/security_solution/public/common/components/matrix_histogram/types.ts b/x-pack/plugins/security_solution/public/common/components/matrix_histogram/types.ts index 9557e2be557424..49ac62cb572e42 100644 --- a/x-pack/plugins/security_solution/public/common/components/matrix_histogram/types.ts +++ b/x-pack/plugins/security_solution/public/common/components/matrix_histogram/types.ts @@ -15,7 +15,6 @@ import type { InputsModelId } from '../../store/inputs/constants'; import type { MatrixHistogramType } from '../../../../common/search_strategy/security_solution'; import type { UpdateDateRange } from '../charts/common'; import type { GlobalTimeArgs } from '../../containers/use_global_time'; -import type { DocValueFields } from '../../../../common/search_strategy'; import type { FieldValueThreshold } from '../../../detections/components/rules/threshold_input'; import type { GetLensAttributes, LensAttributes } from '../visualization_actions/types'; @@ -66,7 +65,6 @@ interface MatrixHistogramBasicProps { } export interface MatrixHistogramQueryProps { - docValueFields?: DocValueFields[]; endDate: string; errorMessage: string; indexNames: string[]; diff --git a/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/index.test.tsx b/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/index.test.tsx index 1387de4b50a67b..2062765d64a0fb 100644 --- a/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/index.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/index.test.tsx @@ -6,7 +6,7 @@ */ import { renderHook } from '@testing-library/react-hooks'; -import type { KibanaPageTemplateProps } from '@kbn/shared-ux-components'; +import type { KibanaPageTemplateProps } from '@kbn/shared-ux-page-kibana-template'; import { useKibana } from '../../../lib/kibana/kibana_react'; import { useGetUserCasesPermissions } from '../../../lib/kibana'; import { SecurityPageName } from '../../../../app/types'; diff --git a/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/use_primary_navigation.tsx b/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/use_primary_navigation.tsx index 7196431bd77af8..9e83ae9339dcd9 100644 --- a/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/use_primary_navigation.tsx +++ b/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/use_primary_navigation.tsx @@ -8,7 +8,7 @@ import React, { useEffect, useState, useCallback } from 'react'; import { i18n } from '@kbn/i18n'; -import type { KibanaPageTemplateProps } from '@kbn/shared-ux-components'; +import type { KibanaPageTemplateProps } from '@kbn/shared-ux-page-kibana-template'; import type { PrimaryNavigationProps } from './types'; import { usePrimaryNavigationItems } from './use_navigation_items'; import { useIsGroupedNavigationEnabled } from '../helpers'; diff --git a/x-pack/plugins/security_solution/public/common/components/search_bar/index.tsx b/x-pack/plugins/security_solution/public/common/components/search_bar/index.tsx index e833f1f1a5dbd1..b85cd2949de59b 100644 --- a/x-pack/plugins/security_solution/public/common/components/search_bar/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/search_bar/index.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { set } from '@elastic/safer-lodash-set/fp'; +import { set } from '@kbn/safer-lodash-set/fp'; import { getOr } from 'lodash/fp'; import React, { memo, useEffect, useCallback, useMemo } from 'react'; import type { ConnectedProps } from 'react-redux'; diff --git a/x-pack/plugins/security_solution/public/common/components/toasters/index.test.tsx b/x-pack/plugins/security_solution/public/common/components/toasters/index.test.tsx index bb42e99d50518e..bf2249fac5c832 100644 --- a/x-pack/plugins/security_solution/public/common/components/toasters/index.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/toasters/index.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { set } from '@elastic/safer-lodash-set/fp'; +import { set } from '@kbn/safer-lodash-set/fp'; import { cloneDeep } from 'lodash/fp'; import { mount } from 'enzyme'; import React, { useEffect } from 'react'; diff --git a/x-pack/plugins/security_solution/public/common/containers/alerts/use_alert_prevalence_from_process_tree.ts b/x-pack/plugins/security_solution/public/common/containers/alerts/use_alert_prevalence_from_process_tree.ts index 4ea3ff08c2abd5..1a59271614c575 100644 --- a/x-pack/plugins/security_solution/public/common/containers/alerts/use_alert_prevalence_from_process_tree.ts +++ b/x-pack/plugins/security_solution/public/common/containers/alerts/use_alert_prevalence_from_process_tree.ts @@ -4,7 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { useQuery } from 'react-query'; +import { useQuery } from '@tanstack/react-query'; import { useHttp } from '../../lib/kibana'; import { useTimelineDataFilters } from '../../../timelines/containers/use_timeline_data_filters'; diff --git a/x-pack/plugins/security_solution/public/common/containers/matrix_histogram/index.ts b/x-pack/plugins/security_solution/public/common/containers/matrix_histogram/index.ts index 8fef932c991a4a..c770713b602b7c 100644 --- a/x-pack/plugins/security_solution/public/common/containers/matrix_histogram/index.ts +++ b/x-pack/plugins/security_solution/public/common/containers/matrix_histogram/index.ts @@ -6,7 +6,7 @@ */ import deepEqual from 'fast-deep-equal'; -import { getOr, isEmpty, noop } from 'lodash/fp'; +import { getOr, noop } from 'lodash/fp'; import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { Subscription } from 'rxjs'; @@ -48,7 +48,6 @@ export interface UseMatrixHistogramArgs { } export const useMatrixHistogram = ({ - docValueFields, endDate, errorMessage, filterQuery, @@ -88,7 +87,6 @@ export const useMatrixHistogram = ({ runtimeMappings, threshold, ...(isPtrIncluded != null ? { isPtrIncluded } : {}), - ...(!isEmpty(docValueFields) ? { docValueFields } : {}), ...(includeMissingData != null ? { includeMissingData } : {}), }); const { addError, addWarning } = useAppToasts(); @@ -171,7 +169,6 @@ export const useMatrixHistogram = ({ stackByField, threshold, ...(isPtrIncluded != null ? { isPtrIncluded } : {}), - ...(!isEmpty(docValueFields) ? { docValueFields } : {}), }; if (!deepEqual(prevRequest, myRequest)) { return myRequest; @@ -187,7 +184,6 @@ export const useMatrixHistogram = ({ histogramType, threshold, isPtrIncluded, - docValueFields, ]); useEffect(() => { diff --git a/x-pack/plugins/security_solution/public/common/containers/query_client/query_client_provider.tsx b/x-pack/plugins/security_solution/public/common/containers/query_client/query_client_provider.tsx index 20fd3d09ad5931..7feaf9c8653efe 100644 --- a/x-pack/plugins/security_solution/public/common/containers/query_client/query_client_provider.tsx +++ b/x-pack/plugins/security_solution/public/common/containers/query_client/query_client_provider.tsx @@ -7,7 +7,7 @@ import type { PropsWithChildren } from 'react'; import React, { memo, useMemo } from 'react'; -import { QueryClient, QueryClientProvider } from 'react-query'; +import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; type QueryClientOptionsProp = ConstructorParameters[0]; diff --git a/x-pack/plugins/security_solution/public/common/containers/source/index.test.tsx b/x-pack/plugins/security_solution/public/common/containers/source/index.test.tsx index 24d58a665177b9..40a473de306871 100644 --- a/x-pack/plugins/security_solution/public/common/containers/source/index.test.tsx +++ b/x-pack/plugins/security_solution/public/common/containers/source/index.test.tsx @@ -102,7 +102,6 @@ describe('source/index.tsx', () => { expect(payload.id).toEqual('neato'); expect(Object.keys(payload.browserFields)).toHaveLength(12); expect(Object.keys(payload.indexFields)).toHaveLength(mocksSource.indexFields.length); - expect(payload.docValueFields).toEqual([{ field: '@timestamp' }]); }); it('should reuse the result for dataView info when cleanCache not passed', async () => { @@ -120,23 +119,18 @@ describe('source/index.tsx', () => { await indexFieldsSearch!({ dataViewId: 'neato' }); const { - payload: { browserFields, indexFields, docValueFields }, + payload: { browserFields, indexFields }, } = mockDispatch.mock.calls[1][0]; mockDispatch.mockClear(); await indexFieldsSearch!({ dataViewId: 'neato' }); const { - payload: { - browserFields: newBrowserFields, - indexFields: newIndexFields, - docValueFields: newDocValueFields, - }, + payload: { browserFields: newBrowserFields, indexFields: newIndexFields }, } = mockDispatch.mock.calls[1][0]; expect(browserFields).toBe(newBrowserFields); expect(indexFields).toBe(newIndexFields); - expect(docValueFields).toBe(newDocValueFields); }); it('should not reuse the result for dataView info when cleanCache passed', async () => { @@ -154,23 +148,18 @@ describe('source/index.tsx', () => { await indexFieldsSearch!({ dataViewId: 'neato' }); const { - payload: { browserFields, indexFields, docValueFields }, + payload: { browserFields, indexFields }, } = mockDispatch.mock.calls[1][0]; mockDispatch.mockClear(); await indexFieldsSearch!({ dataViewId: 'neato', cleanCache: true }); const { - payload: { - browserFields: newBrowserFields, - indexFields: newIndexFields, - docValueFields: newDocValueFields, - }, + payload: { browserFields: newBrowserFields, indexFields: newIndexFields }, } = mockDispatch.mock.calls[1][0]; expect(browserFields).not.toBe(newBrowserFields); expect(indexFields).not.toBe(newIndexFields); - expect(docValueFields).not.toBe(newDocValueFields); }); }); }); diff --git a/x-pack/plugins/security_solution/public/common/containers/source/index.tsx b/x-pack/plugins/security_solution/public/common/containers/source/index.tsx index 68beb34712a6e0..7f420fbf085daf 100644 --- a/x-pack/plugins/security_solution/public/common/containers/source/index.tsx +++ b/x-pack/plugins/security_solution/public/common/containers/source/index.tsx @@ -15,7 +15,6 @@ import { Subscription } from 'rxjs'; import type { BrowserField, BrowserFields, - DocValueFields, IndexField, IndexFieldsStrategyRequest, IndexFieldsStrategyResponse, @@ -26,7 +25,7 @@ import * as i18n from './translations'; import { useAppToasts } from '../../hooks/use_app_toasts'; import { getDataViewStateFromIndexFields } from './use_data_view'; -export type { BrowserField, BrowserFields, DocValueFields }; +export type { BrowserField, BrowserFields }; export function getAllBrowserFields(browserFields: BrowserFields): Array> { const result: Array> = []; @@ -86,11 +85,8 @@ export const getBrowserFields = memoizeOne( const DEFAULT_BROWSER_FIELDS = {}; const DEFAULT_INDEX_PATTERNS = { fields: [], title: '' }; -const DEFAULT_DOC_VALUE_FIELDS: DocValueFields[] = []; - interface FetchIndexReturn { browserFields: BrowserFields; - docValueFields: DocValueFields[]; indexes: string[]; indexExists: boolean; indexPatterns: DataViewBase; @@ -112,7 +108,6 @@ export const useFetchIndex = ( const [state, setState] = useState({ browserFields: DEFAULT_BROWSER_FIELDS, - docValueFields: DEFAULT_DOC_VALUE_FIELDS, indexes: indexNames, indexExists: true, indexPatterns: DEFAULT_INDEX_PATTERNS, @@ -140,14 +135,13 @@ export const useFetchIndex = ( const stringifyIndices = response.indicesExist.sort().join(); previousIndexesName.current = response.indicesExist; - const { browserFields, docValueFields } = getDataViewStateFromIndexFields( + const { browserFields } = getDataViewStateFromIndexFields( stringifyIndices, response.indexFields ); setLoading(false); setState({ browserFields, - docValueFields, indexes: response.indicesExist, indexExists: response.indicesExist.length > 0, indexPatterns: getIndexFields(stringifyIndices, response.indexFields), diff --git a/x-pack/plugins/security_solution/public/common/containers/source/mock.ts b/x-pack/plugins/security_solution/public/common/containers/source/mock.ts index 607225ff62e57a..956275d43bac7b 100644 --- a/x-pack/plugins/security_solution/public/common/containers/source/mock.ts +++ b/x-pack/plugins/security_solution/public/common/containers/source/mock.ts @@ -7,7 +7,6 @@ import type { MappingRuntimeFields } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import { DEFAULT_INDEX_PATTERN } from '../../../../common/constants'; -import type { DocValueFields } from '../../../../common/search_strategy'; import type { BrowserFields } from '../../../../common/search_strategy/index_fields'; export const mocksSource = { @@ -957,17 +956,6 @@ export const mockBrowserFields: BrowserFields = { }, }; -export const mockDocValueFields: DocValueFields[] = [ - { - field: '@timestamp', - format: 'date_time', - }, - { - field: 'event.end', - format: 'date_time', - }, -]; - export const mockRuntimeMappings: MappingRuntimeFields = { '@a.runtime.field': { script: { diff --git a/x-pack/plugins/security_solution/public/common/containers/source/use_data_view.tsx b/x-pack/plugins/security_solution/public/common/containers/source/use_data_view.tsx index 49cf89e0de1b01..51ad895b56f0ca 100644 --- a/x-pack/plugins/security_solution/public/common/containers/source/use_data_view.tsx +++ b/x-pack/plugins/security_solution/public/common/containers/source/use_data_view.tsx @@ -12,7 +12,6 @@ import memoizeOne from 'memoize-one'; import { omit, pick } from 'lodash/fp'; import type { BrowserField, - DocValueFields, IndexField, IndexFieldsStrategyRequest, IndexFieldsStrategyResponse, @@ -40,7 +39,6 @@ type DangerCastForBrowserFieldsMutation = Record< >; interface DataViewInfo { browserFields: DangerCastForBrowserFieldsMutation; - docValueFields: DocValueFields[]; indexFields: FieldSpec[]; } @@ -69,17 +67,10 @@ export const getDataViewStateFromIndexFields = memoizeOne( pick(['name', 'searchable', 'type', 'aggregatable', 'esTypes', 'subType'], field) ); - // mutate docValueFields - if (field.readFromDocValues && acc.docValueFields.length < 100) { - acc.docValueFields.push({ - field: field.name, - }); - } return acc; }, { browserFields: {}, - docValueFields: [], indexFields: [], } ); diff --git a/x-pack/plugins/security_solution/public/common/containers/sourcerer/index.tsx b/x-pack/plugins/security_solution/public/common/containers/sourcerer/index.tsx index effd5196dd9bcc..6db7392b596b72 100644 --- a/x-pack/plugins/security_solution/public/common/containers/sourcerer/index.tsx +++ b/x-pack/plugins/security_solution/public/common/containers/sourcerer/index.tsx @@ -408,7 +408,6 @@ export const useSourcererDataView = ( () => ({ browserFields: sourcererDataView.browserFields, dataViewId: sourcererDataView.id, - docValueFields: sourcererDataView.docValueFields, indexPattern: { fields: sourcererDataView.indexFields, title: selectedPatterns.join(','), diff --git a/x-pack/plugins/security_solution/public/common/containers/sourcerer/readme.md b/x-pack/plugins/security_solution/public/common/containers/sourcerer/readme.md index d6edb9794dc8b3..b8672d7a9edc7d 100644 --- a/x-pack/plugins/security_solution/public/common/containers/sourcerer/readme.md +++ b/x-pack/plugins/security_solution/public/common/containers/sourcerer/readme.md @@ -16,7 +16,6 @@ interface SelectedDataView { browserFields: SourcererDataView['browserFields']; dataViewId: string | null; // null if legacy pre-8.0 timeline - docValueFields: SourcererDataView['docValueFields']; /** * DataViewBase with enhanced index fields used in timelines */ diff --git a/x-pack/plugins/security_solution/public/common/hooks/use_global_header_portal.tsx b/x-pack/plugins/security_solution/public/common/hooks/use_global_header_portal.tsx index 8e8d73ff12849e..c240f102d5e676 100644 --- a/x-pack/plugins/security_solution/public/common/hooks/use_global_header_portal.tsx +++ b/x-pack/plugins/security_solution/public/common/hooks/use_global_header_portal.tsx @@ -6,12 +6,12 @@ */ import { useState } from 'react'; -import { createPortalNode } from 'react-reverse-portal'; +import { createHtmlPortalNode } from 'react-reverse-portal'; /** * A singleton portal for rendering content in the global header */ -const globalKQLHeaderPortalNodeSingleton = createPortalNode(); +const globalKQLHeaderPortalNodeSingleton = createHtmlPortalNode(); export const useGlobalHeaderPortal = () => { const [globalKQLHeaderPortalNode] = useState(globalKQLHeaderPortalNodeSingleton); diff --git a/x-pack/plugins/security_solution/public/common/hooks/use_timeline_events_count.tsx b/x-pack/plugins/security_solution/public/common/hooks/use_timeline_events_count.tsx index e801db0190799d..e6e744fdd4b2e0 100644 --- a/x-pack/plugins/security_solution/public/common/hooks/use_timeline_events_count.tsx +++ b/x-pack/plugins/security_solution/public/common/hooks/use_timeline_events_count.tsx @@ -6,13 +6,13 @@ */ import React, { useState } from 'react'; -import { createPortalNode, OutPortal } from 'react-reverse-portal'; +import { createHtmlPortalNode, OutPortal } from 'react-reverse-portal'; /** * A singleton portal for rendering content in the global header */ -const timelineEventsCountPortalNodeSingleton = createPortalNode(); -const eqlEventsCountPortalNodeSingleton = createPortalNode(); +const timelineEventsCountPortalNodeSingleton = createHtmlPortalNode(); +const eqlEventsCountPortalNodeSingleton = createHtmlPortalNode(); export const useTimelineEventsCountPortal = () => { const [timelineEventsCountPortalNode] = useState(timelineEventsCountPortalNodeSingleton); diff --git a/x-pack/plugins/security_solution/public/common/lib/kibana/hooks.ts b/x-pack/plugins/security_solution/public/common/lib/kibana/hooks.ts index b7c22f4398f918..4a736fc622055d 100644 --- a/x-pack/plugins/security_solution/public/common/lib/kibana/hooks.ts +++ b/x-pack/plugins/security_solution/public/common/lib/kibana/hooks.ts @@ -11,7 +11,7 @@ import { useCallback, useEffect, useState, useRef } from 'react'; import { i18n } from '@kbn/i18n'; import { camelCase, isArray, isObject } from 'lodash'; -import { set } from '@elastic/safer-lodash-set'; +import { set } from '@kbn/safer-lodash-set'; import type { AuthenticatedUser } from '@kbn/security-plugin/common/model'; import type { Capabilities, NavigateToAppOptions } from '@kbn/core/public'; import type { CasesPermissions } from '@kbn/cases-plugin/common/ui'; diff --git a/x-pack/plugins/security_solution/public/common/mock/endpoint/app_context_render.tsx b/x-pack/plugins/security_solution/public/common/mock/endpoint/app_context_render.tsx index b4987a6080342a..4ed453a4ce0a36 100644 --- a/x-pack/plugins/security_solution/public/common/mock/endpoint/app_context_render.tsx +++ b/x-pack/plugins/security_solution/public/common/mock/endpoint/app_context_render.tsx @@ -13,7 +13,7 @@ import type { RenderOptions, RenderResult } from '@testing-library/react'; import { render as reactRender } from '@testing-library/react'; import type { Action, Reducer, Store } from 'redux'; import type { AppDeepLink } from '@kbn/core/public'; -import { QueryClient, QueryClientProvider, setLogger } from 'react-query'; +import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { coreMock } from '@kbn/core/public/mocks'; import { PLUGIN_ID } from '@kbn/fleet-plugin/common'; import type { RenderHookOptions, RenderHookResult } from '@testing-library/react-hooks'; @@ -22,7 +22,7 @@ import type { ReactHooksRenderer, WrapperComponent, } from '@testing-library/react-hooks/src/types/react'; -import type { UseBaseQueryResult } from 'react-query/types/react/types'; +import type { UseBaseQueryResult } from '@tanstack/react-query'; import ReactDOM from 'react-dom'; import { ConsoleManager } from '../../../management/components/console'; import type { StartPlugins, StartServices } from '../../../types'; @@ -89,7 +89,6 @@ export type WaitForReactHookState = | 'isSuccess' | 'isLoading' | 'isError' - | 'isIdle' | 'isLoadingError' | 'isStale' | 'isFetched' @@ -117,15 +116,6 @@ export type ReactQueryHookRenderer< options?: RenderHookOptions ) => Promise; -// hide react-query output in console -setLogger({ - error: () => {}, - // eslint-disable-next-line no-console - log: console.log, - // eslint-disable-next-line no-console - warn: console.warn, -}); - /** * Mocked app root context renderer */ @@ -228,6 +218,14 @@ export const createAppRootMockRenderer = (): AppContextTestRender => { cacheTime: Infinity, }, }, + // hide react-query output in console + logger: { + error: () => {}, + // eslint-disable-next-line no-console + log: console.log, + // eslint-disable-next-line no-console + warn: console.warn, + }, }); const AppWrapper: React.FC<{ children: React.ReactElement }> = ({ children }) => ( diff --git a/x-pack/plugins/security_solution/public/common/mock/global_state.ts b/x-pack/plugins/security_solution/public/common/mock/global_state.ts index 027827474c780b..17f5e4d9be8f8d 100644 --- a/x-pack/plugins/security_solution/public/common/mock/global_state.ts +++ b/x-pack/plugins/security_solution/public/common/mock/global_state.ts @@ -34,12 +34,7 @@ import type { ManagementState } from '../../management/types'; import { initialSourcererState, SourcererScopeName } from '../store/sourcerer/model'; import { allowedExperimentalValues } from '../../../common/experimental_features'; import { getScopePatternListSelection } from '../store/sourcerer/helpers'; -import { - mockBrowserFields, - mockDocValueFields, - mockIndexFields, - mockRuntimeMappings, -} from '../containers/source/mock'; +import { mockBrowserFields, mockIndexFields, mockRuntimeMappings } from '../containers/source/mock'; import { usersModel } from '../../users/store'; import { UsersFields } from '../../../common/search_strategy/security_solution/users/common'; @@ -49,7 +44,6 @@ export const mockSourcererState = { defaultDataView: { ...initialSourcererState.defaultDataView, browserFields: mockBrowserFields, - docValueFields: mockDocValueFields, id: DEFAULT_DATA_VIEW_ID, indexFields: mockIndexFields, loading: false, diff --git a/x-pack/plugins/security_solution/public/common/mock/test_providers.tsx b/x-pack/plugins/security_solution/public/common/mock/test_providers.tsx index 41d68949daccbf..3907232cc1120d 100644 --- a/x-pack/plugins/security_solution/public/common/mock/test_providers.tsx +++ b/x-pack/plugins/security_solution/public/common/mock/test_providers.tsx @@ -16,7 +16,7 @@ import type { Store } from 'redux'; import { BehaviorSubject } from 'rxjs'; import { ThemeProvider } from 'styled-components'; import type { Capabilities } from '@kbn/core/public'; -import { QueryClient, QueryClientProvider } from 'react-query'; +import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { ConsoleManager } from '../../management/components/console'; import type { State } from '../store'; diff --git a/x-pack/plugins/security_solution/public/common/store/sourcerer/actions.ts b/x-pack/plugins/security_solution/public/common/store/sourcerer/actions.ts index 2abd8a7a50919f..f452d34cba3107 100644 --- a/x-pack/plugins/security_solution/public/common/store/sourcerer/actions.ts +++ b/x-pack/plugins/security_solution/public/common/store/sourcerer/actions.ts @@ -19,7 +19,6 @@ const actionCreator = actionCreatorFactory('x-pack/security_solution/local/sourc export const setDataView = actionCreator<{ browserFields: SourcererDataView['browserFields']; - docValueFields: SourcererDataView['docValueFields']; id: SourcererDataView['id']; indexFields: SourcererDataView['indexFields']; loading: SourcererDataView['loading']; diff --git a/x-pack/plugins/security_solution/public/common/store/sourcerer/model.ts b/x-pack/plugins/security_solution/public/common/store/sourcerer/model.ts index 3b35db56f4d0b7..e4d16f2079dba8 100644 --- a/x-pack/plugins/security_solution/public/common/store/sourcerer/model.ts +++ b/x-pack/plugins/security_solution/public/common/store/sourcerer/model.ts @@ -6,12 +6,8 @@ */ import type { MappingRuntimeFields } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; -import type { BrowserFields, DocValueFields } from '@kbn/timelines-plugin/common'; -import { - EMPTY_BROWSER_FIELDS, - EMPTY_DOCVALUE_FIELD, - EMPTY_INDEX_FIELDS, -} from '@kbn/timelines-plugin/common'; +import type { BrowserFields } from '@kbn/timelines-plugin/common'; +import { EMPTY_BROWSER_FIELDS, EMPTY_INDEX_FIELDS } from '@kbn/timelines-plugin/common'; import type { SecuritySolutionDataViewBase } from '../../types'; /** Uniquely identifies a Sourcerer Scope */ export enum SourcererScopeName { @@ -64,8 +60,6 @@ export interface SourcererDataView extends KibanaDataView { * category, description, format * indices the field is included in etc*/ browserFields: BrowserFields; - /** query DSL field and format */ - docValueFields: DocValueFields[]; /** comes from dataView.fields.toSpec() */ indexFields: SecuritySolutionDataViewBase['fields']; /** set when data view fields are fetched */ @@ -84,7 +78,6 @@ export interface SourcererDataView extends KibanaDataView { export interface SelectedDataView { browserFields: SourcererDataView['browserFields']; dataViewId: string | null; // null if legacy pre-8.0 timeline - docValueFields: SourcererDataView['docValueFields']; /** * DataViewBase with enhanced index fields used in timelines */ @@ -131,7 +124,6 @@ export const initSourcererScope: Omit = { }; export const initDataView = { browserFields: EMPTY_BROWSER_FIELDS, - docValueFields: EMPTY_DOCVALUE_FIELD, id: '', indexFields: EMPTY_INDEX_FIELDS, loading: false, diff --git a/x-pack/plugins/security_solution/public/common/store/sourcerer/readme.md b/x-pack/plugins/security_solution/public/common/store/sourcerer/readme.md index 6dbc8f5ad817cb..28059371804c90 100644 --- a/x-pack/plugins/security_solution/public/common/store/sourcerer/readme.md +++ b/x-pack/plugins/security_solution/public/common/store/sourcerer/readme.md @@ -69,7 +69,6 @@ interface SourcererDataView extends KibanaDataView { * indices the field is included in etc*/ browserFields: BrowserFields; /** query DSL field and format */ - docValueFields: DocValueFields[]; /** comes from dataView.fields.toSpec() */ indexFields: SecuritySolutionDataViewBase['fields']; /** set when data view fields are fetched */ diff --git a/x-pack/plugins/security_solution/public/common/utils/alerts.ts b/x-pack/plugins/security_solution/public/common/utils/alerts.ts index 461adbcc6e8c13..e0d497ba9e3f8b 100644 --- a/x-pack/plugins/security_solution/public/common/utils/alerts.ts +++ b/x-pack/plugins/security_solution/public/common/utils/alerts.ts @@ -9,7 +9,6 @@ import { merge } from '@kbn/std'; import { isPlainObject } from 'lodash'; import type { Ecs } from '@kbn/cases-plugin/common'; -// TODO we need to allow -> docValueFields: [{ field: "@timestamp" }], export const buildAlertsQuery = (alertIds: string[]) => { if (alertIds.length === 0) { return {}; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_monitoring/components/execution_events_table/use_execution_events.test.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_monitoring/components/execution_events_table/use_execution_events.test.tsx index 9a62fd58a0fbcb..5e07dadf024921 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_monitoring/components/execution_events_table/use_execution_events.test.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_monitoring/components/execution_events_table/use_execution_events.test.tsx @@ -6,7 +6,7 @@ */ import React from 'react'; -import { QueryClient, QueryClientProvider } from 'react-query'; +import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { renderHook, cleanup } from '@testing-library/react-hooks'; import { diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_monitoring/components/execution_events_table/use_execution_events.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_monitoring/components/execution_events_table/use_execution_events.ts index 4a37f55dc1d6a7..8c0a698eac43f4 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_monitoring/components/execution_events_table/use_execution_events.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_monitoring/components/execution_events_table/use_execution_events.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { useQuery } from 'react-query'; +import { useQuery } from '@tanstack/react-query'; import { useAppToasts } from '../../../../common/hooks/use_app_toasts'; import type { GetRuleExecutionEventsResponse } from '../../../../../common/detection_engine/rule_monitoring'; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_monitoring/components/execution_results_table/use_execution_results.test.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_monitoring/components/execution_results_table/use_execution_results.test.tsx index 63565f7cfa1b50..ddb553998584f7 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_monitoring/components/execution_results_table/use_execution_results.test.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_monitoring/components/execution_results_table/use_execution_results.test.tsx @@ -6,7 +6,7 @@ */ import React from 'react'; -import { QueryClient, QueryClientProvider } from 'react-query'; +import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { renderHook, cleanup } from '@testing-library/react-hooks'; import { useExecutionResults } from './use_execution_results'; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_monitoring/components/execution_results_table/use_execution_results.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_monitoring/components/execution_results_table/use_execution_results.tsx index a07289969af12b..001c0bc1539616 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_monitoring/components/execution_results_table/use_execution_results.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_monitoring/components/execution_results_table/use_execution_results.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { useQuery } from 'react-query'; +import { useQuery } from '@tanstack/react-query'; import { useAppToasts } from '../../../../common/hooks/use_app_toasts'; import type { GetRuleExecutionResultsResponse } from '../../../../../common/detection_engine/rule_monitoring'; diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/additional_filters_action/index.test.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/additional_filters_action/index.test.tsx new file mode 100644 index 00000000000000..ec4fdb5cb6e8d7 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/additional_filters_action/index.test.tsx @@ -0,0 +1,80 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { render, screen, fireEvent } from '@testing-library/react'; + +import { AdditionalFiltersAction } from '.'; +import { TestProviders } from '../../../../common/mock/test_providers'; + +jest.useFakeTimers(); +jest.mock('../../../../common/lib/kibana'); + +describe('AdditionalFiltersAction', () => { + describe('UtilityBarAdditionalFiltersContent', () => { + test('does not show the showBuildingBlockAlerts checked if the showBuildingBlockAlerts is false', async () => { + const onShowBuildingBlockAlertsChanged = jest.fn(); + render( + + + + ); + // click the filters button to popup the checkbox to make it visible + const additionalFiltersButton = screen.findByTestId('additionalFilters-popover'); + fireEvent.click(await additionalFiltersButton); + + // The check box should be false + expect(await screen.findByTestId('showBuildingBlockAlertsCheckbox')).not.toBeChecked(); + }); + + test('does not show the showOnlyThreatIndicatorAlerts checked if the showOnlyThreatIndicatorAlerts is true', async () => { + render( + + + + ); + // click the filters button to popup the checkbox to make it visible + const additionalFiltersButton = screen.findByTestId('additionalFilters-popover'); + fireEvent.click(await additionalFiltersButton); + + expect(await screen.findByTestId('showOnlyThreatIndicatorAlertsCheckbox')).toBeChecked(); + }); + + test('does show the showBuildingBlockAlerts checked if the showBuildingBlockAlerts is true', async () => { + const onShowBuildingBlockAlertsChanged = jest.fn(); + render( + + + + ); + // click the filters button to popup the checkbox to make it visible + const additionalFiltersButton = screen.findByTestId('additionalFilters-popover'); + fireEvent.click(await additionalFiltersButton); + + // The check box should be true + expect(await screen.findByTestId('showBuildingBlockAlertsCheckbox')).toBeChecked(); + }); + }); +}); diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/additional_filters_action/index.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/additional_filters_action/index.tsx new file mode 100644 index 00000000000000..ef780f783e9241 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/additional_filters_action/index.tsx @@ -0,0 +1,94 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { useCallback } from 'react'; + +import { EuiFlexGroup, EuiFlexItem, EuiCheckbox } from '@elastic/eui'; +import styled from 'styled-components'; + +import { UtilityBarAction } from '../../../../common/components/utility_bar'; +import * as i18n from './translations'; + +const UtilityBarFlexGroup = styled(EuiFlexGroup)` + min-width: 175px; +`; + +const AdditionalFiltersItem = styled(EuiFlexItem)` + padding: ${({ theme }) => theme.eui.euiSizeS}; +`; + +const BuildingBlockContainer = styled(AdditionalFiltersItem)` + background: ${({ theme }) => theme.eui.euiColorHighlight}; +`; + +export const AdditionalFiltersAction = ({ + areEventsLoading, + onShowBuildingBlockAlertsChanged, + showBuildingBlockAlerts, + onShowOnlyThreatIndicatorAlertsChanged, + showOnlyThreatIndicatorAlerts, +}: { + areEventsLoading: boolean; + onShowBuildingBlockAlertsChanged: (showBuildingBlockAlerts: boolean) => void; + showBuildingBlockAlerts: boolean; + onShowOnlyThreatIndicatorAlertsChanged: (showOnlyThreatIndicatorAlerts: boolean) => void; + showOnlyThreatIndicatorAlerts: boolean; +}) => { + const UtilityBarAdditionalFiltersContent = useCallback( + (closePopover: () => void) => ( + + + ) => { + closePopover(); + onShowBuildingBlockAlertsChanged(e.target.checked); + }} + checked={showBuildingBlockAlerts} + color="text" + data-test-subj="showBuildingBlockAlertsCheckbox" + label={i18n.ADDITIONAL_FILTERS_ACTIONS_SHOW_BUILDING_BLOCK} + /> + + + ) => { + closePopover(); + onShowOnlyThreatIndicatorAlertsChanged(e.target.checked); + }} + checked={showOnlyThreatIndicatorAlerts} + color="text" + data-test-subj="showOnlyThreatIndicatorAlertsCheckbox" + label={i18n.ADDITIONAL_FILTERS_ACTIONS_SHOW_ONLY_THREAT_INDICATOR_ALERTS} + /> + + + ), + [ + onShowBuildingBlockAlertsChanged, + onShowOnlyThreatIndicatorAlertsChanged, + showBuildingBlockAlerts, + showOnlyThreatIndicatorAlerts, + ] + ); + + return ( + + {i18n.ADDITIONAL_FILTERS_ACTIONS} + + ); +}; diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/additional_filters_action/translations.ts b/x-pack/plugins/security_solution/public/detections/components/alerts_table/additional_filters_action/translations.ts new file mode 100644 index 00000000000000..eb421c67ff39a5 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/additional_filters_action/translations.ts @@ -0,0 +1,36 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { i18n } from '@kbn/i18n'; + +export const ADDITIONAL_FILTERS_ACTIONS = i18n.translate( + 'xpack.securitySolution.detectionEngine.alerts.utilityBar.additionalFiltersTitle', + { + defaultMessage: 'Additional filters', + } +); + +export const ADDITIONAL_FILTERS_ACTIONS_SHOW_BUILDING_BLOCK = i18n.translate( + 'xpack.securitySolution.detectionEngine.alerts.utilityBar.additionalFiltersActions.showBuildingBlockTitle', + { + defaultMessage: 'Include building block alerts', + } +); + +export const ADDITIONAL_FILTERS_ACTIONS_SHOW_ONLY_THREAT_INDICATOR_ALERTS = i18n.translate( + 'xpack.securitySolution.detectionEngine.alerts.utilityBar.additionalFiltersActions.showOnlyThreatIndicatorAlerts', + { + defaultMessage: 'Show only threat indicator alerts', + } +); + +export const TAKE_ACTION = i18n.translate( + 'xpack.securitySolution.detectionEngine.alerts.utilityBar.takeActionTitle', + { + defaultMessage: 'Take action', + } +); diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_utility_bar/index.test.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_utility_bar/index.test.tsx deleted file mode 100644 index f4372631cf0f45..00000000000000 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_utility_bar/index.test.tsx +++ /dev/null @@ -1,419 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React from 'react'; -import { shallow, mount } from 'enzyme'; - -import type { AlertsUtilityBarProps } from '.'; -import { AlertsUtilityBar } from '.'; -import { TestProviders } from '../../../../common/mock/test_providers'; - -jest.useFakeTimers(); -jest.mock('../../../../common/lib/kibana'); - -describe('AlertsUtilityBar', () => { - test('renders correctly', () => { - const wrapper = shallow( - - ); - - expect(wrapper.find('[dataTestSubj="alertActionPopover"]')).toBeTruthy(); - }); - - describe('UtilityBarAdditionalFiltersContent', () => { - test('does not show the showBuildingBlockAlerts checked if the showBuildingBlockAlerts is false', () => { - const onShowBuildingBlockAlertsChanged = jest.fn(); - const wrapper = mount( - - - - ); - // click the filters button to popup the checkbox to make it visible - wrapper - .find('[data-test-subj="additionalFilters"] button') - .first() - .simulate('click') - .update(); - - // The check box should be false - expect( - wrapper - .find('[data-test-subj="showBuildingBlockAlertsCheckbox"] input') - .first() - .prop('checked') - ).toEqual(false); - }); - - test('does not show the showOnlyThreatIndicatorAlerts checked if the showThreatMatchOnly is false', () => { - const wrapper = mount( - - - - ); - // click the filters button to popup the checkbox to make it visible - wrapper - .find('[data-test-subj="additionalFilters"] button') - .first() - .simulate('click') - .update(); - - // The check box should be false - expect( - wrapper - .find('[data-test-subj="showOnlyThreatIndicatorAlertsCheckbox"] input') - .first() - .prop('checked') - ).toEqual(false); - }); - - test('does show the showBuildingBlockAlerts checked if the showBuildingBlockAlerts is true', () => { - const onShowBuildingBlockAlertsChanged = jest.fn(); - const wrapper = mount( - - - - ); - // click the filters button to popup the checkbox to make it visible - wrapper - .find('[data-test-subj="additionalFilters"] button') - .first() - .simulate('click') - .update(); - - // The check box should be true - expect( - wrapper - .find('[data-test-subj="showBuildingBlockAlertsCheckbox"] input') - .first() - .prop('checked') - ).toEqual(true); - }); - - test('does show the showOnlyThreatIndicatorAlerts checked if the showOnlyThreatIndicatorAlerts is true', () => { - const wrapper = mount( - - - - ); - // click the filters button to popup the checkbox to make it visible - wrapper - .find('[data-test-subj="additionalFilters"] button') - .first() - .simulate('click') - .update(); - - // The check box should be true - expect( - wrapper - .find('[data-test-subj="showOnlyThreatIndicatorAlertsCheckbox"] input') - .first() - .prop('checked') - ).toEqual(true); - }); - - test('calls the onShowBuildingBlockAlertsChanged when the check box is clicked', () => { - const onShowBuildingBlockAlertsChanged = jest.fn(); - const wrapper = mount( - - - - ); - // click the filters button to popup the checkbox to make it visible - wrapper - .find('[data-test-subj="additionalFilters"] button') - .first() - .simulate('click') - .update(); - - // check the box - wrapper - .find('[data-test-subj="showBuildingBlockAlertsCheckbox"] input') - .first() - .simulate('change', { target: { checked: true } }); - - // Make sure our callback is called - expect(onShowBuildingBlockAlertsChanged).toHaveBeenCalled(); - }); - - test('calls the onShowOnlyThreatIndicatorAlertsChanged when the check box is clicked', () => { - const onShowOnlyThreatIndicatorAlertsChanged = jest.fn(); - const wrapper = mount( - - - - ); - // click the filters button to popup the checkbox to make it visible - wrapper - .find('[data-test-subj="additionalFilters"] button') - .first() - .simulate('click') - .update(); - - // check the box - wrapper - .find('[data-test-subj="showOnlyThreatIndicatorAlertsCheckbox"] input') - .first() - .simulate('change', { target: { checked: true } }); - - // Make sure our callback is called - expect(onShowOnlyThreatIndicatorAlertsChanged).toHaveBeenCalled(); - }); - - test('can update showBuildingBlockAlerts from false to true', () => { - const Proxy = (props: AlertsUtilityBarProps) => ( - - - - ); - - const wrapper = mount( - - ); - // click the filters button to popup the checkbox to make it visible - wrapper - .find('[data-test-subj="additionalFilters"] button') - .first() - .simulate('click') - .update(); - - // The check box should false now since we initially set the showBuildingBlockAlerts to false - expect( - wrapper - .find('[data-test-subj="showBuildingBlockAlertsCheckbox"] input') - .first() - .prop('checked') - ).toEqual(false); - - wrapper.setProps({ showBuildingBlockAlerts: true }); - wrapper.update(); - - // click the filters button to popup the checkbox to make it visible - wrapper - .find('[data-test-subj="additionalFilters"] button') - .first() - .simulate('click') - .update(); - - // The check box should be true now since we changed the showBuildingBlockAlerts from false to true - expect( - wrapper - .find('[data-test-subj="showBuildingBlockAlertsCheckbox"] input') - .first() - .prop('checked') - ).toEqual(true); - }); - - test('can update showOnlyThreatIndicatorAlerts from false to true', () => { - const Proxy = (props: AlertsUtilityBarProps) => ( - - - - ); - - const wrapper = mount( - - ); - // click the filters button to popup the checkbox to make it visible - wrapper - .find('[data-test-subj="additionalFilters"] button') - .first() - .simulate('click') - .update(); - - // The check box should false now since we initially set the showBuildingBlockAlerts to false - expect( - wrapper - .find('[data-test-subj="showOnlyThreatIndicatorAlertsCheckbox"] input') - .first() - .prop('checked') - ).toEqual(false); - - wrapper.setProps({ showOnlyThreatIndicatorAlerts: true }); - wrapper.update(); - - // click the filters button to popup the checkbox to make it visible - wrapper - .find('[data-test-subj="additionalFilters"] button') - .first() - .simulate('click') - .update(); - - // The check box should be true now since we changed the showBuildingBlockAlerts from false to true - expect( - wrapper - .find('[data-test-subj="showOnlyThreatIndicatorAlertsCheckbox"] input') - .first() - .prop('checked') - ).toEqual(true); - }); - }); -}); diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_utility_bar/index.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_utility_bar/index.tsx deleted file mode 100644 index 91425ab90e60b6..00000000000000 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_utility_bar/index.tsx +++ /dev/null @@ -1,284 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { isEmpty } from 'lodash/fp'; -import React, { useCallback } from 'react'; -import numeral from '@elastic/numeral'; - -import { EuiFlexGroup, EuiFlexItem, EuiCheckbox } from '@elastic/eui'; -import styled from 'styled-components'; - -import type { Status } from '../../../../../common/detection_engine/schemas/common/schemas'; -import { Link } from '../../../../common/components/link_icon'; -import { DEFAULT_NUMBER_FORMAT } from '../../../../../common/constants'; -import { - UtilityBar, - UtilityBarAction, - UtilityBarGroup, - UtilityBarSection, - UtilityBarSpacer, - UtilityBarText, -} from '../../../../common/components/utility_bar'; -import * as i18n from './translations'; -import { useUiSetting$ } from '../../../../common/lib/kibana'; -import type { TimelineNonEcsData } from '../../../../../common/search_strategy/timeline'; -import type { UpdateAlertsStatus } from '../types'; -import { FILTER_CLOSED, FILTER_ACKNOWLEDGED, FILTER_OPEN } from '../alerts_filter_group'; - -export interface AlertsUtilityBarProps { - areEventsLoading: boolean; - clearSelection: () => void; - currentFilter: Status; - hasIndexMaintenance: boolean; - hasIndexWrite: boolean; - onShowBuildingBlockAlertsChanged: (showBuildingBlockAlerts: boolean) => void; - onShowOnlyThreatIndicatorAlertsChanged: (showOnlyThreatIndicatorAlerts: boolean) => void; - selectAll: () => void; - selectedEventIds: Readonly>; - showBuildingBlockAlerts: boolean; - showClearSelection: boolean; - showOnlyThreatIndicatorAlerts: boolean; - totalCount: number; - updateAlertsStatus: UpdateAlertsStatus; -} - -const UtilityBarFlexGroup = styled(EuiFlexGroup)` - min-width: 175px; -`; - -const AdditionalFiltersItem = styled(EuiFlexItem)` - padding: ${({ theme }) => theme.eui.euiSizeS}; -`; - -const BuildingBlockContainer = styled(AdditionalFiltersItem)` - background: ${({ theme }) => theme.eui.euiColorHighlight}; -`; - -const AlertsUtilityBarComponent: React.FC = ({ - areEventsLoading, - clearSelection, - currentFilter, - hasIndexMaintenance, - hasIndexWrite, - onShowBuildingBlockAlertsChanged, - onShowOnlyThreatIndicatorAlertsChanged, - selectAll, - selectedEventIds, - showBuildingBlockAlerts, - showClearSelection, - showOnlyThreatIndicatorAlerts, - totalCount, - updateAlertsStatus, -}) => { - const [defaultNumberFormat] = useUiSetting$(DEFAULT_NUMBER_FORMAT); - - const handleUpdateStatus = useCallback( - async (selectedStatus: Status) => { - await updateAlertsStatus({ - alertIds: Object.keys(selectedEventIds), - status: currentFilter, - selectedStatus, - }); - }, - [currentFilter, selectedEventIds, updateAlertsStatus] - ); - - const formattedTotalCount = numeral(totalCount).format(defaultNumberFormat); - const formattedSelectedEventsCount = numeral(Object.keys(selectedEventIds).length).format( - defaultNumberFormat - ); - - const UtilityBarPopoverContent = (closePopover: () => void) => ( - - {currentFilter !== FILTER_OPEN && ( - - { - closePopover(); - handleUpdateStatus('open'); - }} - color="text" - data-test-subj="openSelectedAlertsButton" - > - {i18n.BATCH_ACTION_OPEN_SELECTED} - - - )} - - {currentFilter !== FILTER_CLOSED && ( - - { - closePopover(); - handleUpdateStatus('closed'); - }} - color="text" - data-test-subj="closeSelectedAlertsButton" - > - {i18n.BATCH_ACTION_CLOSE_SELECTED} - - - )} - - {currentFilter !== FILTER_ACKNOWLEDGED && ( - - { - closePopover(); - handleUpdateStatus('acknowledged'); - }} - color="text" - data-test-subj="markSelectedAlertsAcknowledgedButton" - > - {i18n.BATCH_ACTION_ACKNOWLEDGED_SELECTED} - - - )} - - ); - - const handleSelectAllAlertsClick = useCallback(() => { - if (!showClearSelection) { - selectAll(); - } else { - clearSelection(); - } - }, [clearSelection, selectAll, showClearSelection]); - - return ( - <> - - - - - {i18n.SHOWING_ALERTS(formattedTotalCount, totalCount)} - - - - - {hasIndexWrite && hasIndexMaintenance && ( - <> - - {i18n.SELECTED_ALERTS( - showClearSelection ? formattedTotalCount : formattedSelectedEventsCount, - showClearSelection ? totalCount : Object.keys(selectedEventIds).length - )} - - - - {i18n.TAKE_ACTION} - - - - {showClearSelection - ? i18n.CLEAR_SELECTION - : i18n.SELECT_ALL_ALERTS(formattedTotalCount, totalCount)} - - - )} - - - - - - - ); -}; - -export const AlertsUtilityBar = React.memo( - AlertsUtilityBarComponent, - (prevProps, nextProps) => - prevProps.areEventsLoading === nextProps.areEventsLoading && - prevProps.selectedEventIds === nextProps.selectedEventIds && - prevProps.totalCount === nextProps.totalCount && - prevProps.showClearSelection === nextProps.showClearSelection && - prevProps.showBuildingBlockAlerts === nextProps.showBuildingBlockAlerts && - prevProps.showOnlyThreatIndicatorAlerts === nextProps.showOnlyThreatIndicatorAlerts -); - -export const AditionalFiltersAction = ({ - areEventsLoading, - onShowBuildingBlockAlertsChanged, - showBuildingBlockAlerts, - onShowOnlyThreatIndicatorAlertsChanged, - showOnlyThreatIndicatorAlerts, -}: { - areEventsLoading: boolean; - onShowBuildingBlockAlertsChanged: (showBuildingBlockAlerts: boolean) => void; - showBuildingBlockAlerts: boolean; - onShowOnlyThreatIndicatorAlertsChanged: (showOnlyThreatIndicatorAlerts: boolean) => void; - showOnlyThreatIndicatorAlerts: boolean; -}) => { - const UtilityBarAdditionalFiltersContent = (closePopover: () => void) => ( - - - ) => { - closePopover(); - onShowBuildingBlockAlertsChanged(e.target.checked); - }} - checked={showBuildingBlockAlerts} - color="text" - data-test-subj="showBuildingBlockAlertsCheckbox" - label={i18n.ADDITIONAL_FILTERS_ACTIONS_SHOW_BUILDING_BLOCK} - /> - - - ) => { - closePopover(); - onShowOnlyThreatIndicatorAlertsChanged(e.target.checked); - }} - checked={showOnlyThreatIndicatorAlerts} - color="text" - data-test-subj="showOnlyThreatIndicatorAlertsCheckbox" - label={i18n.ADDITIONAL_FILTERS_ACTIONS_SHOW_ONLY_THREAT_INDICATOR_ALERTS} - /> - - - ); - - return ( - - {i18n.ADDITIONAL_FILTERS_ACTIONS} - - ); -}; diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_utility_bar/translations.ts b/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_utility_bar/translations.ts deleted file mode 100644 index 5da63a5ab95984..00000000000000 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_utility_bar/translations.ts +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { i18n } from '@kbn/i18n'; - -export const SHOWING_ALERTS = (totalAlertsFormatted: string, totalAlerts: number) => - i18n.translate('xpack.securitySolution.detectionEngine.alerts.utilityBar.showingAlertsTitle', { - values: { totalAlertsFormatted, totalAlerts }, - defaultMessage: - 'Showing {totalAlertsFormatted} {totalAlerts, plural, =1 {alert} other {alerts}}', - }); - -export const SELECTED_ALERTS = (selectedAlertsFormatted: string, selectedAlerts: number) => - i18n.translate('xpack.securitySolution.detectionEngine.alerts.utilityBar.selectedAlertsTitle', { - values: { selectedAlertsFormatted, selectedAlerts }, - defaultMessage: - 'Selected {selectedAlertsFormatted} {selectedAlerts, plural, =1 {alert} other {alerts}}', - }); - -export const SELECT_ALL_ALERTS = (totalAlertsFormatted: string, totalAlerts: number) => - i18n.translate('xpack.securitySolution.detectionEngine.alerts.utilityBar.selectAllAlertsTitle', { - values: { totalAlertsFormatted, totalAlerts }, - defaultMessage: - 'Select all {totalAlertsFormatted} {totalAlerts, plural, =1 {alert} other {alerts}}', - }); - -export const ADDITIONAL_FILTERS_ACTIONS = i18n.translate( - 'xpack.securitySolution.detectionEngine.alerts.utilityBar.additionalFiltersTitle', - { - defaultMessage: 'Additional filters', - } -); - -export const ADDITIONAL_FILTERS_ACTIONS_SHOW_BUILDING_BLOCK = i18n.translate( - 'xpack.securitySolution.detectionEngine.alerts.utilityBar.additionalFiltersActions.showBuildingBlockTitle', - { - defaultMessage: 'Include building block alerts', - } -); - -export const ADDITIONAL_FILTERS_ACTIONS_SHOW_ONLY_THREAT_INDICATOR_ALERTS = i18n.translate( - 'xpack.securitySolution.detectionEngine.alerts.utilityBar.additionalFiltersActions.showOnlyThreatIndicatorAlerts', - { - defaultMessage: 'Show only threat indicator alerts', - } -); - -export const CLEAR_SELECTION = i18n.translate( - 'xpack.securitySolution.detectionEngine.alerts.utilityBar.clearSelectionTitle', - { - defaultMessage: 'Clear selection', - } -); - -export const TAKE_ACTION = i18n.translate( - 'xpack.securitySolution.detectionEngine.alerts.utilityBar.takeActionTitle', - { - defaultMessage: 'Take action', - } -); - -export const BATCH_ACTION_OPEN_SELECTED = i18n.translate( - 'xpack.securitySolution.detectionEngine.alerts.utilityBar.batchActions.openSelectedTitle', - { - defaultMessage: 'Open selected', - } -); - -export const BATCH_ACTION_CLOSE_SELECTED = i18n.translate( - 'xpack.securitySolution.detectionEngine.alerts.utilityBar.batchActions.closeSelectedTitle', - { - defaultMessage: 'Close selected', - } -); - -export const BATCH_ACTION_ACKNOWLEDGED_SELECTED = i18n.translate( - 'xpack.securitySolution.detectionEngine.alerts.utilityBar.batchActions.acknowledgedSelectedTitle', - { - defaultMessage: 'Mark as acknowledged', - } -); diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/index.test.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/index.test.tsx index 304f0ac1808214..34378594a952dc 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/index.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/index.test.tsx @@ -33,13 +33,11 @@ describe('AlertsTableComponent', () => { loadingEventIds={[]} selectedEventIds={{}} isSelectAllChecked={false} - clearSelected={jest.fn()} - setEventsLoading={jest.fn()} - setEventsDeleted={jest.fn()} showBuildingBlockAlerts={false} onShowBuildingBlockAlertsChanged={jest.fn()} showOnlyThreatIndicatorAlerts={false} onShowOnlyThreatIndicatorAlertsChanged={jest.fn()} + dispatch={jest.fn()} /> ); diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/index.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/index.tsx index 9c11f4499db95c..d4dead20989a6e 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/index.tsx @@ -6,22 +6,15 @@ */ import { isEmpty } from 'lodash/fp'; -import React, { useCallback, useEffect, useMemo, useState } from 'react'; +import React, { useCallback, useEffect, useMemo } from 'react'; import type { ConnectedProps } from 'react-redux'; import { connect, useDispatch } from 'react-redux'; -import type { Dispatch } from 'redux'; import type { Filter } from '@kbn/es-query'; import { getEsQueryConfig } from '@kbn/data-plugin/common'; import type { Status } from '../../../../common/detection_engine/schemas/common/schemas'; import type { RowRendererId, TimelineIdLiteral } from '../../../../common/types/timeline'; import { StatefulEventsViewer } from '../../../common/components/events_viewer'; -import { - displayErrorToast, - displaySuccessToast, - useStateToaster, -} from '../../../common/components/toasters'; import { useSourcererDataView } from '../../../common/containers/sourcerer'; -import { useAppToasts } from '../../../common/hooks/use_app_toasts'; import { useIsExperimentalFeatureEnabled } from '../../../common/hooks/use_experimental_features'; import { useInvalidFilterQuery } from '../../../common/hooks/use_invalid_filter_query'; import { defaultCellActions } from '../../../common/lib/cell_actions/default_cell_actions'; @@ -29,7 +22,6 @@ import { useKibana } from '../../../common/lib/kibana'; import type { inputsModel, State } from '../../../common/store'; import { inputsSelectors } from '../../../common/store'; import { SourcererScopeName } from '../../../common/store/sourcerer/model'; -import * as i18nCommon from '../../../common/translations'; import { DEFAULT_COLUMN_MIN_WIDTH } from '../../../timelines/components/timeline/body/constants'; import { getDefaultControlColumn } from '../../../timelines/components/timeline/body/control_columns'; import { defaultRowRenderers } from '../../../timelines/components/timeline/body/renderers'; @@ -38,8 +30,7 @@ import { timelineActions, timelineSelectors } from '../../../timelines/store/tim import { timelineDefaults } from '../../../timelines/store/timeline/defaults'; import type { TimelineModel } from '../../../timelines/store/timeline/model'; import { columns, RenderCellValue } from '../../configurations/security_solution_detections'; -import { updateAlertStatusAction } from './actions'; -import { AditionalFiltersAction, AlertsUtilityBar } from './alerts_utility_bar'; +import { AdditionalFiltersAction } from './additional_filters_action'; import { alertsDefaultModel, buildAlertStatusFilter, @@ -47,13 +38,6 @@ import { } from './default_config'; import { buildTimeRangeFilter } from './helpers'; import * as i18n from './translations'; -import type { - SetEventsDeletedProps, - SetEventsLoadingProps, - UpdateAlertsStatusCallback, - UpdateAlertsStatusProps, -} from './types'; - interface OwnProps { defaultFilters?: Filter[]; from: string; @@ -73,7 +57,6 @@ interface OwnProps { type AlertsTableComponentProps = OwnProps & PropsFromRedux; export const AlertsTableComponent: React.FC = ({ - clearSelected, defaultFilters, from, globalFilters, @@ -86,9 +69,6 @@ export const AlertsTableComponent: React.FC = ({ onRuleChange, onShowBuildingBlockAlertsChanged, onShowOnlyThreatIndicatorAlertsChanged, - selectedEventIds, - setEventsDeleted, - setEventsLoading, showBuildingBlockAlerts, showOnlyThreatIndicatorAlerts, timelineId, @@ -96,15 +76,12 @@ export const AlertsTableComponent: React.FC = ({ filterGroup = 'open', }) => { const dispatch = useDispatch(); - const [showClearSelectionAction, setShowClearSelectionAction] = useState(false); const { browserFields, indexPattern: indexPatterns, selectedPatterns, } = useSourcererDataView(SourcererScopeName.detections); const kibana = useKibana(); - const [, dispatchToaster] = useStateToaster(); - const { addWarning } = useAppToasts(); const ACTION_BUTTON_COUNT = 5; const getGlobalQuery = useCallback( @@ -123,7 +100,6 @@ export const AlertsTableComponent: React.FC = ({ ], kqlQuery: globalQuery, kqlMode: globalQuery.language, - isEventViewer: true, }); } return null; @@ -140,66 +116,6 @@ export const AlertsTableComponent: React.FC = ({ endDate: to, }); - const setEventsLoadingCallback = useCallback( - ({ eventIds, isLoading }: SetEventsLoadingProps) => { - setEventsLoading({ id: timelineId, eventIds, isLoading }); - }, - [setEventsLoading, timelineId] - ); - - const setEventsDeletedCallback = useCallback( - ({ eventIds, isDeleted }: SetEventsDeletedProps) => { - setEventsDeleted({ id: timelineId, eventIds, isDeleted }); - }, - [setEventsDeleted, timelineId] - ); - - const onAlertStatusUpdateSuccess = useCallback( - (updated: number, conflicts: number, status: Status) => { - if (conflicts > 0) { - // Partial failure - addWarning({ - title: i18nCommon.UPDATE_ALERT_STATUS_FAILED(conflicts), - text: i18nCommon.UPDATE_ALERT_STATUS_FAILED_DETAILED(updated, conflicts), - }); - } else { - let title = ''; - switch (status) { - case 'closed': - title = i18n.CLOSED_ALERT_SUCCESS_TOAST(updated); - break; - case 'open': - title = i18n.OPENED_ALERT_SUCCESS_TOAST(updated); - break; - case 'acknowledged': - case 'in-progress': - title = i18n.ACKNOWLEDGED_ALERT_SUCCESS_TOAST(updated); - } - displaySuccessToast(title, dispatchToaster); - } - }, - [addWarning, dispatchToaster] - ); - - const onAlertStatusUpdateFailure = useCallback( - (status: Status, error: Error) => { - let title = ''; - switch (status) { - case 'closed': - title = i18n.CLOSED_ALERT_FAILED_TOAST; - break; - case 'open': - title = i18n.OPENED_ALERT_FAILED_TOAST; - break; - case 'acknowledged': - case 'in-progress': - title = i18n.ACKNOWLEDGED_ALERT_FAILED_TOAST; - } - displayErrorToast(title, [error.message], dispatchToaster); - }, - [dispatchToaster] - ); - // Catches state change isSelectAllChecked->false upon user selection change to reset utility bar useEffect(() => { if (isSelectAllChecked) { @@ -209,107 +125,12 @@ export const AlertsTableComponent: React.FC = ({ selectAll: false, }) ); - } else { - setShowClearSelectionAction(false); } }, [dispatch, isSelectAllChecked, timelineId]); - // Callback for clearing entire selection from utility bar - const clearSelectionCallback = useCallback(() => { - clearSelected({ id: timelineId }); - dispatch( - timelineActions.setTGridSelectAll({ - id: timelineId, - selectAll: false, - }) - ); - setShowClearSelectionAction(false); - }, [clearSelected, dispatch, timelineId]); - - // Callback for selecting all events on all pages from utility bar - // Dispatches to stateful_body's selectAll via TimelineTypeContext props - // as scope of response data required to actually set selectedEvents - const selectAllOnAllPagesCallback = useCallback(() => { - dispatch( - timelineActions.setTGridSelectAll({ - id: timelineId, - selectAll: true, - }) - ); - setShowClearSelectionAction(true); - }, [dispatch, timelineId]); - - const updateAlertsStatusCallback: UpdateAlertsStatusCallback = useCallback( - async ( - refetchQuery: inputsModel.Refetch, - { status, selectedStatus }: UpdateAlertsStatusProps - ) => { - await updateAlertStatusAction({ - query: showClearSelectionAction - ? getGlobalQuery(buildAlertStatusFilter(status))?.filterQuery - : undefined, - alertIds: Object.keys(selectedEventIds), - selectedStatus, - setEventsDeleted: setEventsDeletedCallback, - setEventsLoading: setEventsLoadingCallback, - onAlertStatusUpdateSuccess, - onAlertStatusUpdateFailure, - }); - refetchQuery(); - }, - [ - getGlobalQuery, - selectedEventIds, - setEventsDeletedCallback, - setEventsLoadingCallback, - showClearSelectionAction, - onAlertStatusUpdateSuccess, - onAlertStatusUpdateFailure, - ] - ); - - // Callback for creating the AlertsUtilityBar which receives totalCount from EventsViewer component - const utilityBarCallback = useCallback( - (refetchQuery: inputsModel.Refetch, totalCount: number) => { - return ( - 0} - clearSelection={clearSelectionCallback} - currentFilter={filterGroup} - hasIndexMaintenance={hasIndexMaintenance} - hasIndexWrite={hasIndexWrite} - onShowBuildingBlockAlertsChanged={onShowBuildingBlockAlertsChanged} - onShowOnlyThreatIndicatorAlertsChanged={onShowOnlyThreatIndicatorAlertsChanged} - selectAll={selectAllOnAllPagesCallback} - selectedEventIds={selectedEventIds} - showBuildingBlockAlerts={showBuildingBlockAlerts} - showClearSelection={showClearSelectionAction} - showOnlyThreatIndicatorAlerts={showOnlyThreatIndicatorAlerts} - totalCount={totalCount} - updateAlertsStatus={updateAlertsStatusCallback.bind(null, refetchQuery)} - /> - ); - }, - [ - clearSelectionCallback, - filterGroup, - hasIndexMaintenance, - hasIndexWrite, - loadingEventIds.length, - onShowBuildingBlockAlertsChanged, - onShowOnlyThreatIndicatorAlertsChanged, - selectAllOnAllPagesCallback, - selectedEventIds, - showBuildingBlockAlerts, - showClearSelectionAction, - showOnlyThreatIndicatorAlerts, - updateAlertsStatusCallback, - ] - ); - const additionalFiltersComponent = useMemo( () => ( - 0} onShowBuildingBlockAlertsChanged={onShowBuildingBlockAlertsChanged} showBuildingBlockAlerts={showBuildingBlockAlerts} @@ -387,7 +208,6 @@ export const AlertsTableComponent: React.FC = ({ rowRenderers={defaultRowRenderers} scopeId={SourcererScopeName.detections} start={from} - utilityBar={utilityBarCallback} /> ); }; @@ -414,29 +234,7 @@ const makeMapStateToProps = () => { return mapStateToProps; }; -const mapDispatchToProps = (dispatch: Dispatch) => ({ - clearSelected: ({ id }: { id: string }) => dispatch(timelineActions.clearSelected({ id })), - setEventsLoading: ({ - id, - eventIds, - isLoading, - }: { - id: string; - eventIds: string[]; - isLoading: boolean; - }) => dispatch(timelineActions.setEventsLoading({ id, eventIds, isLoading })), - setEventsDeleted: ({ - id, - eventIds, - isDeleted, - }: { - id: string; - eventIds: string[]; - isDeleted: boolean; - }) => dispatch(timelineActions.setEventsDeleted({ id, eventIds, isDeleted })), -}); - -const connector = connect(makeMapStateToProps, mapDispatchToProps); +const connector = connect(makeMapStateToProps); type PropsFromRedux = ConnectedProps; diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/add_item_form/index.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/add_item_form/index.tsx index 68ba032175e3aa..48c306a36a2eb3 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/add_item_form/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/add_item_form/index.tsx @@ -99,7 +99,6 @@ export const AddItem = ({ const updateItem = useCallback( (event: ChangeEvent, index: number) => { - event.persist(); const values = field.value as string[]; const value = event.target.value; field.setValue([...values.slice(0, index), value, ...values.slice(index + 1)]); diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/related_integrations/use_installed_integrations.test.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/related_integrations/use_installed_integrations.test.tsx index 9ce7134db5f2a8..705c7f5f3fbd38 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/related_integrations/use_installed_integrations.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/related_integrations/use_installed_integrations.test.tsx @@ -9,7 +9,7 @@ jest.mock('../../../containers/detection_engine/rules/api'); jest.mock('../../../../common/lib/kibana'); import React from 'react'; -import { QueryClient, QueryClientProvider } from 'react-query'; +import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { renderHook, cleanup } from '@testing-library/react-hooks'; import { useInstalledIntegrations } from './use_installed_integrations'; diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/related_integrations/use_installed_integrations.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/related_integrations/use_installed_integrations.tsx index bc9e837911233a..734ef6e6282149 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/related_integrations/use_installed_integrations.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/related_integrations/use_installed_integrations.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { useQuery } from 'react-query'; +import { useQuery } from '@tanstack/react-query'; import type { InstalledIntegrationArray } from '../../../../../common/detection_engine/schemas/common'; import { fetchInstalledIntegrations } from '../../../containers/detection_engine/rules/api'; // import { useAppToasts } from '../../../../common/hooks/use_app_toasts'; diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/rule_actions_field/index.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/rule_actions_field/index.tsx index 1cccca810f7e05..c0698ba443d8bf 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/rule_actions_field/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/rule_actions_field/index.tsx @@ -150,7 +150,7 @@ export const RuleActionsField: React.FC = ({ field, messageVariables }) = <> - + {fieldErrors} diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/rule_actions_overflow/index.test.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/rule_actions_overflow/index.test.tsx index 8e8c6f11975f50..8b736bad37b927 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/rule_actions_overflow/index.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/rule_actions_overflow/index.test.tsx @@ -11,6 +11,7 @@ import React from 'react'; import { goToRuleEditPage, executeRulesBulkAction, + bulkExportRules, } from '../../../pages/detection_engine/rules/all/actions'; import { RuleActionsOverflow } from '.'; import { mockRule } from '../../../pages/detection_engine/rules/all/__mocks__/mock'; @@ -33,6 +34,8 @@ jest.mock('../../../../common/lib/kibana', () => { jest.mock('../../../pages/detection_engine/rules/all/actions'); const executeRulesBulkActionMock = executeRulesBulkAction as jest.Mock; +const bulkExportRulesMock = bulkExportRules as jest.Mock; + const flushPromises = () => new Promise(setImmediate); describe('RuleActionsOverflow', () => { @@ -233,6 +236,28 @@ describe('RuleActionsOverflow', () => { }); describe('rules details export rule', () => { + test('should call export actions and display toast when export option is clicked', async () => { + bulkExportRulesMock.mockImplementation(() => Promise.resolve({})); + const wrapper = mount( + + ); + wrapper.find('[data-test-subj="rules-details-popover-button-icon"] button').simulate('click'); + wrapper.update(); + wrapper.find('[data-test-subj="rules-details-export-rule"] button').simulate('click'); + wrapper.update(); + await flushPromises(); + + expect(bulkExportRulesMock).toHaveBeenCalledWith( + expect.objectContaining({ action: 'export' }) + ); + expect(bulkExportRulesMock).toHaveBeenCalledWith( + expect.not.objectContaining({ onSuccess: expect.any }) + ); + }); test('it does not open the popover when rules-details-popover-button-icon is clicked and the user does not have permission', () => { const rule = mockRule('id'); const wrapper = mount( diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/rule_actions_overflow/index.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/rule_actions_overflow/index.tsx index 27b776e67c61f7..b8e423827edcea 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/rule_actions_overflow/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/rule_actions_overflow/index.tsx @@ -111,7 +111,6 @@ const RuleActionsOverflowComponent = ({ closePopover(); await bulkExportRules({ action: BulkAction.export, - onSuccess: noop, search: { ids: [rule.id] }, toasts, }); diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/rule_preview/helpers.ts b/x-pack/plugins/security_solution/public/detections/components/rules/rule_preview/helpers.ts index 9ee6628636ad4b..266c0185745af2 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/rule_preview/helpers.ts +++ b/x-pack/plugins/security_solution/public/detections/components/rules/rule_preview/helpers.ts @@ -5,6 +5,7 @@ * 2.0. */ +import { isEmpty } from 'lodash'; import { Position, ScaleType } from '@elastic/charts'; import type { EuiSelectOption } from '@elastic/eui'; import type { Type, Language, ThreatMapping } from '@kbn/securitysolution-io-ts-alerting-types'; @@ -207,7 +208,7 @@ export const getIsRulePreviewDisabled = ({ return machineLearningJobId.length === 0; } if (ruleType === 'eql' || ruleType === 'query' || ruleType === 'threshold') { - return queryBar.query.query.length === 0; + return isEmpty(queryBar.query.query) && isEmpty(queryBar.filters); } if (ruleType === 'new_terms') { return newTermsFields.length === 0; diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/rule_preview/index.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/rule_preview/index.tsx index 3f541344abe5a2..0639fda39ca4da 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/rule_preview/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/rule_preview/index.tsx @@ -101,6 +101,13 @@ const PreviewButton = styled(EuiButton)` const defaultTimeRange: Unit = 'h'; +const refreshedTimeframe = (startDate: string, endDate: string) => { + return { + start: dateMath.parse(startDate) || moment().subtract(1, 'hour'), + end: dateMath.parse(endDate) || moment(), + }; +}; + const RulePreviewComponent: React.FC = ({ index, indexPattern, @@ -129,9 +136,20 @@ const RulePreviewComponent: React.FC = ({ } }, [spaces]); + // Raw timeframe as a string const [startDate, setStartDate] = useState('now-1h'); const [endDate, setEndDate] = useState('now'); + // Parsed timeframe as a Moment object + const [timeframeStart, setTimeframeStart] = useState(moment().subtract(1, 'hour')); + const [timeframeEnd, setTimeframeEnd] = useState(moment()); + + useEffect(() => { + const { start, end } = refreshedTimeframe(startDate, endDate); + setTimeframeStart(start); + setTimeframeEnd(end); + }, [startDate, endDate]); + const { form } = useForm({ defaultValue: advancedOptionsDefaultValue, options: { stripEmptyFields: false }, @@ -180,21 +198,22 @@ const RulePreviewComponent: React.FC = ({ const showAdvancedOptions = queryPreviewIdSelected === ADVANCED_QUERY_SELECT_ID; const advancedOptions = useMemo( () => - showAdvancedOptions && startDate && endDate && formInterval && formLookback + showAdvancedOptions && formInterval && formLookback ? { - timeframeStart: dateMath.parse(startDate) || moment().subtract(1, 'hour'), - timeframeEnd: dateMath.parse(endDate) || moment(), + timeframeStart, + timeframeEnd, interval: formInterval, lookback: formLookback, } : undefined, - [endDate, formInterval, formLookback, showAdvancedOptions, startDate] + [formInterval, formLookback, showAdvancedOptions, timeframeEnd, timeframeStart] ); const [timeFrame, setTimeFrame] = useState(defaultTimeRange); const { addNoiseWarning, createPreview, + clearPreview, isPreviewRequestInProgress, previewId, logs, @@ -228,10 +247,27 @@ const RulePreviewComponent: React.FC = ({ const { startTransaction } = useStartTransaction(); + const [isRefreshing, setIsRefreshing] = useState(false); + useEffect(() => { + if (!isRefreshing) { + return; + } + createPreview(); + setIsRefreshing(false); + }, [isRefreshing, createPreview]); + const handlePreviewClick = useCallback(() => { startTransaction({ name: SINGLE_RULE_ACTIONS.PREVIEW }); - createPreview(); - }, [createPreview, startTransaction]); + if (showAdvancedOptions) { + // Refresh timeframe on Preview button click to make sure that relative times recalculated based on current time + const { start, end } = refreshedTimeframe(startDate, endDate); + setTimeframeStart(start); + setTimeframeEnd(end); + } else { + clearPreview(); + } + setIsRefreshing(true); + }, [clearPreview, endDate, showAdvancedOptions, startDate, startTransaction]); const onTimeChange = useCallback( ({ start: newStart, end: newEnd, isInvalid }: OnTimeChangeProps) => { diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/rule_preview/use_preview_route.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/rule_preview/use_preview_route.tsx index d0c543e3c3a31c..7c5c3e673fd2af 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/rule_preview/use_preview_route.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/rule_preview/use_preview_route.tsx @@ -5,7 +5,8 @@ * 2.0. */ -import { useEffect, useState, useCallback } from 'react'; +import { useEffect, useMemo, useState, useCallback } from 'react'; +import moment from 'moment'; import type { Unit } from '@kbn/datemath'; import type { Type, ThreatMapping } from '@kbn/securitysolution-io-ts-alerting-types'; import type { FieldValueQueryBar } from '../query_bar'; @@ -60,8 +61,23 @@ export const usePreviewRoute = ({ }: PreviewRouteParams) => { const [isRequestTriggered, setIsRequestTriggered] = useState(false); + const [timeframeEnd, setTimeframeEnd] = useState(moment()); + useEffect(() => { + if (isRequestTriggered) { + setTimeframeEnd(moment()); + } + }, [isRequestTriggered, setTimeframeEnd]); + + const quickQueryOptions = useMemo( + () => ({ + timeframe: timeFrame, + timeframeEnd, + }), + [timeFrame, timeframeEnd] + ); + const { isLoading, showInvocationCountWarning, response, rule, setRule } = usePreviewRule({ - timeframe: timeFrame, + quickQueryOptions, advancedOptions, }); const [logs, setLogs] = useState(response.logs ?? []); diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/step_define_rule/index.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/step_define_rule/index.tsx index b1c55bdecc52df..f9be710725986f 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/step_define_rule/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/step_define_rule/index.tsx @@ -615,7 +615,6 @@ const StepDefineRuleComponent: FC = ({ component={QueryBarDefineRule} componentProps={{ browserFields, - // docValueFields, // runtimeMappings, idAria: 'detectionEngineStepDefineRuleQueryBar', indexPattern, diff --git a/x-pack/plugins/security_solution/public/detections/components/take_action_dropdown/index.test.tsx b/x-pack/plugins/security_solution/public/detections/components/take_action_dropdown/index.test.tsx index 01e676189f79ee..6a83df5a87d198 100644 --- a/x-pack/plugins/security_solution/public/detections/components/take_action_dropdown/index.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/take_action_dropdown/index.test.tsx @@ -474,14 +474,13 @@ describe('take action dropdown', () => { await waitFor(() => { expect(apiMocks.responseProvider.metadataDetails).toHaveBeenCalled(); - }); - - wrapper.update(); + wrapper.update(); - expect(findLaunchResponderButton().first().prop('disabled')).toBe(true); - expect(findLaunchResponderButton().first().prop('toolTipContent')).toEqual( - HOST_ENDPOINT_UNENROLLED_TOOLTIP - ); + expect(findLaunchResponderButton().first().prop('disabled')).toBe(true); + expect(findLaunchResponderButton().first().prop('toolTipContent')).toEqual( + HOST_ENDPOINT_UNENROLLED_TOOLTIP + ); + }); }); }); }); diff --git a/x-pack/plugins/security_solution/public/detections/components/take_action_dropdown/index.tsx b/x-pack/plugins/security_solution/public/detections/components/take_action_dropdown/index.tsx index ea66ebb132d8a6..197d655d2420bf 100644 --- a/x-pack/plugins/security_solution/public/detections/components/take_action_dropdown/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/take_action_dropdown/index.tsx @@ -10,7 +10,7 @@ import { EuiButton, EuiContextMenuPanel, EuiPopover } from '@elastic/eui'; import type { ExceptionListType } from '@kbn/securitysolution-io-ts-list-types'; import { useResponderActionItem } from '../endpoint_responder'; import type { TimelineEventsDetailsItem } from '../../../../common/search_strategy'; -import { TAKE_ACTION } from '../alerts_table/alerts_utility_bar/translations'; +import { TAKE_ACTION } from '../alerts_table/additional_filters_action/translations'; import { useExceptionActions } from '../alerts_table/timeline_actions/use_add_exception_actions'; import { useAlertsActions } from '../alerts_table/timeline_actions/use_alerts_actions'; import { useInvestigateInTimeline } from '../alerts_table/timeline_actions/use_investigate_in_timeline'; diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_find_rules_query.ts b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_find_rules_query.ts index e78be9ca1c7537..523a05012ca19a 100644 --- a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_find_rules_query.ts +++ b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_find_rules_query.ts @@ -6,8 +6,8 @@ */ import { useCallback } from 'react'; -import type { UseQueryOptions } from 'react-query'; -import { useQuery, useQueryClient } from 'react-query'; +import type { UseQueryOptions } from '@tanstack/react-query'; +import { useQuery, useQueryClient } from '@tanstack/react-query'; import { useAppToasts } from '../../../../common/hooks/use_app_toasts'; import { fetchRules } from './api'; import * as i18n from './translations'; @@ -78,9 +78,8 @@ export const useInvalidateRules = () => { * Invalidate all queries that start with FIND_RULES_QUERY_KEY. This * includes the in-memory query cache and paged query cache. */ - queryClient.invalidateQueries(FIND_RULES_QUERY_KEY, { - refetchActive: true, - refetchInactive: false, + queryClient.invalidateQueries([FIND_RULES_QUERY_KEY], { + refetchType: 'active', }); }, [queryClient]); }; @@ -104,7 +103,7 @@ export const useUpdateRulesCache = () => { return useCallback( (newRules: Rule[]) => { queryClient.setQueriesData['data']>( - FIND_RULES_QUERY_KEY, + [FIND_RULES_QUERY_KEY], (currentData) => currentData ? { diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_install_pre_packaged_rules.ts b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_install_pre_packaged_rules.ts index ff3493037182cf..3f56cac04fb021 100644 --- a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_install_pre_packaged_rules.ts +++ b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_install_pre_packaged_rules.ts @@ -4,7 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { useMutation } from 'react-query'; +import { useMutation } from '@tanstack/react-query'; import { useAppToasts } from '../../../../common/hooks/use_app_toasts'; import { createPrepackagedRules } from './api'; import * as i18n from './translations'; diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_pre_packaged_rules.test.tsx b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_pre_packaged_rules.test.tsx index f977e15626c168..5cddbeef63028c 100644 --- a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_pre_packaged_rules.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_pre_packaged_rules.test.tsx @@ -4,7 +4,6 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ - import { act, renderHook } from '@testing-library/react-hooks'; import { shallow } from 'enzyme'; import type { ReactElement } from 'react'; @@ -144,6 +143,7 @@ describe('usePrePackagedRules', () => { result.current.createPrePackagedRules(); await waitForNextUpdate(); expect(api.createPrepackagedRules).toHaveBeenCalled(); + await waitForNextUpdate(); expect(result.current).toEqual({ getLoadPrebuiltRulesAndTemplatesButton: result.current.getLoadPrebuiltRulesAndTemplatesButton, diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_pre_packaged_rules_status.ts b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_pre_packaged_rules_status.ts index 02350d84ec99e4..c01bce4fe8bc2e 100644 --- a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_pre_packaged_rules_status.ts +++ b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_pre_packaged_rules_status.ts @@ -5,7 +5,7 @@ * 2.0. */ import { useCallback } from 'react'; -import { useQuery, useQueryClient } from 'react-query'; +import { useQuery, useQueryClient } from '@tanstack/react-query'; import { useAppToasts } from '../../../../common/hooks/use_app_toasts'; import { getPrePackagedRulesStatus } from './api'; import * as i18n from './translations'; @@ -62,9 +62,8 @@ export const useInvalidatePrePackagedRulesStatus = () => { const queryClient = useQueryClient(); return useCallback(() => { - queryClient.invalidateQueries(PRE_PACKAGED_RULES_STATUS_QUERY_KEY, { - refetchActive: true, - refetchInactive: false, + queryClient.invalidateQueries([PRE_PACKAGED_RULES_STATUS_QUERY_KEY], { + refetchType: 'active', }); }, [queryClient]); }; diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_preview_rule.ts b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_preview_rule.ts index a8b12a9ebc1214..ed7f4150f7349e 100644 --- a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_preview_rule.ts +++ b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_preview_rule.ts @@ -8,7 +8,6 @@ import { useEffect, useMemo, useState } from 'react'; import moment from 'moment'; -import type { Unit } from '@kbn/datemath'; import { RULE_PREVIEW_FROM, RULE_PREVIEW_INTERVAL, @@ -23,7 +22,10 @@ import type { import { previewRule } from './api'; import * as i18n from './translations'; import { transformOutput } from './transforms'; -import type { AdvancedPreviewOptions } from '../../../pages/detection_engine/rules/types'; +import type { + AdvancedPreviewOptions, + QuickQueryPreviewOptions, +} from '../../../pages/detection_engine/rules/types'; import { getTimeTypeValue } from '../../../pages/detection_engine/rules/create/helpers'; const REASONABLE_INVOCATION_COUNT = 200; @@ -35,10 +37,10 @@ const emptyPreviewRule: PreviewResponse = { }; export const usePreviewRule = ({ - timeframe = 'h', + quickQueryOptions, advancedOptions, }: { - timeframe: Unit; + quickQueryOptions: QuickQueryPreviewOptions; advancedOptions?: AdvancedPreviewOptions; }) => { const [rule, setRule] = useState(null); @@ -49,7 +51,7 @@ export const usePreviewRule = ({ let interval: string = RULE_PREVIEW_INTERVAL.HOUR; let from: string = RULE_PREVIEW_FROM.HOUR; - switch (timeframe) { + switch (quickQueryOptions.timeframe) { case 'd': invocationCount = RULE_PREVIEW_INVOCATION_COUNT.DAY; interval = RULE_PREVIEW_INTERVAL.DAY; @@ -67,8 +69,11 @@ export const usePreviewRule = ({ break; } const timeframeEnd = useMemo( - () => (advancedOptions ? advancedOptions.timeframeEnd.toISOString() : moment().toISOString()), - [advancedOptions] + () => + advancedOptions + ? advancedOptions.timeframeEnd.toISOString() + : quickQueryOptions.timeframeEnd.toISOString(), + [advancedOptions, quickQueryOptions] ); if (advancedOptions) { diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/bulk_actions/use_bulk_actions_dry_run.ts b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/bulk_actions/use_bulk_actions_dry_run.ts index 4468b1c65ece0a..28c4e4be608dcf 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/bulk_actions/use_bulk_actions_dry_run.ts +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/bulk_actions/use_bulk_actions_dry_run.ts @@ -5,8 +5,8 @@ * 2.0. */ -import type { UseMutateAsyncFunction } from 'react-query'; -import { useMutation } from 'react-query'; +import type { UseMutateAsyncFunction } from '@tanstack/react-query'; +import { useMutation } from '@tanstack/react-query'; import type { BulkAction, diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/exceptions_table.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/exceptions_table.tsx index 415bbfd1498c79..d7908d0bbce669 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/exceptions_table.tsx +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/exceptions_table.tsx @@ -26,7 +26,7 @@ import { useFormatUrl } from '../../../../../../common/components/link_to'; import { Loader } from '../../../../../../common/components/loader'; import * as i18n from './translations'; -import { AllRulesUtilityBar } from '../utility_bar'; +import { ExceptionsTableUtilityBar } from './exceptions_table_utility_bar'; import type { AllExceptionListsColumns } from './columns'; import { getAllExceptionListsColumns } from './columns'; import { useAllExceptionLists } from './use_all_exception_lists'; @@ -378,11 +378,8 @@ export const ExceptionListsTable = React.memo(() => { ) : ( <> - diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/exceptions_table_utility_bar.test.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/exceptions_table_utility_bar.test.tsx new file mode 100644 index 00000000000000..d2bf2b8547f68f --- /dev/null +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/exceptions_table_utility_bar.test.tsx @@ -0,0 +1,43 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { TestProviders } from '../../../../../../common/mock'; +import { render, screen, within } from '@testing-library/react'; +import { ExceptionsTableUtilityBar } from './exceptions_table_utility_bar'; + +describe('ExceptionsTableUtilityBar', () => { + it('displays correct exception lists label and refresh rules action button', () => { + const EXCEPTION_LISTS_NUMBER = 25; + render( + + + + ); + + expect(screen.getByTestId('showingExceptionLists')).toBeInTheDocument(); + expect(screen.getByTestId('refreshRulesAction')).toBeInTheDocument(); + expect(screen.getByText(`Showing ${EXCEPTION_LISTS_NUMBER} lists`)).toBeInTheDocument(); + }); + + it('invokes refresh on refresh action click', () => { + const mockRefresh = jest.fn(); + render( + + + + ); + + const buttonWrapper = screen.getByTestId('refreshRulesAction'); + within(buttonWrapper).getByRole('button').click(); + + expect(mockRefresh).toHaveBeenCalled(); + }); +}); diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/exceptions_table_utility_bar.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/exceptions_table_utility_bar.tsx new file mode 100644 index 00000000000000..062b4b0fef8f9a --- /dev/null +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/exceptions_table_utility_bar.tsx @@ -0,0 +1,51 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; + +import { + UtilityBar, + UtilityBarAction, + UtilityBarGroup, + UtilityBarSection, + UtilityBarText, +} from '../../../../../../common/components/utility_bar'; +import * as i18n from './translations'; + +interface ExceptionsTableUtilityBarProps { + onRefresh?: () => void; + totalExceptionLists: number; +} + +export const ExceptionsTableUtilityBar: React.FC = ({ + onRefresh, + totalExceptionLists, +}) => { + return ( + + + + + {i18n.SHOWING_EXCEPTION_LISTS(totalExceptionLists)} + + + + + {i18n.REFRESH_EXCEPTIONS_TABLE} + + + + + ); +}; + +ExceptionsTableUtilityBar.displayName = 'ExceptionsTableUtilityBar'; diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/translations.ts b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/translations.ts index 004b6c5d97bec9..b22d4030384a38 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/translations.ts +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/translations.ts @@ -28,6 +28,15 @@ export const EXCEPTION_LIST_ACTIONS = i18n.translate( } ); +export const SHOWING_EXCEPTION_LISTS = (totalLists: number) => + i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.all.exceptions.showingExceptionLists', + { + values: { totalLists }, + defaultMessage: 'Showing {totalLists} {totalLists, plural, =1 {list} other {lists}}', + } + ); + export const RULES_ASSIGNED_TO_TITLE = i18n.translate( 'xpack.securitySolution.detectionEngine.rules.all.exceptions.rulesAssignedTitle', { @@ -151,3 +160,10 @@ export const EXCEPTION_LIST_SEARCH_PLACEHOLDER = i18n.translate( defaultMessage: 'e.g. Example List Name', } ); + +export const REFRESH_EXCEPTIONS_TABLE = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.all.exceptions.refresh', + { + defaultMessage: 'Refresh', + } +); diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/utility_bar.test.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/rules_table_utility_bar.test.tsx similarity index 52% rename from x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/utility_bar.test.tsx rename to x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/rules_table_utility_bar.test.tsx index 91f4a0b06e71d9..4fecfc4afa6a23 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/utility_bar.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/rules_table_utility_bar.test.tsx @@ -9,67 +9,80 @@ import React from 'react'; import { mount } from 'enzyme'; import { waitFor } from '@testing-library/react'; -import { AllRulesUtilityBar } from './utility_bar'; +import { getShowingRulesParams, RulesTableUtilityBar } from './rules_table_utility_bar'; import { TestProviders } from '../../../../../common/mock'; -describe('AllRules', () => { - it('renders AllRulesUtilityBar total rules and selected rules', () => { +jest.mock('./rules_table/rules_table_context'); + +describe('RulesTableUtilityBar', () => { + it('renders RulesTableUtilityBar total rules and selected rules', () => { const wrapper = mount( - ); - expect(wrapper.find('[data-test-subj="showingRules"]').at(0).text()).toEqual('Showing 4 rules'); + expect(wrapper.find('[data-test-subj="showingRules"]').at(0).text()).toEqual( + 'Showing 1-10 of 21 rules' + ); expect(wrapper.find('[data-test-subj="selectedRules"]').at(0).text()).toEqual( 'Selected 1 rule' ); }); - it('does not render total selected and bulk actions when "hasBulkActions" is false', () => { + it('renders correct pagination label according to pagination data', () => { const wrapper = mount( - ); - - expect(wrapper.find('[data-test-subj="showingRules"]').exists()).toBeFalsy(); - expect(wrapper.find('[data-test-subj="tableBulkActions"]').exists()).toBeFalsy(); - expect(wrapper.find('[data-test-subj="showingExceptionLists"]').at(0).text()).toEqual( - 'Showing 4 lists' + expect(wrapper.find('[data-test-subj="showingRules"]').at(0).text()).toEqual( + 'Showing 1-10 of 21 rules' ); }); it('renders utility actions if user has permissions', () => { const wrapper = mount( - ); @@ -80,15 +93,19 @@ describe('AllRules', () => { it('renders no utility actions if user has no permissions', () => { const wrapper = mount( - ); @@ -100,15 +117,19 @@ describe('AllRules', () => { const mockRefresh = jest.fn(); const wrapper = mount( - ); @@ -122,15 +143,19 @@ describe('AllRules', () => { const mockSwitch = jest.fn(); const wrapper = mount( - ); @@ -146,15 +171,19 @@ describe('AllRules', () => { const mockSwitch = jest.fn(); const wrapper = mount( - ); @@ -165,4 +194,72 @@ describe('AllRules', () => { expect(mockSwitch).not.toHaveBeenCalled(); }); }); + + describe('getShowingRulesParams creates correct label when', () => { + it('there are 0 rules to display', () => { + const pagination = { + page: 1, + perPage: 10, + total: 0, + }; + const [firstInPage, lastInPage] = getShowingRulesParams(pagination); + expect(firstInPage).toEqual(0); + expect(lastInPage).toEqual(0); + }); + + it('there is 1 rule to display', () => { + const pagination = { + page: 1, + perPage: 10, + total: 1, + }; + const [firstInPage, lastInPage] = getShowingRulesParams(pagination); + expect(firstInPage).toEqual(1); + expect(lastInPage).toEqual(1); + }); + + it('the table displays the first page, and rules per page is less than total rules', () => { + const pagination = { + page: 1, + perPage: 10, + total: 21, + }; + const [firstInPage, lastInPage] = getShowingRulesParams(pagination); + expect(firstInPage).toEqual(1); + expect(lastInPage).toEqual(10); + }); + + it('the table displays the first page, and rules per page is greater than total rules', () => { + const pagination = { + page: 1, + perPage: 10, + total: 8, + }; + const [firstInPage, lastInPage] = getShowingRulesParams(pagination); + expect(firstInPage).toEqual(1); + expect(lastInPage).toEqual(8); + }); + + it('the table displays the second page, and rules per page is less than total rules', () => { + const pagination = { + page: 2, + perPage: 10, + total: 31, + }; + const [firstInPage, lastInPage] = getShowingRulesParams(pagination); + expect(firstInPage).toEqual(11); + expect(lastInPage).toEqual(20); + }); + + it('the table displays the last page, displaying the remaining rules', () => { + const pagination = { + page: 2, + perPage: 100, + total: 101, + }; + const [firstInPage, lastInPage] = getShowingRulesParams(pagination); + expect(firstInPage).toEqual(101); + expect(lastInPage).toEqual(101); + }); + }); }); diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/utility_bar.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/rules_table_utility_bar.tsx similarity index 58% rename from x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/utility_bar.tsx rename to x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/rules_table_utility_bar.tsx index 4809a44528e2ae..7f9b0dba048813 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/utility_bar.tsx +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/rules_table_utility_bar.tsx @@ -25,25 +25,31 @@ import { } from '../../../../../common/components/utility_bar'; import * as i18n from '../translations'; import { useKibana } from '../../../../../common/lib/kibana'; -import { useRulesTableContextOptional } from './rules_table/rules_table_context'; +import { useRulesTableContext } from './rules_table/rules_table_context'; +import type { PaginationOptions } from '../../../../containers/detection_engine/rules/types'; -interface AllRulesUtilityBarProps { +export const getShowingRulesParams = ({ page, perPage, total: totalRules }: PaginationOptions) => { + const firstInPage = totalRules === 0 ? 0 : (page - 1) * perPage + 1; + const lastInPage = page * perPage > totalRules ? totalRules : page * perPage; + + return [firstInPage, lastInPage, totalRules] as const; +}; + +interface RulesTableUtilityBarProps { canBulkEdit: boolean; isAllSelected?: boolean; isAutoRefreshOn?: boolean; numberSelectedItems: number; onGetBulkItemsPopoverContent?: (closePopover: () => void) => EuiContextMenuPanelDescriptor[]; - onRefresh?: () => void; - onRefreshSwitch?: (checked: boolean) => void; - onToggleSelectAll?: () => void; - paginationTotal: number; - hasBulkActions: boolean; - hasPagination?: boolean; + onRefresh: () => void; + onRefreshSwitch: (checked: boolean) => void; + onToggleSelectAll: () => void; + pagination: PaginationOptions; isBulkActionInProgress?: boolean; hasDisabledActions?: boolean; } -export const AllRulesUtilityBar = React.memo( +export const RulesTableUtilityBar = React.memo( ({ canBulkEdit, isAllSelected, @@ -53,14 +59,12 @@ export const AllRulesUtilityBar = React.memo( onRefresh, onRefreshSwitch, onToggleSelectAll, - paginationTotal, - hasBulkActions = true, - hasPagination, + pagination, isBulkActionInProgress, hasDisabledActions, }) => { const { timelines } = useKibana().services; - const rulesTableContext = useRulesTableContextOptional(); + const rulesTableContext = useRulesTableContext(); const isAnyRuleSelected = numberSelectedItems > 0; const handleGetBulkItemsPopoverContent = useCallback( @@ -125,73 +129,44 @@ export const AllRulesUtilityBar = React.memo( - {hasBulkActions ? ( - - {i18n.SHOWING_RULES(paginationTotal)} - - ) : ( - - {i18n.SHOWING_EXCEPTION_LISTS(paginationTotal)} - - )} + + {i18n.SHOWING_RULES(...getShowingRulesParams(pagination))} + + <> + + + {i18n.SELECTED_RULES(numberSelectedItems)} + - {hasBulkActions ? ( - <> - - - {i18n.SELECTED_RULES(numberSelectedItems)} - - - {canBulkEdit && onToggleSelectAll && hasPagination && ( - - {isAllSelected ? i18n.CLEAR_SELECTION : i18n.SELECT_ALL_RULES(paginationTotal)} - - )} - - {canBulkEdit && ( - - {i18n.BATCH_ACTIONS} - - )} - + {canBulkEdit && ( - {i18n.REFRESH} + {isAllSelected ? i18n.CLEAR_SELECTION : i18n.SELECT_ALL_RULES(pagination.total)} + )} + + {canBulkEdit && ( - {i18n.REFRESH_RULE_POPOVER_LABEL} + {i18n.BATCH_ACTIONS} - - - ) : ( - + )} + ( > {i18n.REFRESH} + + {i18n.REFRESH_RULE_POPOVER_LABEL} + - )} + + + + {timelines.getLastUpdated({ + showUpdating: rulesTableContext.state.isFetching, + updatedAt: rulesTableContext.state.lastUpdated, + })} - {rulesTableContext && ( - - {timelines.getLastUpdated({ - showUpdating: rulesTableContext.state.isFetching, - updatedAt: rulesTableContext.state.lastUpdated, - })} - - )} ); } ); -AllRulesUtilityBar.displayName = 'AllRulesUtilityBar'; +RulesTableUtilityBar.displayName = 'RulesTableUtilityBar'; diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/rules_tables.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/rules_tables.tsx index 328b9a51b30a33..d04832d2e738ce 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/rules_tables.tsx +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/rules_tables.tsx @@ -5,8 +5,6 @@ * 2.0. */ -/* eslint-disable complexity */ - import { EuiBasicTable, EuiConfirmModal, @@ -33,7 +31,7 @@ import { showRulesTable } from './helpers'; import { useRulesTableContext } from './rules_table/rules_table_context'; import { useAsyncConfirmation } from './rules_table/use_async_confirmation'; import { RulesTableFilters } from './rules_table_filters/rules_table_filters'; -import { AllRulesUtilityBar } from './utility_bar'; +import { RulesTableUtilityBar } from './rules_table_utility_bar'; import { useBulkActionsDryRun } from './bulk_actions/use_bulk_actions_dry_run'; import { useBulkActionsConfirmation } from './bulk_actions/use_bulk_actions_confirmation'; import { useBulkEditFormFlyout } from './bulk_actions/use_bulk_edit_form_flyout'; @@ -147,7 +145,6 @@ export const RulesTables = React.memo( } = useBulkEditFormFlyout(); const selectedItemsCount = isAllSelected ? pagination.total : selectedRuleIds.length; - const hasPagination = pagination.total > pagination.perPage; const { isBulkActionsDryRunLoading, executeBulkActionsDryRun } = useBulkActionsDryRun(); @@ -334,10 +331,9 @@ export const RulesTables = React.memo( )} {shouldShowRulesTable && ( <> - ( onToggleSelectAll={toggleSelectAll} isBulkActionInProgress={isBulkActionsDryRunLoading || loadingRulesAction != null} hasDisabledActions={loadingRulesAction != null} - hasBulkActions /> +export const SHOWING_RULES = (firstInPage: number, lastOfPage: number, totalRules: number) => i18n.translate('xpack.securitySolution.detectionEngine.rules.allRules.showingRulesTitle', { - values: { totalRules }, - defaultMessage: 'Showing {totalRules} {totalRules, plural, =1 {rule} other {rules}}', + values: { firstInPage, lastOfPage, totalRules }, + defaultMessage: + 'Showing {firstInPage}-{lastOfPage} of {totalRules} {totalRules, plural, =1 {rule} other {rules}}', }); export const SELECT_ALL_RULES = (totalRules: number) => @@ -839,12 +840,6 @@ export const REFRESH_RULE_POPOVER_LABEL = i18n.translate( } ); -export const SHOWING_EXCEPTION_LISTS = (totalLists: number) => - i18n.translate('xpack.securitySolution.detectionEngine.rules.allRules.showingExceptionLists', { - values: { totalLists }, - defaultMessage: 'Showing {totalLists} {totalLists, plural, =1 {list} other {lists}}', - }); - /** * Bulk Export */ diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/types.ts b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/types.ts index ce4060dcf6e87a..93910509193e2b 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/types.ts +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/types.ts @@ -19,6 +19,7 @@ import type { import type { Filter } from '@kbn/es-query'; import type { RuleAction } from '@kbn/alerting-plugin/common'; import type { DataViewListItem } from '@kbn/data-views-plugin/common'; +import type { Unit } from '@kbn/datemath'; import type { RuleAlertAction } from '../../../../../common/detection_engine/types'; import type { FieldValueQueryBar } from '../../../components/rules/query_bar'; @@ -242,6 +243,11 @@ export interface ActionsStepRuleJson { meta?: unknown; } +export interface QuickQueryPreviewOptions { + timeframe: Unit; + timeframeEnd: moment.Moment; +} + export interface AdvancedPreviewForm { interval: string; lookback: string; diff --git a/x-pack/plugins/security_solution/public/hosts/containers/hosts/index.tsx b/x-pack/plugins/security_solution/public/hosts/containers/hosts/index.tsx index e6e02c335180cc..156af86d9df371 100644 --- a/x-pack/plugins/security_solution/public/hosts/containers/hosts/index.tsx +++ b/x-pack/plugins/security_solution/public/hosts/containers/hosts/index.tsx @@ -17,7 +17,6 @@ import { generateTablePaginationOptions } from '../../../common/components/pagin import type { HostsEdges, PageInfoPaginated, - DocValueFields, HostsRequestOptions, } from '../../../../common/search_strategy'; import { HostsQueries } from '../../../../common/search_strategy'; @@ -44,7 +43,6 @@ export interface HostsArgs { } interface UseAllHost { - docValueFields?: DocValueFields[]; endDate: string; filterQuery?: ESTermQuery | string; indexNames: string[]; @@ -54,7 +52,6 @@ interface UseAllHost { } export const useAllHost = ({ - docValueFields, endDate, filterQuery, indexNames, @@ -136,7 +133,6 @@ export const useAllHost = ({ const myRequest = { ...(prevRequest ?? {}), defaultIndex: indexNames, - docValueFields: docValueFields ?? [], factoryQueryType: HostsQueries.hosts, filterQuery: createFilter(filterQuery), pagination: generateTablePaginationOptions(activePage, limit), @@ -155,17 +151,7 @@ export const useAllHost = ({ } return prevRequest; }); - }, [ - activePage, - direction, - docValueFields, - endDate, - filterQuery, - indexNames, - limit, - startDate, - sortField, - ]); + }, [activePage, direction, endDate, filterQuery, indexNames, limit, startDate, sortField]); useEffect(() => { if (!skip && hostsRequest) { diff --git a/x-pack/plugins/security_solution/public/management/components/artifact_list_page/components/artifact_flyout.test.tsx b/x-pack/plugins/security_solution/public/management/components/artifact_list_page/components/artifact_flyout.test.tsx index 7a95a328606cbd..ee3ac4a907ee48 100644 --- a/x-pack/plugins/security_solution/public/management/components/artifact_list_page/components/artifact_flyout.test.tsx +++ b/x-pack/plugins/security_solution/public/management/components/artifact_list_page/components/artifact_flyout.test.tsx @@ -146,7 +146,9 @@ describe('When the flyout is opened in the ArtifactListPage component', () => { let getByTestId: typeof renderResult['getByTestId']; beforeEach(async () => { - await render(); + await act(async () => { + await render(); + }); getByTestId = renderResult.getByTestId; @@ -166,34 +168,38 @@ describe('When the flyout is opened in the ArtifactListPage component', () => { } }); - it('should disable all buttons while an update is in flight', () => { - expect(getByTestId('testPage-flyout-cancelButton')).not.toBeEnabled(); - expect(getByTestId('testPage-flyout-submitButton')).not.toBeEnabled(); + it('should disable all buttons while an update is in flight', async () => { + await waitFor(() => { + expect(getByTestId('testPage-flyout-cancelButton')).not.toBeEnabled(); + expect(getByTestId('testPage-flyout-submitButton')).not.toBeEnabled(); + }); }); - it('should display loading indicator on Submit while an update is in flight', () => { - expect( - getByTestId('testPage-flyout-submitButton').querySelector('.euiLoadingSpinner') - ).toBeTruthy(); + it('should display loading indicator on Submit while an update is in flight', async () => { + await waitFor(() => + expect( + getByTestId('testPage-flyout-submitButton').querySelector('.euiLoadingSpinner') + ).toBeTruthy() + ); }); - it('should pass `disabled=true` to the Form component while an update is in flight', () => { - expect(getLastFormComponentProps().disabled).toBe(true); + it('should pass `disabled=true` to the Form component while an update is in flight', async () => { + await waitFor(() => expect(getLastFormComponentProps().disabled).toBe(true)); }); }); describe('and submit is successful', () => { beforeEach(async () => { - await render(); + await act(async () => { + await render(); + }); act(() => { userEvent.click(renderResult.getByTestId('testPage-flyout-submitButton')); }); - await act(async () => { - await waitFor(() => { - expect(renderResult.queryByTestId('testPage-flyout')).toBeNull(); - }); + await waitFor(() => { + expect(renderResult.queryByTestId('testPage-flyout')).toBeNull(); }); }); @@ -209,25 +215,25 @@ describe('When the flyout is opened in the ArtifactListPage component', () => { }); describe('and submit fails', () => { - beforeEach(async () => { + beforeEach(() => { const _renderAndWaitForFlyout = render; render = async (...args) => { - mockedApi.responseProvider.trustedAppCreate.mockImplementation(() => { - throw new Error('oh oh. no good!'); - }); + mockedApi.responseProvider.trustedAppCreate.mockRejectedValue( + new Error('oh oh. no good!') as never + ); - await _renderAndWaitForFlyout(...args); + await act(async () => { + await _renderAndWaitForFlyout(...args); + }); act(() => { userEvent.click(renderResult.getByTestId('testPage-flyout-submitButton')); }); - await act(async () => { - await waitFor(() => - expect(mockedApi.responseProvider.trustedAppCreate).toHaveBeenCalled() - ); - }); + await waitFor(() => + expect(mockedApi.responseProvider.trustedAppCreate).toHaveBeenCalled() + ); return renderResult; }; @@ -270,7 +276,9 @@ describe('When the flyout is opened in the ArtifactListPage component', () => { return new ExceptionsListItemGenerator().generateTrustedApp(item); }); - await render({ onFormSubmit: handleSubmitCallback }); + await act(async () => { + await render({ onFormSubmit: handleSubmitCallback }); + }); act(() => { userEvent.click(renderResult.getByTestId('testPage-flyout-submitButton')); @@ -319,8 +327,10 @@ describe('When the flyout is opened in the ArtifactListPage component', () => { }); describe('and in Edit mode', () => { - beforeEach(async () => { - history.push('somepage?show=edit&itemId=123'); + beforeEach(() => { + act(() => { + history.push('somepage?show=edit&itemId=123'); + }); }); it('should show loader while initializing in edit mode', async () => { @@ -355,10 +365,8 @@ describe('When the flyout is opened in the ArtifactListPage component', () => { it('should provide Form component with the item for edit', async () => { const { getByTestId } = await render(); - await act(async () => { - await waitFor(() => { - expect(getByTestId('formMock')).toBeTruthy(); - }); + await waitFor(() => { + expect(getByTestId('formMock')).toBeTruthy(); }); const expectedProps = { @@ -373,37 +381,34 @@ describe('When the flyout is opened in the ArtifactListPage component', () => { expectedProps.entries ) as ExceptionListItemSchema['entries']; - expect(getLastFormComponentProps().item).toEqual(expectedProps); + await waitFor(() => { + expect(getLastFormComponentProps().item).toEqual(expectedProps); + }); }); it('should show error toast and close flyout if item for edit does not exist', async () => { - mockedApi.responseProvider.trustedApp.mockImplementation(() => { - throw new Error('does not exist'); - }); - - await render(); + mockedApi.responseProvider.trustedApp.mockRejectedValue(new Error('does not exist') as never); await act(async () => { - await waitFor(() => { - expect(mockedApi.responseProvider.trustedApp).toHaveBeenCalled(); - }); + await render(); }); - expect(coreStart.notifications.toasts.addWarning).toHaveBeenCalledWith( - 'Failed to retrieve item for edit. Reason: does not exist' - ); + await waitFor(() => { + expect(mockedApi.responseProvider.trustedApp).toHaveBeenCalled(); + + expect(coreStart.notifications.toasts.addWarning).toHaveBeenCalledWith( + 'Failed to retrieve item for edit. Reason: does not exist' + ); + }); }); it('should not show the expired license callout', async () => { const { queryByTestId, getByTestId } = await render(); - await act(async () => { - await waitFor(() => { - expect(getByTestId('formMock')).toBeTruthy(); - }); + await waitFor(() => { + expect(getByTestId('formMock')).toBeTruthy(); + expect(queryByTestId('testPage-flyout-expiredLicenseCallout')).not.toBeTruthy(); }); - - expect(queryByTestId('testPage-flyout-expiredLicenseCallout')).not.toBeTruthy(); }); it('should show expired license warning when unsupported features are being used (downgrade scenario)', async () => { @@ -425,13 +430,10 @@ describe('When the flyout is opened in the ArtifactListPage component', () => { const { getByTestId } = await render(); - await act(async () => { - await waitFor(() => { - expect(getByTestId('formMock')).toBeTruthy(); - }); + await waitFor(() => { + expect(getByTestId('formMock')).toBeTruthy(); + expect(getByTestId('testPage-flyout-expiredLicenseCallout')).toBeTruthy(); }); - - expect(getByTestId('testPage-flyout-expiredLicenseCallout')).toBeTruthy(); }); }); }); diff --git a/x-pack/plugins/security_solution/public/management/components/artifact_list_page/components/artifact_flyout.tsx b/x-pack/plugins/security_solution/public/management/components/artifact_list_page/components/artifact_flyout.tsx index e0ec473d22dad9..4d9f53c73341ec 100644 --- a/x-pack/plugins/security_solution/public/management/components/artifact_list_page/components/artifact_flyout.tsx +++ b/x-pack/plugins/security_solution/public/management/components/artifact_list_page/components/artifact_flyout.tsx @@ -231,7 +231,7 @@ export const ArtifactFlyout = memo( }, [externalSubmitHandlerError, internalSubmitError, submitHandler]); const { - isLoading: isLoadingItemForEdit, + isRefetching: isLoadingItemForEdit, error, refetch: fetchItemForEdit, } = useGetArtifact(apiClient, urlParams.itemId ?? '', undefined, { diff --git a/x-pack/plugins/security_solution/public/management/components/artifact_list_page/hooks/use_with_artifact_list_data.ts b/x-pack/plugins/security_solution/public/management/components/artifact_list_page/hooks/use_with_artifact_list_data.ts index 1f343142ee18ee..813e205b64c9a8 100644 --- a/x-pack/plugins/security_solution/public/management/components/artifact_list_page/hooks/use_with_artifact_list_data.ts +++ b/x-pack/plugins/security_solution/public/management/components/artifact_list_page/hooks/use_with_artifact_list_data.ts @@ -7,7 +7,7 @@ import { useEffect, useMemo, useState } from 'react'; import type { Pagination } from '@elastic/eui'; -import { useQuery } from 'react-query'; +import { useQuery } from '@tanstack/react-query'; import type { ServerApiError } from '../../../../common/types'; import { useIsMounted } from '../../../hooks/use_is_mounted'; import { MANAGEMENT_PAGE_SIZE_OPTIONS } from '../../../common/constants'; diff --git a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/action_log_button.tsx b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/action_log_button.tsx index bdfd987af131b9..85a5f2655dd68a 100644 --- a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/action_log_button.tsx +++ b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/action_log_button.tsx @@ -9,7 +9,7 @@ import React, { memo, useCallback, useState } from 'react'; import { EuiButton, EuiFlyout, EuiFlyoutBody, EuiFlyoutHeader, EuiTitle } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; import type { EndpointResponderExtensionComponentProps } from './types'; -import { ResponseActionsList } from '../endpoint_response_actions_list/response_actions_list'; +import { ResponseActionsLog } from '../endpoint_response_actions_list/response_actions_log'; import { UX_MESSAGES } from '../endpoint_response_actions_list/translations'; export const ActionLogButton = memo((props) => { @@ -46,7 +46,7 @@ export const ActionLogButton = memo((p - + )} diff --git a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/status_action.tsx b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/status_action.tsx index de8987f47ea557..b75a480765844c 100644 --- a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/status_action.tsx +++ b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/status_action.tsx @@ -46,7 +46,7 @@ export const EndpointStatusActionResult = memo< error: fetchedDetailsError, isFetching, isFetched, - } = useGetEndpointDetails(endpointId, { enabled: isPending, queryKey }); + } = useGetEndpointDetails(endpointId, { enabled: isPending, queryKey: [queryKey] }); const { data: fetchedPendingActionsSummary } = useGetEndpointPendingActionsSummary([endpointId], { enabled: isPending, diff --git a/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/components/action_list_date_range_picker.tsx b/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/components/actions_log_date_range_picker.tsx similarity index 79% rename from x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/components/action_list_date_range_picker.tsx rename to x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/components/actions_log_date_range_picker.tsx index cf453e20707058..015fd3a501621a 100644 --- a/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/components/action_list_date_range_picker.tsx +++ b/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/components/actions_log_date_range_picker.tsx @@ -5,8 +5,8 @@ * 2.0. */ -import React, { useCallback, memo, useState } from 'react'; -import { EuiFlexGroup, EuiFlexItem, EuiSuperDatePicker, EuiSuperUpdateButton } from '@elastic/eui'; +import React, { memo, useState } from 'react'; +import { EuiFlexGroup, EuiFlexItem, EuiSuperDatePicker } from '@elastic/eui'; import type { IDataPluginServices } from '@kbn/data-plugin/public'; import { euiStyled } from '@kbn/kibana-react-plugin/common'; import type { EuiSuperDatePickerRecentRange } from '@elastic/eui'; @@ -16,7 +16,7 @@ import type { OnRefreshChangeProps, } from '@elastic/eui/src/components/date_picker/types'; import { UI_SETTINGS } from '@kbn/data-plugin/common'; -import type { useGetEndpointActionList } from '../../../hooks'; + import { useTestIdGenerator } from '../../../hooks/use_test_id_generator'; export interface DateRangePickerValues { @@ -33,21 +33,19 @@ const DatePickerWrapper = euiStyled.div` padding-bottom: ${(props) => `${props.theme.eui.euiCodeBlockPaddingModifiers.paddingLarge}`}; `; -export const ActionListDateRangePicker = memo( +export const ActionLogDateRangePicker = memo( ({ dateRangePickerState, isDataLoading, onRefresh, onRefreshChange, onTimeChange, - onClick, }: { dateRangePickerState: DateRangePickerValues; isDataLoading: boolean; onRefresh: () => void; onRefreshChange: (evt: OnRefreshChangeProps) => void; onTimeChange: ({ start, end }: DurationRange) => void; - onClick: ReturnType['refetch']; }) => { const getTestId = useTestIdGenerator('response-actions-list'); const kibana = useKibana(); @@ -65,7 +63,6 @@ export const ActionListDateRangePicker = memo( }) ?? [] ); }); - const onClickCallback = useCallback(() => onClick(), [onClick]); return ( @@ -88,19 +85,10 @@ export const ActionListDateRangePicker = memo( width="auto" /> - - - ); } ); -ActionListDateRangePicker.displayName = 'ActionListDateRangePicker'; +ActionLogDateRangePicker.displayName = 'ActionLogDateRangePicker'; diff --git a/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/components/actions_log_filter.tsx b/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/components/actions_log_filter.tsx new file mode 100644 index 00000000000000..1f89233a24ce78 --- /dev/null +++ b/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/components/actions_log_filter.tsx @@ -0,0 +1,103 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { memo, useCallback } from 'react'; +import { EuiFlexGroup, EuiFlexItem, EuiSelectable, EuiPopoverTitle } from '@elastic/eui'; +import { ActionsLogFilterPopover } from './actions_log_filter_popover'; +import { type FilterItems, type FilterName, useActionsLogFilter } from './hooks'; +import { ClearAllButton } from './clear_all_button'; +import { UX_MESSAGES } from '../translations'; +import { useTestIdGenerator } from '../../../hooks/use_test_id_generator'; + +export const ActionsLogFilter = memo( + ({ + filterName, + onChangeCommandsFilter, + }: { + filterName: FilterName; + onChangeCommandsFilter: (selectedCommands: string[]) => void; + }) => { + const getTestId = useTestIdGenerator('response-actions-list'); + const { items, setItems, hasActiveFilters, numActiveFilters, numFilters } = + useActionsLogFilter(); + + const onChange = useCallback( + (newOptions: FilterItems) => { + setItems(newOptions.map((e) => e)); + + // update selected filter state + const selectedItems = newOptions.reduce((acc, curr) => { + if (curr.checked === 'on') { + acc.push(curr.key); + } + return acc; + }, []); + + // update query state + onChangeCommandsFilter(selectedItems); + }, + [onChangeCommandsFilter, setItems] + ); + + // clear all selected options + const onClearAll = useCallback(() => { + setItems( + items.map((e) => { + e.checked = undefined; + return e; + }) + ); + onChangeCommandsFilter([]); + }, [items, setItems, onChangeCommandsFilter]); + + return ( + + + {(list, search) => ( +
+ + {search} + + {list} + + + + + +
+ )} +
+
+ ); + } +); + +ActionsLogFilter.displayName = 'ActionsLogFilter'; diff --git a/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/components/actions_log_filter_popover.tsx b/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/components/actions_log_filter_popover.tsx new file mode 100644 index 00000000000000..9d2aada871707f --- /dev/null +++ b/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/components/actions_log_filter_popover.tsx @@ -0,0 +1,79 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { memo, useState, useCallback, useMemo } from 'react'; +import { EuiPopover, EuiFilterButton, useGeneratedHtmlId } from '@elastic/eui'; +import { FILTER_NAMES } from '../translations'; +import type { FilterName } from './hooks'; +import { useTestIdGenerator } from '../../../hooks/use_test_id_generator'; + +export const ActionsLogFilterPopover = memo( + ({ + children, + filterName, + hasActiveFilters, + numActiveFilters, + numFilters, + }: { + children: React.ReactNode; + filterName: FilterName; + hasActiveFilters: boolean; + numActiveFilters: number; + numFilters: number; + }) => { + const getTestId = useTestIdGenerator('response-actions-list'); + const [isPopoverOpen, setIsPopoverOpen] = useState(false); + const onButtonClick = useCallback(() => { + setIsPopoverOpen(!isPopoverOpen); + }, [setIsPopoverOpen, isPopoverOpen]); + const closePopover = useCallback(() => { + setIsPopoverOpen(false); + }, [setIsPopoverOpen]); + const filterGroupPopoverId = useGeneratedHtmlId({ + prefix: 'filterGroupPopover', + }); + + const button = useMemo( + () => ( + + {FILTER_NAMES[filterName]} + + ), + [ + filterName, + getTestId, + hasActiveFilters, + isPopoverOpen, + numActiveFilters, + numFilters, + onButtonClick, + ] + ); + + return ( + + {children} + + ); + } +); + +ActionsLogFilterPopover.displayName = 'ActionsLogFilterPopover'; diff --git a/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/components/actions_log_filters.tsx b/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/components/actions_log_filters.tsx new file mode 100644 index 00000000000000..3f28d552276a20 --- /dev/null +++ b/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/components/actions_log_filters.tsx @@ -0,0 +1,83 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import React, { memo, useCallback, useMemo } from 'react'; +import { EuiFlexGroup, EuiFlexItem, EuiFilterGroup, EuiSuperUpdateButton } from '@elastic/eui'; +import type { + DurationRange, + OnRefreshChangeProps, +} from '@elastic/eui/src/components/date_picker/types'; +import type { useGetEndpointActionList } from '../../../hooks'; +import { + type DateRangePickerValues, + ActionLogDateRangePicker, +} from './actions_log_date_range_picker'; +import { ActionsLogFilter } from './actions_log_filter'; +import type { FilterName } from './hooks'; +import { useTestIdGenerator } from '../../../hooks/use_test_id_generator'; + +export const ActionsLogFilters = memo( + ({ + dateRangePickerState, + isDataLoading, + onClick, + onChangeCommandsFilter, + onRefresh, + onRefreshChange, + onTimeChange, + }: { + dateRangePickerState: DateRangePickerValues; + isDataLoading: boolean; + onChangeCommandsFilter: (selectedCommands: string[]) => void; + onRefresh: () => void; + onRefreshChange: (evt: OnRefreshChangeProps) => void; + onTimeChange: ({ start, end }: DurationRange) => void; + onClick: ReturnType['refetch']; + }) => { + const getTestId = useTestIdGenerator('response-actions-list'); + const filters = useMemo(() => { + // TODO: add more filter names here (users, hosts, statuses) + const filterNames: FilterName[] = ['actions']; + return filterNames.map((filterName) => ( + + )); + }, [onChangeCommandsFilter]); + + const onClickRefreshButton = useCallback(() => onClick(), [onClick]); + + return ( + + + + + + {filters} + + + + + + ); + } +); + +ActionsLogFilters.displayName = 'ActionsLogFilters'; diff --git a/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/components/clear_all_button.tsx b/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/components/clear_all_button.tsx new file mode 100644 index 00000000000000..96fd1dcc757aa1 --- /dev/null +++ b/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/components/clear_all_button.tsx @@ -0,0 +1,38 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { memo } from 'react'; +import { euiStyled } from '@kbn/kibana-react-plugin/common'; +import { EuiButtonEmpty } from '@elastic/eui'; +import { UX_MESSAGES } from '../translations'; + +const StyledEuiButtonEmpty = euiStyled(EuiButtonEmpty).attrs({ + iconType: 'crossInACircleFilled', + color: 'danger', +})` + border-top: ${(props) => `${props.theme.eui.euiBorderThin}`}; + border-radius : 0; +`; +export const ClearAllButton = memo( + ({ + 'data-test-subj': dataTestSubj, + isDisabled, + onClick, + }: { + 'data-test-subj'?: string; + isDisabled: boolean; + onClick: () => void; + }) => { + return ( + + {UX_MESSAGES.filterClearAll} + + ); + } +); + +ClearAllButton.displayName = 'ClearAllButton'; diff --git a/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/components/hooks.tsx b/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/components/hooks.tsx index 5ea37b444dad12..304e77c655751b 100644 --- a/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/components/hooks.tsx +++ b/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/components/hooks.tsx @@ -5,12 +5,14 @@ * 2.0. */ -import { useCallback, useState } from 'react'; +import { useCallback, useMemo, useState } from 'react'; import type { DurationRange, OnRefreshChangeProps, } from '@elastic/eui/src/components/date_picker/types'; -import type { DateRangePickerValues } from './action_list_date_range_picker'; +import type { DateRangePickerValues } from './actions_log_date_range_picker'; +import { RESPONSE_ACTION_COMMANDS } from '../../../../../common/endpoint/types'; +import type { FILTER_NAMES } from '../translations'; const defaultDateRangeOptions = Object.freeze({ autoRefreshOptions: { @@ -85,3 +87,30 @@ export const useDateRangePicker = () => { return { dateRangePickerState, onRefreshChange, onTimeChange }; }; + +export type FilterItems = Array<{ + key: string; + label: string; + checked: 'on' | undefined; +}>; + +// TODO: add more filter names here +export type FilterName = keyof typeof FILTER_NAMES; +export const useActionsLogFilter = () => { + const [items, setItems] = useState( + RESPONSE_ACTION_COMMANDS.slice().map((filter) => ({ + key: filter, + label: filter === 'unisolate' ? 'release' : filter, + checked: undefined, + })) + ); + + const hasActiveFilters = useMemo(() => !!items.find((item) => item.checked === 'on'), [items]); + const numActiveFilters = useMemo( + () => items.filter((item) => item.checked === 'on').length, + [items] + ); + const numFilters = useMemo(() => items.filter((item) => item.checked !== 'on').length, [items]); + + return { items, setItems, hasActiveFilters, numActiveFilters, numFilters }; +}; diff --git a/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/response_actions_list.tsx b/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/response_actions_list.tsx deleted file mode 100644 index 169128a373976f..00000000000000 --- a/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/response_actions_list.tsx +++ /dev/null @@ -1,547 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { - EuiAvatar, - EuiBadge, - EuiBasicTable, - EuiButtonIcon, - EuiDescriptionList, - EuiEmptyPrompt, - EuiFacetButton, - EuiFlexGroup, - EuiFlexItem, - EuiHorizontalRule, - EuiScreenReaderOnly, - EuiI18nNumber, - EuiText, - EuiCodeBlock, - EuiToolTip, - RIGHT_ALIGNMENT, -} from '@elastic/eui'; -import { euiStyled, css } from '@kbn/kibana-react-plugin/common'; - -import type { HorizontalAlignment, CriteriaWithPagination } from '@elastic/eui'; -import React, { memo, useCallback, useMemo, useState } from 'react'; -import { FormattedMessage } from '@kbn/i18n-react'; -import { getEmptyValue } from '../../../common/components/empty_value'; -import { FormattedDate } from '../../../common/components/formatted_date'; -import type { ActionDetails } from '../../../../common/endpoint/types'; -import type { EndpointActionListRequestQuery } from '../../../../common/endpoint/schema/actions'; -import { ManagementEmptyStateWrapper } from '../management_empty_state_wrapper'; -import { useGetEndpointActionList } from '../../hooks'; -import { OUTPUT_MESSAGES, TABLE_COLUMN_NAMES, UX_MESSAGES } from './translations'; -import { MANAGEMENT_PAGE_SIZE_OPTIONS } from '../../common/constants'; -import { useTestIdGenerator } from '../../hooks/use_test_id_generator'; -import { ActionListDateRangePicker } from './components/action_list_date_range_picker'; -import { useDateRangePicker } from './components/hooks'; - -const emptyValue = getEmptyValue(); - -const getCommand = ( - command: ActionDetails['command'] -): Exclude | 'release' => - command === 'unisolate' ? 'release' : command; - -// Truncated usernames -const StyledFacetButton = euiStyled(EuiFacetButton)` - .euiText { - margin-top: 0.38rem; - overflow-y: visible !important; - } -`; - -const customDescriptionListCss = css` - &.euiDescriptionList { - > .euiDescriptionList__title { - color: ${(props) => props.theme.eui.euiColorDarkShade}; - font-size: ${(props) => props.theme.eui.euiFontSizeXS}; - margin-top: ${(props) => props.theme.eui.euiSizeS}; - } - - > .euiDescriptionList__description { - font-weight: ${(props) => props.theme.eui.euiFontWeightSemiBold}; - margin-top: ${(props) => props.theme.eui.euiSizeS}; - } - } -`; - -const StyledDescriptionList = euiStyled(EuiDescriptionList).attrs({ - compressed: true, - type: 'column', -})` - ${customDescriptionListCss} -`; - -// output section styles -const topSpacingCss = css` - ${(props) => `${props.theme.eui.euiCodeBlockPaddingModifiers.paddingMedium} 0`} -`; -const dashedBorderCss = css` - ${(props) => `1px dashed ${props.theme.eui.euiColorDisabled}`}; -`; -const StyledDescriptionListOutput = euiStyled(EuiDescriptionList).attrs({ compressed: true })` - ${customDescriptionListCss} - dd { - margin: ${topSpacingCss}; - padding: ${topSpacingCss}; - border-top: ${dashedBorderCss}; - border-bottom: ${dashedBorderCss}; - } -`; - -// code block styles -const StyledEuiCodeBlock = euiStyled(EuiCodeBlock).attrs({ - transparentBackground: true, - paddingSize: 'none', -})` - code { - color: ${(props) => props.theme.eui.euiColorDarkShade} !important; - } -`; - -export const ResponseActionsList = memo< - Pick ->(({ agentIds, commands, userIds }) => { - const getTestId = useTestIdGenerator('response-actions-list'); - const [itemIdToExpandedRowMap, setItemIdToExpandedRowMap] = useState<{ - [k: ActionDetails['id']]: React.ReactNode; - }>({}); - - const [queryParams, setQueryParams] = useState({ - page: 1, - pageSize: 10, - agentIds, - commands, - userIds, - }); - - // date range picker state and handlers - const { dateRangePickerState, onRefreshChange, onTimeChange } = useDateRangePicker(); - - // initial fetch of list data - const { - error, - data: actionList, - isFetching, - isFetched, - refetch: reFetchEndpointActionList, - } = useGetEndpointActionList({ - ...queryParams, - startDate: dateRangePickerState.startDate, - endDate: dateRangePickerState.endDate, - }); - - // handle auto refresh data - const onRefresh = useCallback(() => { - if (dateRangePickerState.autoRefreshOptions.enabled) { - reFetchEndpointActionList(); - } - }, [dateRangePickerState.autoRefreshOptions.enabled, reFetchEndpointActionList]); - - // total actions - const totalItemCount = useMemo(() => actionList?.total ?? 0, [actionList]); - - // expanded tray contents - const toggleDetails = useCallback( - (item: ActionDetails) => { - const itemIdToExpandedRowMapValues = { ...itemIdToExpandedRowMap }; - if (itemIdToExpandedRowMapValues[item.id]) { - delete itemIdToExpandedRowMapValues[item.id]; - } else { - const { - startedAt, - completedAt, - isCompleted, - wasSuccessful, - isExpired, - command: _command, - parameters, - } = item; - - const parametersList = parameters - ? Object.entries(parameters).map(([key, value]) => { - return `${key}:${value}`; - }) - : undefined; - - const command = getCommand(_command); - const dataList = [ - { - title: OUTPUT_MESSAGES.expandSection.placedAt, - description: `${startedAt}`, - }, - { - title: OUTPUT_MESSAGES.expandSection.startedAt, - description: `${startedAt}`, - }, - { - title: OUTPUT_MESSAGES.expandSection.completedAt, - description: `${completedAt ?? emptyValue}`, - }, - { - title: OUTPUT_MESSAGES.expandSection.input, - description: `${command}`, - }, - { - title: OUTPUT_MESSAGES.expandSection.parameters, - description: parametersList ? parametersList : emptyValue, - }, - ].map(({ title, description }) => { - return { - title: {title}, - description: {description}, - }; - }); - - const outputList = [ - { - title: ( - {`${OUTPUT_MESSAGES.expandSection.output}:`} - ), - description: ( - // codeblock for output - - {isExpired - ? OUTPUT_MESSAGES.hasExpired(command) - : isCompleted - ? wasSuccessful - ? OUTPUT_MESSAGES.wasSuccessful(command) - : OUTPUT_MESSAGES.hasFailed(command) - : OUTPUT_MESSAGES.isPending(command)} - - ), - }, - ]; - - itemIdToExpandedRowMapValues[item.id] = ( - <> - - - - - - - - - - ); - } - setItemIdToExpandedRowMap(itemIdToExpandedRowMapValues); - }, - [getTestId, itemIdToExpandedRowMap] - ); - // memoized callback for toggleDetails - const onClickCallback = useCallback( - (data: ActionDetails) => () => toggleDetails(data), - [toggleDetails] - ); - - // table column - const responseActionListColumns = useMemo(() => { - const hideHostColumn = typeof agentIds === 'string'; - - const columns = [ - { - field: 'startedAt', - name: TABLE_COLUMN_NAMES.time, - width: hideHostColumn ? '21%' : '15%', - truncateText: true, - render: (startedAt: ActionDetails['startedAt']) => { - return ( - - ); - }, - }, - { - field: 'command', - name: TABLE_COLUMN_NAMES.command, - width: hideHostColumn ? '21%' : '10%', - truncateText: true, - render: (_command: ActionDetails['command']) => { - const command = getCommand(_command); - return ( - - - - ); - }, - }, - { - field: 'createdBy', - name: TABLE_COLUMN_NAMES.user, - width: hideHostColumn ? '21%' : '14%', - truncateText: true, - render: (userId: ActionDetails['createdBy']) => { - return ( - - } - > - - - {userId} - - - - ); - }, - }, - // conditional hostname column - { - field: 'agents', - name: TABLE_COLUMN_NAMES.host, - width: '20%', - truncateText: true, - render: (agents: ActionDetails['agents']) => { - // TODO: compute host names later with hostMetadata? (using agent Ids for now) - const hostname = agents?.[0] ?? ''; - return ( - - - {hostname} - - - ); - }, - }, - { - field: 'comment', - name: TABLE_COLUMN_NAMES.comments, - width: hideHostColumn ? '21%' : '30%', - truncateText: true, - render: (comment: ActionDetails['comment']) => { - return ( - - - {comment ?? emptyValue} - - - ); - }, - }, - { - field: 'isCompleted', - name: TABLE_COLUMN_NAMES.status, - width: hideHostColumn ? '15%' : '10%', - render: (isCompleted: ActionDetails['isCompleted'], data: ActionDetails) => { - const status = data.isExpired - ? UX_MESSAGES.badge.failed - : isCompleted - ? data.wasSuccessful - ? UX_MESSAGES.badge.completed - : UX_MESSAGES.badge.failed - : UX_MESSAGES.badge.pending; - - return ( - - - - - - ); - }, - }, - { - field: '', - align: RIGHT_ALIGNMENT as HorizontalAlignment, - width: '40px', - isExpander: true, - name: ( - - {UX_MESSAGES.screenReaderExpand} - - ), - render: (data: ActionDetails) => { - return ( - - ); - }, - }, - ]; - // filter out the host column - if (hideHostColumn) { - return columns.filter((column) => column.field !== 'agents'); - } - return columns; - }, [agentIds, getTestId, itemIdToExpandedRowMap, onClickCallback]); - - // table pagination - const tablePagination = useMemo(() => { - return { - // this controls the table UI page - // to match 0-based table paging - pageIndex: (queryParams.page || 1) - 1, - pageSize: queryParams.pageSize || 10, - totalItemCount, - pageSizeOptions: MANAGEMENT_PAGE_SIZE_OPTIONS as number[], - }; - }, [queryParams, totalItemCount]); - - // handle onChange - const handleTableOnChange = useCallback( - ({ page: _page }: CriteriaWithPagination) => { - // table paging is 0 based - const { index, size } = _page; - setQueryParams((prevState) => ({ - ...prevState, - // adjust the page to conform to - // 1-based API page - page: index + 1, - pageSize: size, - })); - reFetchEndpointActionList(); - }, - [reFetchEndpointActionList, setQueryParams] - ); - - // compute record ranges - const pagedResultsCount = useMemo(() => { - const page = queryParams.page ?? 1; - const perPage = queryParams?.pageSize ?? 10; - - const totalPages = Math.ceil(totalItemCount / perPage); - const fromCount = perPage * page - perPage + 1; - const toCount = - page === totalPages || totalPages === 1 ? totalItemCount : fromCount + perPage - 1; - return { fromCount, toCount }; - }, [queryParams.page, queryParams.pageSize, totalItemCount]); - - // create range label to display - const recordRangeLabel = useMemo( - () => ( - - - - {'-'} - - - ), - total: , - recordsLabel: {UX_MESSAGES.recordsLabel(totalItemCount)}, - }} - /> - - ), - [getTestId, pagedResultsCount.fromCount, pagedResultsCount.toCount, totalItemCount] - ); - - return ( - <> - - {isFetched && !totalItemCount ? ( - - - - - - } - body={ -

- -

- } - data-test-subj="responseActions-empty" - /> -
-
- ) : ( - <> - {recordRangeLabel} - - - - )} - - ); -}); - -ResponseActionsList.displayName = 'ResponseActionsList'; diff --git a/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/response_actions_list.test.tsx b/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/response_actions_log.test.tsx similarity index 88% rename from x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/response_actions_list.test.tsx rename to x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/response_actions_log.test.tsx index 57cbfff15790ba..a731bf784f2e90 100644 --- a/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/response_actions_list.test.tsx +++ b/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/response_actions_log.test.tsx @@ -12,7 +12,7 @@ import userEvent from '@testing-library/user-event'; import { waitForEuiPopoverOpen } from '@elastic/eui/lib/test/rtl'; import type { AppContextTestRender } from '../../../common/mock/endpoint'; import { createAppRootMockRenderer } from '../../../common/mock/endpoint'; -import { ResponseActionsList } from './response_actions_list'; +import { ResponseActionsLog } from './response_actions_log'; import type { ActionDetails, ActionListApiResponse } from '../../../../common/endpoint/types'; import { MANAGEMENT_PATH } from '../../../../common/constants'; import { EndpointActionGenerator } from '../../../../common/endpoint/data_generators/endpoint_action_generator'; @@ -106,11 +106,11 @@ jest.mock('@kbn/kibana-react-plugin/public', () => { }; }); -describe('Response Actions List', () => { +describe('Response Actions Log', () => { const testPrefix = 'response-actions-list'; let render: ( - props?: React.ComponentProps + props?: React.ComponentProps ) => ReturnType; let renderResult: ReturnType; let history: AppContextTestRender['history']; @@ -127,8 +127,8 @@ describe('Response Actions List', () => { beforeEach(async () => { mockedContext = createAppRootMockRenderer(); ({ history } = mockedContext); - render = (props?: React.ComponentProps) => - (renderResult = mockedContext.render()); + render = (props?: React.ComponentProps) => + (renderResult = mockedContext.render()); reactTestingLibrary.act(() => { history.push(`${MANAGEMENT_PATH}/response_actions`); }); @@ -152,6 +152,11 @@ describe('Response Actions List', () => { expect(renderResult.getByTestId(`${testPrefix}-super-date-picker`)).toBeTruthy(); }); + it('should show actions filter', () => { + render(); + expect(renderResult.getByTestId(`${testPrefix}-actions-filter-popoverButton`)).toBeTruthy(); + }); + it('should show empty state when there is no data', async () => { mockUseGetEndpointActionList = { ...baseMockedActionList, @@ -282,9 +287,7 @@ describe('Response Actions List', () => { it('should refresh data when super date picker refresh button is clicked', async () => { render(); - const superRefreshButton = renderResult.getByTestId( - `${testPrefix}-super-date-picker-refresh-button` - ); + const superRefreshButton = renderResult.getByTestId(`${testPrefix}-super-refresh-button`); userEvent.click(superRefreshButton); expect(refetchFunction).toHaveBeenCalledTimes(1); }); @@ -414,6 +417,40 @@ describe('Response Actions List', () => { ).toEqual(['Time', 'Command', 'User', 'Host', 'Comments', 'Status']); }); }); + + describe('Actions filter', () => { + const filterPrefix = '-actions-filter'; + + it('should have a search bar', () => { + render(); + userEvent.click(renderResult.getByTestId(`${testPrefix}${filterPrefix}-popoverButton`)); + const searchBar = renderResult.getByTestId(`${testPrefix}${filterPrefix}-search`); + expect(searchBar).toBeTruthy(); + expect(searchBar.querySelector('input')?.getAttribute('placeholder')).toEqual( + 'Search actions' + ); + }); + + it('should show a list of actions when opened', () => { + render(); + userEvent.click(renderResult.getByTestId(`${testPrefix}${filterPrefix}-popoverButton`)); + const filterList = renderResult.getByTestId(`${testPrefix}${filterPrefix}-popoverList`); + expect(filterList).toBeTruthy(); + expect(filterList.querySelectorAll('ul>li').length).toEqual(5); + expect( + Array.from(filterList.querySelectorAll('ul>li')).map((option) => option.textContent) + ).toEqual(['isolate', 'release', 'kill-process', 'suspend-process', 'running-processes']); + }); + + it('should have `clear all` button `disabled` when no selected values', () => { + render(); + userEvent.click(renderResult.getByTestId(`${testPrefix}${filterPrefix}-popoverButton`)); + const clearAllButton = renderResult.getByTestId( + `${testPrefix}${filterPrefix}-clearAllButton` + ); + expect(clearAllButton.hasAttribute('disabled')).toBeTruthy(); + }); + }); }); // mock API response diff --git a/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/response_actions_log.tsx b/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/response_actions_log.tsx new file mode 100644 index 00000000000000..7afb5ce81f4cf4 --- /dev/null +++ b/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/response_actions_log.tsx @@ -0,0 +1,556 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { + EuiAvatar, + EuiBadge, + EuiBasicTable, + EuiButtonIcon, + EuiDescriptionList, + EuiEmptyPrompt, + EuiFacetButton, + EuiFlexGroup, + EuiFlexItem, + EuiHorizontalRule, + EuiScreenReaderOnly, + EuiI18nNumber, + EuiText, + EuiCodeBlock, + EuiToolTip, + RIGHT_ALIGNMENT, +} from '@elastic/eui'; +import { euiStyled, css } from '@kbn/kibana-react-plugin/common'; + +import type { HorizontalAlignment, CriteriaWithPagination } from '@elastic/eui'; +import React, { memo, useCallback, useMemo, useState } from 'react'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { getEmptyValue } from '../../../common/components/empty_value'; +import { FormattedDate } from '../../../common/components/formatted_date'; +import type { ActionDetails } from '../../../../common/endpoint/types'; +import type { EndpointActionListRequestQuery } from '../../../../common/endpoint/schema/actions'; +import { ManagementEmptyStateWrapper } from '../management_empty_state_wrapper'; +import { useGetEndpointActionList } from '../../hooks'; +import { OUTPUT_MESSAGES, TABLE_COLUMN_NAMES, UX_MESSAGES } from './translations'; +import { MANAGEMENT_PAGE_SIZE_OPTIONS } from '../../common/constants'; +import { useTestIdGenerator } from '../../hooks/use_test_id_generator'; +import { ActionsLogFilters } from './components/actions_log_filters'; +import { useDateRangePicker } from './components/hooks'; + +const emptyValue = getEmptyValue(); + +const getCommand = ( + command: ActionDetails['command'] +): Exclude | 'release' => + command === 'unisolate' ? 'release' : command; + +// Truncated usernames +const StyledFacetButton = euiStyled(EuiFacetButton)` + .euiText { + margin-top: 0.38rem; + overflow-y: visible !important; + } +`; + +const customDescriptionListCss = css` + &.euiDescriptionList { + > .euiDescriptionList__title { + color: ${(props) => props.theme.eui.euiColorDarkShade}; + font-size: ${(props) => props.theme.eui.euiFontSizeXS}; + margin-top: ${(props) => props.theme.eui.euiSizeS}; + } + + > .euiDescriptionList__description { + font-weight: ${(props) => props.theme.eui.euiFontWeightSemiBold}; + margin-top: ${(props) => props.theme.eui.euiSizeS}; + } + } +`; + +const StyledDescriptionList = euiStyled(EuiDescriptionList).attrs({ + compressed: true, + type: 'column', +})` + ${customDescriptionListCss} +`; + +// output section styles +const topSpacingCss = css` + ${(props) => `${props.theme.eui.euiCodeBlockPaddingModifiers.paddingMedium} 0`} +`; +const dashedBorderCss = css` + ${(props) => `1px dashed ${props.theme.eui.euiColorDisabled}`}; +`; +const StyledDescriptionListOutput = euiStyled(EuiDescriptionList).attrs({ compressed: true })` + ${customDescriptionListCss} + dd { + margin: ${topSpacingCss}; + padding: ${topSpacingCss}; + border-top: ${dashedBorderCss}; + border-bottom: ${dashedBorderCss}; + } +`; + +// code block styles +const StyledEuiCodeBlock = euiStyled(EuiCodeBlock).attrs({ + transparentBackground: true, + paddingSize: 'none', +})` + code { + color: ${(props) => props.theme.eui.euiColorDarkShade} !important; + } +`; + +export const ResponseActionsLog = memo>( + ({ agentIds }) => { + const getTestId = useTestIdGenerator('response-actions-list'); + const [itemIdToExpandedRowMap, setItemIdToExpandedRowMap] = useState<{ + [k: ActionDetails['id']]: React.ReactNode; + }>({}); + + const [queryParams, setQueryParams] = useState({ + page: 1, + pageSize: 10, + agentIds, + commands: [], + userIds: [], + }); + + // date range picker state and handlers + const { dateRangePickerState, onRefreshChange, onTimeChange } = useDateRangePicker(); + + // initial fetch of list data + const { + error, + data: actionList, + isFetching, + isFetched, + refetch: reFetchEndpointActionList, + } = useGetEndpointActionList({ + ...queryParams, + startDate: dateRangePickerState.startDate, + endDate: dateRangePickerState.endDate, + }); + + // handle auto refresh data + const onRefresh = useCallback(() => { + if (dateRangePickerState.autoRefreshOptions.enabled) { + reFetchEndpointActionList(); + } + }, [dateRangePickerState.autoRefreshOptions.enabled, reFetchEndpointActionList]); + + // handle on change actions filter + const onChangeCommandsFilter = useCallback( + (selectedCommands: string[]) => { + setQueryParams((prevState) => ({ ...prevState, commands: selectedCommands })); + }, + [setQueryParams] + ); + + // total actions + const totalItemCount = useMemo(() => actionList?.total ?? 0, [actionList]); + + // expanded tray contents + const toggleDetails = useCallback( + (item: ActionDetails) => { + const itemIdToExpandedRowMapValues = { ...itemIdToExpandedRowMap }; + if (itemIdToExpandedRowMapValues[item.id]) { + delete itemIdToExpandedRowMapValues[item.id]; + } else { + const { + startedAt, + completedAt, + isCompleted, + wasSuccessful, + isExpired, + command: _command, + parameters, + } = item; + + const parametersList = parameters + ? Object.entries(parameters).map(([key, value]) => { + return `${key}:${value}`; + }) + : undefined; + + const command = getCommand(_command); + const dataList = [ + { + title: OUTPUT_MESSAGES.expandSection.placedAt, + description: `${startedAt}`, + }, + { + title: OUTPUT_MESSAGES.expandSection.startedAt, + description: `${startedAt}`, + }, + { + title: OUTPUT_MESSAGES.expandSection.completedAt, + description: `${completedAt ?? emptyValue}`, + }, + { + title: OUTPUT_MESSAGES.expandSection.input, + description: `${command}`, + }, + { + title: OUTPUT_MESSAGES.expandSection.parameters, + description: parametersList ? parametersList : emptyValue, + }, + ].map(({ title, description }) => { + return { + title: {title}, + description: {description}, + }; + }); + + const outputList = [ + { + title: ( + {`${OUTPUT_MESSAGES.expandSection.output}:`} + ), + description: ( + // codeblock for output + + {isExpired + ? OUTPUT_MESSAGES.hasExpired(command) + : isCompleted + ? wasSuccessful + ? OUTPUT_MESSAGES.wasSuccessful(command) + : OUTPUT_MESSAGES.hasFailed(command) + : OUTPUT_MESSAGES.isPending(command)} + + ), + }, + ]; + + itemIdToExpandedRowMapValues[item.id] = ( + <> + + + + + + + + + + ); + } + setItemIdToExpandedRowMap(itemIdToExpandedRowMapValues); + }, + [getTestId, itemIdToExpandedRowMap] + ); + // memoized callback for toggleDetails + const onClickCallback = useCallback( + (data: ActionDetails) => () => toggleDetails(data), + [toggleDetails] + ); + + // table column + const responseActionListColumns = useMemo(() => { + const hideHostColumn = typeof agentIds === 'string'; + + const columns = [ + { + field: 'startedAt', + name: TABLE_COLUMN_NAMES.time, + width: hideHostColumn ? '21%' : '15%', + truncateText: true, + render: (startedAt: ActionDetails['startedAt']) => { + return ( + + ); + }, + }, + { + field: 'command', + name: TABLE_COLUMN_NAMES.command, + width: hideHostColumn ? '21%' : '10%', + truncateText: true, + render: (_command: ActionDetails['command']) => { + const command = getCommand(_command); + return ( + + + + ); + }, + }, + { + field: 'createdBy', + name: TABLE_COLUMN_NAMES.user, + width: hideHostColumn ? '21%' : '14%', + truncateText: true, + render: (userId: ActionDetails['createdBy']) => { + return ( + + } + > + + + {userId} + + + + ); + }, + }, + // conditional hostname column + { + field: 'agents', + name: TABLE_COLUMN_NAMES.host, + width: '20%', + truncateText: true, + render: (agents: ActionDetails['agents']) => { + // TODO: compute host names later with hostMetadata? (using agent Ids for now) + const hostname = agents?.[0] ?? ''; + return ( + + + {hostname} + + + ); + }, + }, + { + field: 'comment', + name: TABLE_COLUMN_NAMES.comments, + width: hideHostColumn ? '21%' : '30%', + truncateText: true, + render: (comment: ActionDetails['comment']) => { + return ( + + + {comment ?? emptyValue} + + + ); + }, + }, + { + field: 'isCompleted', + name: TABLE_COLUMN_NAMES.status, + width: hideHostColumn ? '15%' : '10%', + render: (isCompleted: ActionDetails['isCompleted'], data: ActionDetails) => { + const status = data.isExpired + ? UX_MESSAGES.badge.failed + : isCompleted + ? data.wasSuccessful + ? UX_MESSAGES.badge.completed + : UX_MESSAGES.badge.failed + : UX_MESSAGES.badge.pending; + + return ( + + + + + + ); + }, + }, + { + field: '', + align: RIGHT_ALIGNMENT as HorizontalAlignment, + width: '40px', + isExpander: true, + name: ( + + {UX_MESSAGES.screenReaderExpand} + + ), + render: (data: ActionDetails) => { + return ( + + ); + }, + }, + ]; + // filter out the host column + if (hideHostColumn) { + return columns.filter((column) => column.field !== 'agents'); + } + return columns; + }, [agentIds, getTestId, itemIdToExpandedRowMap, onClickCallback]); + + // table pagination + const tablePagination = useMemo(() => { + return { + // this controls the table UI page + // to match 0-based table paging + pageIndex: (queryParams.page || 1) - 1, + pageSize: queryParams.pageSize || 10, + totalItemCount, + pageSizeOptions: MANAGEMENT_PAGE_SIZE_OPTIONS as number[], + }; + }, [queryParams, totalItemCount]); + + // handle onChange + const handleTableOnChange = useCallback( + ({ page: _page }: CriteriaWithPagination) => { + // table paging is 0 based + const { index, size } = _page; + setQueryParams((prevState) => ({ + ...prevState, + // adjust the page to conform to + // 1-based API page + page: index + 1, + pageSize: size, + })); + reFetchEndpointActionList(); + }, + [reFetchEndpointActionList, setQueryParams] + ); + + // compute record ranges + const pagedResultsCount = useMemo(() => { + const page = queryParams.page ?? 1; + const perPage = queryParams?.pageSize ?? 10; + + const totalPages = Math.ceil(totalItemCount / perPage); + const fromCount = perPage * page - perPage + 1; + const toCount = + page === totalPages || totalPages === 1 ? totalItemCount : fromCount + perPage - 1; + return { fromCount, toCount }; + }, [queryParams.page, queryParams.pageSize, totalItemCount]); + + // create range label to display + const recordRangeLabel = useMemo( + () => ( + + + + {'-'} + + + ), + total: , + recordsLabel: {UX_MESSAGES.recordsLabel(totalItemCount)}, + }} + /> + + ), + [getTestId, pagedResultsCount.fromCount, pagedResultsCount.toCount, totalItemCount] + ); + + return ( + <> + + {isFetched && !totalItemCount ? ( + + + + + + } + body={ +

+ +

+ } + data-test-subj="responseActions-empty" + /> +
+
+ ) : ( + <> + {recordRangeLabel} + + + + )} + + ); + } +); + +ResponseActionsLog.displayName = 'ResponseActionsLog'; diff --git a/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/translations.tsx b/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/translations.tsx index 04255a9ceaf533..fe3d368e8aec73 100644 --- a/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/translations.tsx +++ b/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/translations.tsx @@ -101,6 +101,17 @@ export const UX_MESSAGES = Object.freeze({ fetchError: i18n.translate('xpack.securitySolution.responseActionsList.list.errorMessage', { defaultMessage: 'Error while retrieving response actions', }), + filterClearAll: i18n.translate( + 'xpack.securitySolution.responseActionsList.list.filter.clearAll', + { + defaultMessage: 'Clear all', + } + ), + filterSearchPlaceholder: (filterName: string) => + i18n.translate('xpack.securitySolution.responseActionsList.list.filter.searchPlaceholder', { + defaultMessage: 'Search {filterName}', + values: { filterName }, + }), badge: { completed: i18n.translate( 'xpack.securitySolution.responseActionsList.list.item.badge.completed', @@ -129,3 +140,10 @@ export const UX_MESSAGES = Object.freeze({ }, }), }); + +// TODO: Add more filter names here (hosts, statuses) etc +export const FILTER_NAMES = Object.freeze({ + actions: i18n.translate('xpack.securitySolution.responseActionsList.list.filter.actions', { + defaultMessage: 'Actions', + }), +}); diff --git a/x-pack/plugins/security_solution/public/management/components/policy_response/policy_response_wrapper.test.tsx b/x-pack/plugins/security_solution/public/management/components/policy_response/policy_response_wrapper.test.tsx index 7bc3e5ac0be6db..3c6d4f66d59cbc 100644 --- a/x-pack/plugins/security_solution/public/management/components/policy_response/policy_response_wrapper.test.tsx +++ b/x-pack/plugins/security_solution/public/management/components/policy_response/policy_response_wrapper.test.tsx @@ -25,18 +25,12 @@ import { policyResponseTitles, } from './policy_response_friendly_names'; +jest.setTimeout(10000); + jest.mock('../../hooks/endpoint/use_get_endpoint_policy_response'); jest.mock('../../hooks/endpoint/use_get_endpoint_details'); -// FLAKY: https://github.com/elastic/kibana/issues/136272 -// FLAKY: https://github.com/elastic/kibana/issues/139033 -// FLAKY: https://github.com/elastic/kibana/issues/139032 -// FLAKY: https://github.com/elastic/kibana/issues/139031 -// FLAKY: https://github.com/elastic/kibana/issues/139030 -// FLAKY: https://github.com/elastic/kibana/issues/139028 -// FLAKY: https://github.com/elastic/kibana/issues/139029 -// FLAKY: https://github.com/elastic/kibana/issues/139027 -describe.skip('when on the policy response', () => { +describe('when on the policy response', () => { const docGenerator = new EndpointDocGenerator(); const createPolicyResponse = ( overallStatus: HostPolicyResponseActionStatus = HostPolicyResponseActionStatus.success, diff --git a/x-pack/plugins/security_solution/public/management/hooks/artifacts/use_bulk_delete_artifact.tsx b/x-pack/plugins/security_solution/public/management/hooks/artifacts/use_bulk_delete_artifact.tsx index e75402ae984271..aef46affd4252f 100644 --- a/x-pack/plugins/security_solution/public/management/hooks/artifacts/use_bulk_delete_artifact.tsx +++ b/x-pack/plugins/security_solution/public/management/hooks/artifacts/use_bulk_delete_artifact.tsx @@ -7,8 +7,8 @@ import pMap from 'p-map'; import type { IHttpFetchError } from '@kbn/core-http-browser'; import type { ExceptionListItemSchema } from '@kbn/securitysolution-io-ts-list-types'; -import type { UseMutationOptions, UseMutationResult } from 'react-query'; -import { useMutation } from 'react-query'; +import type { UseMutationOptions, UseMutationResult } from '@tanstack/react-query'; +import { useMutation } from '@tanstack/react-query'; import type { ExceptionsListApiClient } from '../../services/exceptions_list/exceptions_list_api_client'; const DEFAULT_OPTIONS = Object.freeze({}); diff --git a/x-pack/plugins/security_solution/public/management/hooks/artifacts/use_bulk_update_artifact.tsx b/x-pack/plugins/security_solution/public/management/hooks/artifacts/use_bulk_update_artifact.tsx index fdbe6a451dc449..be99fb5f1abb81 100644 --- a/x-pack/plugins/security_solution/public/management/hooks/artifacts/use_bulk_update_artifact.tsx +++ b/x-pack/plugins/security_solution/public/management/hooks/artifacts/use_bulk_update_artifact.tsx @@ -10,8 +10,8 @@ import type { UpdateExceptionListItemSchema, ExceptionListItemSchema, } from '@kbn/securitysolution-io-ts-list-types'; -import type { UseMutationOptions, UseMutationResult } from 'react-query'; -import { useMutation } from 'react-query'; +import type { UseMutationOptions, UseMutationResult } from '@tanstack/react-query'; +import { useMutation } from '@tanstack/react-query'; import type { ExceptionsListApiClient } from '../../services/exceptions_list/exceptions_list_api_client'; const DEFAULT_OPTIONS = Object.freeze({}); diff --git a/x-pack/plugins/security_solution/public/management/hooks/artifacts/use_create_artifact.tsx b/x-pack/plugins/security_solution/public/management/hooks/artifacts/use_create_artifact.tsx index fa807e2d93438a..63a41492b26997 100644 --- a/x-pack/plugins/security_solution/public/management/hooks/artifacts/use_create_artifact.tsx +++ b/x-pack/plugins/security_solution/public/management/hooks/artifacts/use_create_artifact.tsx @@ -9,8 +9,8 @@ import type { ExceptionListItemSchema, } from '@kbn/securitysolution-io-ts-list-types'; import type { IHttpFetchError } from '@kbn/core-http-browser'; -import type { UseMutationOptions, UseMutationResult } from 'react-query'; -import { useMutation } from 'react-query'; +import type { UseMutationOptions, UseMutationResult } from '@tanstack/react-query'; +import { useMutation } from '@tanstack/react-query'; import type { ExceptionsListApiClient } from '../../services/exceptions_list/exceptions_list_api_client'; const DEFAULT_OPTIONS = Object.freeze({}); diff --git a/x-pack/plugins/security_solution/public/management/hooks/artifacts/use_delete_artifact.tsx b/x-pack/plugins/security_solution/public/management/hooks/artifacts/use_delete_artifact.tsx index de3b4c386bc3f0..9b366d033caf56 100644 --- a/x-pack/plugins/security_solution/public/management/hooks/artifacts/use_delete_artifact.tsx +++ b/x-pack/plugins/security_solution/public/management/hooks/artifacts/use_delete_artifact.tsx @@ -6,8 +6,8 @@ */ import type { ExceptionListItemSchema } from '@kbn/securitysolution-io-ts-list-types'; import type { IHttpFetchError } from '@kbn/core-http-browser'; -import type { UseMutationOptions, UseMutationResult } from 'react-query'; -import { useMutation } from 'react-query'; +import type { UseMutationOptions, UseMutationResult } from '@tanstack/react-query'; +import { useMutation } from '@tanstack/react-query'; import type { ExceptionsListApiClient } from '../../services/exceptions_list/exceptions_list_api_client'; const DEFAULT_OPTIONS = Object.freeze({}); diff --git a/x-pack/plugins/security_solution/public/management/hooks/artifacts/use_get_artifact.tsx b/x-pack/plugins/security_solution/public/management/hooks/artifacts/use_get_artifact.tsx index 7ce83d84c93941..58b0cd1c16e737 100644 --- a/x-pack/plugins/security_solution/public/management/hooks/artifacts/use_get_artifact.tsx +++ b/x-pack/plugins/security_solution/public/management/hooks/artifacts/use_get_artifact.tsx @@ -6,8 +6,8 @@ */ import type { ExceptionListItemSchema } from '@kbn/securitysolution-io-ts-list-types'; import type { IHttpFetchError } from '@kbn/core-http-browser'; -import type { QueryObserverResult, UseQueryOptions } from 'react-query'; -import { useQuery } from 'react-query'; +import type { QueryObserverResult, UseQueryOptions } from '@tanstack/react-query'; +import { useQuery } from '@tanstack/react-query'; import type { ExceptionsListApiClient } from '../../services/exceptions_list/exceptions_list_api_client'; export function useGetArtifact( diff --git a/x-pack/plugins/security_solution/public/management/hooks/artifacts/use_list_artifact.tsx b/x-pack/plugins/security_solution/public/management/hooks/artifacts/use_list_artifact.tsx index 4064c9bdeb82e1..0c751cd6525cb6 100644 --- a/x-pack/plugins/security_solution/public/management/hooks/artifacts/use_list_artifact.tsx +++ b/x-pack/plugins/security_solution/public/management/hooks/artifacts/use_list_artifact.tsx @@ -6,8 +6,8 @@ */ import type { FoundExceptionListItemSchema } from '@kbn/securitysolution-io-ts-list-types'; import type { IHttpFetchError } from '@kbn/core-http-browser'; -import type { QueryObserverResult, UseQueryOptions } from 'react-query'; -import { useQuery } from 'react-query'; +import type { QueryObserverResult, UseQueryOptions } from '@tanstack/react-query'; +import { useQuery } from '@tanstack/react-query'; import { useMemo } from 'react'; import { MANAGEMENT_DEFAULT_PAGE, diff --git a/x-pack/plugins/security_solution/public/management/hooks/artifacts/use_summary_artifact.tsx b/x-pack/plugins/security_solution/public/management/hooks/artifacts/use_summary_artifact.tsx index 36fc65a309fa6a..da4dcf765a8c96 100644 --- a/x-pack/plugins/security_solution/public/management/hooks/artifacts/use_summary_artifact.tsx +++ b/x-pack/plugins/security_solution/public/management/hooks/artifacts/use_summary_artifact.tsx @@ -6,8 +6,8 @@ */ import type { ExceptionListSummarySchema } from '@kbn/securitysolution-io-ts-list-types'; import type { IHttpFetchError } from '@kbn/core-http-browser'; -import type { QueryObserverResult, UseQueryOptions } from 'react-query'; -import { useQuery } from 'react-query'; +import type { QueryObserverResult, UseQueryOptions } from '@tanstack/react-query'; +import { useQuery } from '@tanstack/react-query'; import { parsePoliciesAndFilterToKql, parseQueryFilterToKQL } from '../../common/utils'; import type { ExceptionsListApiClient } from '../../services/exceptions_list/exceptions_list_api_client'; import { DEFAULT_EXCEPTION_LIST_ITEM_SEARCHABLE_FIELDS } from '../../../../common/endpoint/service/artifacts/constants'; diff --git a/x-pack/plugins/security_solution/public/management/hooks/artifacts/use_update_artifact.tsx b/x-pack/plugins/security_solution/public/management/hooks/artifacts/use_update_artifact.tsx index 910f2228040a00..ad0791f94f6872 100644 --- a/x-pack/plugins/security_solution/public/management/hooks/artifacts/use_update_artifact.tsx +++ b/x-pack/plugins/security_solution/public/management/hooks/artifacts/use_update_artifact.tsx @@ -9,8 +9,8 @@ import type { ExceptionListItemSchema, } from '@kbn/securitysolution-io-ts-list-types'; import type { IHttpFetchError } from '@kbn/core-http-browser'; -import type { UseMutationOptions, UseMutationResult } from 'react-query'; -import { useMutation } from 'react-query'; +import type { UseMutationOptions, UseMutationResult } from '@tanstack/react-query'; +import { useMutation } from '@tanstack/react-query'; import type { ExceptionsListApiClient } from '../../services/exceptions_list/exceptions_list_api_client'; const DEFAULT_OPTIONS = Object.freeze({}); diff --git a/x-pack/plugins/security_solution/public/management/hooks/endpoint/use_get_action_details.test.ts b/x-pack/plugins/security_solution/public/management/hooks/endpoint/use_get_action_details.test.ts index b04e0428037cf5..381bd906f58f56 100644 --- a/x-pack/plugins/security_solution/public/management/hooks/endpoint/use_get_action_details.test.ts +++ b/x-pack/plugins/security_solution/public/management/hooks/endpoint/use_get_action_details.test.ts @@ -11,12 +11,12 @@ import { useGetActionDetails } from './use_get_action_details'; import { responseActionsHttpMocks } from '../../mocks/response_actions_http_mocks'; import { resolvePathVariables } from '../../../common/utils/resolve_path_variables'; import { ACTION_DETAILS_ROUTE } from '../../../../common/endpoint/constants'; -import { useQuery as _useQuery } from 'react-query'; +import { useQuery as _useQuery } from '@tanstack/react-query'; const useQueryMock = _useQuery as jest.Mock; -jest.mock('react-query', () => { - const actualReactQueryModule = jest.requireActual('react-query'); +jest.mock('@tanstack/react-query', () => { + const actualReactQueryModule = jest.requireActual('@tanstack/react-query'); return { ...actualReactQueryModule, diff --git a/x-pack/plugins/security_solution/public/management/hooks/endpoint/use_get_action_details.ts b/x-pack/plugins/security_solution/public/management/hooks/endpoint/use_get_action_details.ts index 5bc85d80071764..8336c46e2b232d 100644 --- a/x-pack/plugins/security_solution/public/management/hooks/endpoint/use_get_action_details.ts +++ b/x-pack/plugins/security_solution/public/management/hooks/endpoint/use_get_action_details.ts @@ -5,9 +5,9 @@ * 2.0. */ -import type { UseQueryOptions, UseQueryResult } from 'react-query'; +import type { UseQueryOptions, UseQueryResult } from '@tanstack/react-query'; import type { IHttpFetchError } from '@kbn/core-http-browser'; -import { useQuery } from 'react-query'; +import { useQuery } from '@tanstack/react-query'; import { useHttp } from '../../../common/lib/kibana'; import { resolvePathVariables } from '../../../common/utils/resolve_path_variables'; import { ACTION_DETAILS_ROUTE } from '../../../../common/endpoint/constants'; diff --git a/x-pack/plugins/security_solution/public/management/hooks/endpoint/use_get_endpoint_action_list.test.ts b/x-pack/plugins/security_solution/public/management/hooks/endpoint/use_get_endpoint_action_list.test.ts index 8ff8a6f43d11e9..d039890256a3de 100644 --- a/x-pack/plugins/security_solution/public/management/hooks/endpoint/use_get_endpoint_action_list.test.ts +++ b/x-pack/plugins/security_solution/public/management/hooks/endpoint/use_get_endpoint_action_list.test.ts @@ -9,13 +9,13 @@ import type { AppContextTestRender, ReactQueryHookRenderer } from '../../../comm import { createAppRootMockRenderer } from '../../../common/mock/endpoint'; import { useGetEndpointActionList } from './use_get_endpoint_action_list'; import { ENDPOINTS_ACTION_LIST_ROUTE } from '../../../../common/endpoint/constants'; -import { useQuery as _useQuery } from 'react-query'; +import { useQuery as _useQuery } from '@tanstack/react-query'; import { responseActionsHttpMocks } from '../../mocks/response_actions_http_mocks'; const useQueryMock = _useQuery as jest.Mock; -jest.mock('react-query', () => { - const actualReactQueryModule = jest.requireActual('react-query'); +jest.mock('@tanstack/react-query', () => { + const actualReactQueryModule = jest.requireActual('@tanstack/react-query'); return { ...actualReactQueryModule, diff --git a/x-pack/plugins/security_solution/public/management/hooks/endpoint/use_get_endpoint_action_list.ts b/x-pack/plugins/security_solution/public/management/hooks/endpoint/use_get_endpoint_action_list.ts index e0a1e1c1a24855..58420993cb7883 100644 --- a/x-pack/plugins/security_solution/public/management/hooks/endpoint/use_get_endpoint_action_list.ts +++ b/x-pack/plugins/security_solution/public/management/hooks/endpoint/use_get_endpoint_action_list.ts @@ -5,9 +5,9 @@ * 2.0. */ -import type { UseQueryOptions, UseQueryResult } from 'react-query'; +import type { UseQueryOptions, UseQueryResult } from '@tanstack/react-query'; import type { IHttpFetchError } from '@kbn/core-http-browser'; -import { useQuery } from 'react-query'; +import { useQuery } from '@tanstack/react-query'; import type { EndpointActionListRequestQuery } from '../../../../common/endpoint/schema/actions'; import { useHttp } from '../../../common/lib/kibana'; import { ENDPOINTS_ACTION_LIST_ROUTE } from '../../../../common/endpoint/constants'; diff --git a/x-pack/plugins/security_solution/public/management/hooks/endpoint/use_get_endpoint_details.test.ts b/x-pack/plugins/security_solution/public/management/hooks/endpoint/use_get_endpoint_details.test.ts index b9771f7dee3dd8..ce8b08014686e9 100644 --- a/x-pack/plugins/security_solution/public/management/hooks/endpoint/use_get_endpoint_details.test.ts +++ b/x-pack/plugins/security_solution/public/management/hooks/endpoint/use_get_endpoint_details.test.ts @@ -10,13 +10,13 @@ import { createAppRootMockRenderer } from '../../../common/mock/endpoint'; import { useGetEndpointDetails } from './use_get_endpoint_details'; import { resolvePathVariables } from '../../../common/utils/resolve_path_variables'; import { HOST_METADATA_GET_ROUTE } from '../../../../common/endpoint/constants'; -import { useQuery as _useQuery } from 'react-query'; +import { useQuery as _useQuery } from '@tanstack/react-query'; import { endpointMetadataHttpMocks } from '../../pages/endpoint_hosts/mocks'; const useQueryMock = _useQuery as jest.Mock; -jest.mock('react-query', () => { - const actualReactQueryModule = jest.requireActual('react-query'); +jest.mock('@tanstack/react-query', () => { + const actualReactQueryModule = jest.requireActual('@tanstack/react-query'); return { ...actualReactQueryModule, diff --git a/x-pack/plugins/security_solution/public/management/hooks/endpoint/use_get_endpoint_details.ts b/x-pack/plugins/security_solution/public/management/hooks/endpoint/use_get_endpoint_details.ts index e81e8b716ea9cd..68d53372e9dd3f 100644 --- a/x-pack/plugins/security_solution/public/management/hooks/endpoint/use_get_endpoint_details.ts +++ b/x-pack/plugins/security_solution/public/management/hooks/endpoint/use_get_endpoint_details.ts @@ -5,8 +5,8 @@ * 2.0. */ -import type { UseQueryOptions, UseQueryResult } from 'react-query'; -import { useQuery } from 'react-query'; +import type { UseQueryOptions, UseQueryResult } from '@tanstack/react-query'; +import { useQuery } from '@tanstack/react-query'; import type { IHttpFetchError } from '@kbn/core-http-browser'; import { resolvePathVariables } from '../../../common/utils/resolve_path_variables'; import { useHttp } from '../../../common/lib/kibana'; diff --git a/x-pack/plugins/security_solution/public/management/hooks/endpoint/use_get_endpoint_pending_actions_summary.test.ts b/x-pack/plugins/security_solution/public/management/hooks/endpoint/use_get_endpoint_pending_actions_summary.test.ts index b36cf686d67f58..6bc17c87946165 100644 --- a/x-pack/plugins/security_solution/public/management/hooks/endpoint/use_get_endpoint_pending_actions_summary.test.ts +++ b/x-pack/plugins/security_solution/public/management/hooks/endpoint/use_get_endpoint_pending_actions_summary.test.ts @@ -9,13 +9,13 @@ import type { AppContextTestRender, ReactQueryHookRenderer } from '../../../comm import { createAppRootMockRenderer } from '../../../common/mock/endpoint'; import { useGetEndpointPendingActionsSummary } from './use_get_endpoint_pending_actions_summary'; import { ACTION_STATUS_ROUTE } from '../../../../common/endpoint/constants'; -import { useQuery as _useQuery } from 'react-query'; +import { useQuery as _useQuery } from '@tanstack/react-query'; import { responseActionsHttpMocks } from '../../mocks/response_actions_http_mocks'; const useQueryMock = _useQuery as jest.Mock; -jest.mock('react-query', () => { - const actualReactQueryModule = jest.requireActual('react-query'); +jest.mock('@tanstack/react-query', () => { + const actualReactQueryModule = jest.requireActual('@tanstack/react-query'); return { ...actualReactQueryModule, diff --git a/x-pack/plugins/security_solution/public/management/hooks/endpoint/use_get_endpoint_pending_actions_summary.ts b/x-pack/plugins/security_solution/public/management/hooks/endpoint/use_get_endpoint_pending_actions_summary.ts index 3254e743da44af..cee29041b0354a 100644 --- a/x-pack/plugins/security_solution/public/management/hooks/endpoint/use_get_endpoint_pending_actions_summary.ts +++ b/x-pack/plugins/security_solution/public/management/hooks/endpoint/use_get_endpoint_pending_actions_summary.ts @@ -5,8 +5,8 @@ * 2.0. */ -import type { QueryObserverResult, UseQueryOptions } from 'react-query'; -import { useQuery } from 'react-query'; +import type { QueryObserverResult, UseQueryOptions } from '@tanstack/react-query'; +import { useQuery } from '@tanstack/react-query'; import type { IHttpFetchError } from '@kbn/core-http-browser'; import type { PendingActionsResponse } from '../../../../common/endpoint/types'; import { fetchPendingActionsByAgentId } from '../../../common/lib/endpoint_pending_actions'; diff --git a/x-pack/plugins/security_solution/public/management/hooks/endpoint/use_get_endpoint_policy_response.tsx b/x-pack/plugins/security_solution/public/management/hooks/endpoint/use_get_endpoint_policy_response.tsx index 7a67d5a446bac9..a930dd43eecd4a 100644 --- a/x-pack/plugins/security_solution/public/management/hooks/endpoint/use_get_endpoint_policy_response.tsx +++ b/x-pack/plugins/security_solution/public/management/hooks/endpoint/use_get_endpoint_policy_response.tsx @@ -5,8 +5,8 @@ * 2.0. */ import type { IHttpFetchError } from '@kbn/core-http-browser'; -import type { UseQueryResult, UseQueryOptions } from 'react-query'; -import { useQuery } from 'react-query'; +import type { UseQueryResult, UseQueryOptions } from '@tanstack/react-query'; +import { useQuery } from '@tanstack/react-query'; import { useHttp } from '../../../common/lib/kibana'; import { BASE_POLICY_RESPONSE_ROUTE } from '../../../../common/endpoint/constants'; import type { GetHostPolicyResponse } from '../../../../common/endpoint/types'; diff --git a/x-pack/plugins/security_solution/public/management/hooks/endpoint/use_send_get_endpoint_processes_request.ts b/x-pack/plugins/security_solution/public/management/hooks/endpoint/use_send_get_endpoint_processes_request.ts index aa3f2b69c807bd..8fa97e75dc6be9 100644 --- a/x-pack/plugins/security_solution/public/management/hooks/endpoint/use_send_get_endpoint_processes_request.ts +++ b/x-pack/plugins/security_solution/public/management/hooks/endpoint/use_send_get_endpoint_processes_request.ts @@ -5,8 +5,8 @@ * 2.0. */ -import type { UseMutationOptions, UseMutationResult } from 'react-query'; -import { useMutation } from 'react-query'; +import type { UseMutationOptions, UseMutationResult } from '@tanstack/react-query'; +import { useMutation } from '@tanstack/react-query'; import type { IHttpFetchError } from '@kbn/core-http-browser'; import type { ProcessesRequestBody, diff --git a/x-pack/plugins/security_solution/public/management/hooks/endpoint/use_send_isolate_endpoint_request.ts b/x-pack/plugins/security_solution/public/management/hooks/endpoint/use_send_isolate_endpoint_request.ts index d4ca621a1fc16c..b0fb5029ab15d3 100644 --- a/x-pack/plugins/security_solution/public/management/hooks/endpoint/use_send_isolate_endpoint_request.ts +++ b/x-pack/plugins/security_solution/public/management/hooks/endpoint/use_send_isolate_endpoint_request.ts @@ -5,8 +5,8 @@ * 2.0. */ -import type { UseMutationOptions, UseMutationResult } from 'react-query'; -import { useMutation } from 'react-query'; +import type { UseMutationOptions, UseMutationResult } from '@tanstack/react-query'; +import { useMutation } from '@tanstack/react-query'; import type { IHttpFetchError } from '@kbn/core-http-browser'; import { isolateHost } from '../../../common/lib/endpoint_isolation'; import type { diff --git a/x-pack/plugins/security_solution/public/management/hooks/endpoint/use_send_kill_process_endpoint_request.ts b/x-pack/plugins/security_solution/public/management/hooks/endpoint/use_send_kill_process_endpoint_request.ts index a049d35c21f5c4..2d86f15f81d406 100644 --- a/x-pack/plugins/security_solution/public/management/hooks/endpoint/use_send_kill_process_endpoint_request.ts +++ b/x-pack/plugins/security_solution/public/management/hooks/endpoint/use_send_kill_process_endpoint_request.ts @@ -5,8 +5,8 @@ * 2.0. */ -import type { UseMutationOptions, UseMutationResult } from 'react-query'; -import { useMutation } from 'react-query'; +import type { UseMutationOptions, UseMutationResult } from '@tanstack/react-query'; +import { useMutation } from '@tanstack/react-query'; import type { IHttpFetchError } from '@kbn/core-http-browser'; import type { KillOrSuspendProcessRequestBody, diff --git a/x-pack/plugins/security_solution/public/management/hooks/endpoint/use_send_release_endpoint_request.ts b/x-pack/plugins/security_solution/public/management/hooks/endpoint/use_send_release_endpoint_request.ts index aaf6e6ab719446..f6d45393ae8850 100644 --- a/x-pack/plugins/security_solution/public/management/hooks/endpoint/use_send_release_endpoint_request.ts +++ b/x-pack/plugins/security_solution/public/management/hooks/endpoint/use_send_release_endpoint_request.ts @@ -5,8 +5,8 @@ * 2.0. */ -import type { UseMutationOptions, UseMutationResult } from 'react-query'; -import { useMutation } from 'react-query'; +import type { UseMutationOptions, UseMutationResult } from '@tanstack/react-query'; +import { useMutation } from '@tanstack/react-query'; import type { IHttpFetchError } from '@kbn/core-http-browser'; import type { HostIsolationRequestBody, diff --git a/x-pack/plugins/security_solution/public/management/hooks/endpoint/use_send_suspend_process_endpoint_request.ts b/x-pack/plugins/security_solution/public/management/hooks/endpoint/use_send_suspend_process_endpoint_request.ts index 483b0d53e1d6b3..d6c2f56cb627f5 100644 --- a/x-pack/plugins/security_solution/public/management/hooks/endpoint/use_send_suspend_process_endpoint_request.ts +++ b/x-pack/plugins/security_solution/public/management/hooks/endpoint/use_send_suspend_process_endpoint_request.ts @@ -5,8 +5,8 @@ * 2.0. */ -import { useMutation } from 'react-query'; -import type { UseMutationOptions, UseMutationResult } from 'react-query'; +import { useMutation } from '@tanstack/react-query'; +import type { UseMutationOptions, UseMutationResult } from '@tanstack/react-query'; import type { IHttpFetchError } from '@kbn/core-http-browser'; import type { KillOrSuspendProcessRequestBody, diff --git a/x-pack/plugins/security_solution/public/management/mocks/fleet_mocks.ts b/x-pack/plugins/security_solution/public/management/mocks/fleet_mocks.ts index 4370bd9e242150..1e5cc83bb0bcc8 100644 --- a/x-pack/plugins/security_solution/public/management/mocks/fleet_mocks.ts +++ b/x-pack/plugins/security_solution/public/management/mocks/fleet_mocks.ts @@ -10,7 +10,10 @@ import type { CheckPermissionsResponse, GetAgentPoliciesResponse, GetAgentStatusResponse, + GetPackagePoliciesResponse, GetPackagesResponse, + BulkGetPackagePoliciesResponse, + BulkGetAgentPoliciesResponse, } from '@kbn/fleet-plugin/common'; import { AGENT_API_ROUTES, @@ -25,6 +28,7 @@ import { httpHandlerMockFactory } from '../../common/mock/endpoint/http_handler_ import { EndpointDocGenerator } from '../../../common/endpoint/generate_data'; import type { GetPolicyListResponse, GetPolicyResponse } from '../pages/policy/types'; import { FleetAgentPolicyGenerator } from '../../../common/endpoint/data_generators/fleet_agent_policy_generator'; +import { FleetPackagePolicyGenerator } from '../../../common/endpoint/data_generators/fleet_package_policy_generator'; interface KqlArgumentType { type: string; @@ -216,8 +220,141 @@ export const fleetGetAgentPolicyListHttpMock = return { items: requiredPolicyIds.map((packagePolicyId) => { - return agentPolicyGenerator.generate({ - package_policies: [packagePolicyId], + return agentPolicyGenerator.generate({}); + }), + perPage: Math.max(requiredPolicyIds.length, 10), + total: requiredPolicyIds.length, + page: 1, + }; + }, + }, + ]); + +export type FleetBulkGetAgentPolicyListHttpMockInterface = ResponseProvidersInterface<{ + agentPolicy: () => BulkGetAgentPoliciesResponse; +}>; +export const fleetBulkGetAgentPolicyListHttpMock = + httpHandlerMockFactory([ + { + id: 'agentPolicy', + path: AGENT_POLICY_API_ROUTES.BULK_GET_PATTERN, + method: 'post', + handler: ({ body }) => { + const generator = new EndpointDocGenerator('seed'); + const agentPolicyGenerator = new FleetAgentPolicyGenerator('seed'); + const endpointMetadata = generator.generateHostMetadata(); + const requiredPolicyIds: string[] = [ + // Make sure that the Agent policy returned from the API has the Integration Policy ID that + // the first endpoint metadata generated is using. This is needed especially when testing the + // Endpoint Details flyout where certain actions might be disabled if we know the endpoint integration policy no + // longer exists. + endpointMetadata.Endpoint.policy.applied.id, + + // In addition, some of our UI logic looks for the existence of certain Endpoint Integration policies + // using the Agents Policy API (normally when checking IDs since query by ids is not supported via API) + // so also add the first two package policy IDs that the `fleetGetEndpointPackagePolicyListHttpMock()` + // method above creates (which Trusted Apps HTTP mocks also use) + // FIXME: remove hard-coded IDs below and get them from the new FleetPackagePolicyGenerator (#2262) + 'ddf6570b-9175-4a6d-b288-61a09771c647', + 'b8e616ae-44fc-4be7-846c-ce8fa5c082dd', + ]; + + return { + items: requiredPolicyIds.map((packagePolicyId) => { + return agentPolicyGenerator.generate({}); + }), + }; + }, + }, + ]); + +export type FleetBulkGetPackagePoliciesListHttpMockInterface = ResponseProvidersInterface<{ + packagePolicies: () => BulkGetPackagePoliciesResponse; +}>; +export const fleetBulkGetPackagePoliciesListHttpMock = + httpHandlerMockFactory([ + { + id: 'packagePolicies', + path: PACKAGE_POLICY_API_ROUTES.BULK_GET_PATTERN, + method: 'post', + handler: ({ body }) => { + const generator = new EndpointDocGenerator('seed'); + const fleetPackagePolicyGenerator = new FleetPackagePolicyGenerator('seed'); + const endpointMetadata = generator.generateHostMetadata(); + const requiredPolicyIds: string[] = [ + // Make sure that the Agent policy returned from the API has the Integration Policy ID that + // the first endpoint metadata generated is using. This is needed especially when testing the + // Endpoint Details flyout where certain actions might be disabled if we know the endpoint integration policy no + // longer exists. + endpointMetadata.Endpoint.policy.applied.id, + + // In addition, some of our UI logic looks for the existence of certain Endpoint Integration policies + // using the Agents Policy API (normally when checking IDs since query by ids is not supported via API) + // so also add the first two package policy IDs that the `fleetGetEndpointPackagePolicyListHttpMock()` + // method above creates (which Trusted Apps HTTP mocks also use) + // FIXME: remove hard-coded IDs below and get them from the new FleetPackagePolicyGenerator (#2262) + 'ddf6570b-9175-4a6d-b288-61a09771c647', + 'b8e616ae-44fc-4be7-846c-ce8fa5c082dd', + + // And finally, include any kql filters for package policies ids + ...getPackagePoliciesFromKueryString( + `${AGENT_POLICY_SAVED_OBJECT_TYPE}.package_policies: (${( + JSON.parse(body?.toString() ?? '{}')?.ids as string[] + ).join(' or ')} )` + ), + ]; + + return { + items: requiredPolicyIds.map((packagePolicyId) => { + return fleetPackagePolicyGenerator.generate({ + id: packagePolicyId, + }); + }), + }; + }, + }, + ]); + +export type FleetGetPackagePoliciesListHttpMockInterface = ResponseProvidersInterface<{ + packagePolicies: () => GetPackagePoliciesResponse; +}>; +export const fleetGetPackagePoliciesListHttpMock = + httpHandlerMockFactory([ + { + id: 'packagePolicies', + path: PACKAGE_POLICY_API_ROUTES.LIST_PATTERN, + method: 'get', + handler: ({ query }) => { + const generator = new EndpointDocGenerator('seed'); + const fleetPackagePolicyGenerator = new FleetPackagePolicyGenerator('seed'); + const endpointMetadata = generator.generateHostMetadata(); + const requiredPolicyIds: string[] = [ + // Make sure that the Agent policy returned from the API has the Integration Policy ID that + // the first endpoint metadata generated is using. This is needed especially when testing the + // Endpoint Details flyout where certain actions might be disabled if we know the endpoint integration policy no + // longer exists. + endpointMetadata.Endpoint.policy.applied.id, + + // In addition, some of our UI logic looks for the existence of certain Endpoint Integration policies + // using the Agents Policy API (normally when checking IDs since query by ids is not supported via API) + // so also add the first two package policy IDs that the `fleetGetEndpointPackagePolicyListHttpMock()` + // method above creates (which Trusted Apps HTTP mocks also use) + // FIXME: remove hard-coded IDs below and get them from the new FleetPackagePolicyGenerator (#2262) + 'ddf6570b-9175-4a6d-b288-61a09771c647', + 'b8e616ae-44fc-4be7-846c-ce8fa5c082dd', + + // And finally, include any kql filters for package policies ids + ...getPackagePoliciesFromKueryString( + `${AGENT_POLICY_SAVED_OBJECT_TYPE}.package_policies: (${(query?.ids as string[]).join( + ' or ' + )} )` + ), + ]; + + return { + items: requiredPolicyIds.map((packagePolicyId) => { + return fleetPackagePolicyGenerator.generate({ + id: packagePolicyId, }); }), perPage: Math.max(requiredPolicyIds.length, 10), diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/mocks.ts b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/mocks.ts index 4cc923cf8d86bd..7dfd55664acc70 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/mocks.ts +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/mocks.ts @@ -38,6 +38,9 @@ import { fleetGetAgentPolicyListHttpMock, fleetGetCheckPermissionsHttpMock, fleetGetPackageListHttpMock, + fleetBulkGetPackagePoliciesListHttpMock, + fleetBulkGetAgentPolicyListHttpMock, + fleetGetPackagePoliciesListHttpMock, } from '../../mocks'; type EndpointMetadataHttpMocksInterface = ResponseProvidersInterface<{ @@ -133,6 +136,9 @@ export const endpointListFleetApisHttpMock = composeHttpHandlerMocks([ fleetGetPackageListHttpMock, fleetGetAgentPolicyListHttpMock, + fleetBulkGetPackagePoliciesListHttpMock, + fleetBulkGetAgentPolicyListHttpMock, + fleetGetPackagePoliciesListHttpMock, fleetGetCheckPermissionsHttpMock, ]); type EndpointPageHttpMockInterface = EndpointMetadataHttpMocksInterface & diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/middleware.test.ts b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/middleware.test.ts index 70b31f88b2f764..7d1fd0a3d77fee 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/middleware.test.ts +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/middleware.test.ts @@ -50,6 +50,7 @@ import { jest.mock('../../../services/policies/ingest', () => ({ sendGetAgentConfigList: () => Promise.resolve({ items: [] }), sendGetAgentPolicyList: () => Promise.resolve({ items: [] }), + sendBulkGetPackagePolicies: () => Promise.resolve({ items: [] }), sendGetEndpointSecurityPackage: () => Promise.resolve({ version: '1.1.1' }), sendGetFleetAgentsWithEndpoint: () => Promise.resolve({ total: 0 }), })); diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/middleware.ts b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/middleware.ts index 2194e51ec5aaf6..fb0e1949ad7572 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/middleware.ts +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/middleware.ts @@ -9,7 +9,6 @@ import type { DataViewBase, Query } from '@kbn/es-query'; import type { CoreStart, HttpStart } from '@kbn/core/public'; import type { Dispatch } from 'redux'; import semverGte from 'semver/functions/gte'; -import { AGENT_POLICY_SAVED_OBJECT_TYPE } from '@kbn/fleet-plugin/common'; import { BASE_POLICY_RESPONSE_ROUTE, HOST_METADATA_GET_ROUTE, @@ -41,7 +40,7 @@ import { createLoadingResourceState, } from '../../../state'; import { - sendGetAgentPolicyList, + sendBulkGetPackagePolicies, sendGetEndpointSecurityPackage, sendGetFleetAgentsWithEndpoint, } from '../../../services/policies/ingest'; @@ -173,19 +172,12 @@ const getAgentAndPoliciesForEndpointsList = async ( // Package Ids that it uses, thus if a reference exists there, then the package policy (policy) // exists. const policiesFound = ( - await sendGetAgentPolicyList(http, { - query: { - kuery: `${AGENT_POLICY_SAVED_OBJECT_TYPE}.package_policies: (${policyIdsToCheck.join( - ' or ' - )})`, - }, - }) + await sendBulkGetPackagePolicies(http, policyIdsToCheck) ).items.reduce( - (list, agentPolicy) => { - (agentPolicy.package_policies as string[]).forEach((packagePolicy) => { - list.packagePolicy[packagePolicy as string] = true; - list.agentPolicy[packagePolicy as string] = agentPolicy.id; - }); + (list, packagePolicy) => { + list.packagePolicy[packagePolicy.id as string] = true; + list.agentPolicy[packagePolicy.id as string] = packagePolicy.policy_id; + return list; }, { packagePolicy: {}, agentPolicy: {} } diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/mock_endpoint_result_list.ts b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/mock_endpoint_result_list.ts index 03a0fdda897976..5a983574f7545c 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/mock_endpoint_result_list.ts +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/mock_endpoint_result_list.ts @@ -11,6 +11,7 @@ import type { GetAgentPoliciesResponseItem, GetPackagesResponse, GetAgentsResponse, + BulkGetPackagePoliciesResponse, } from '@kbn/fleet-plugin/common/types/rest_spec'; import type { GetHostPolicyResponse, @@ -120,9 +121,6 @@ const endpointListApiPathHandlerMocks = ({ // Do policies referenced in endpoint list exist // just returns 1 single agent policy that includes all of the packagePolicy IDs provided [INGEST_API_AGENT_POLICIES]: (): GetAgentPoliciesResponse => { - (agentPolicy.package_policies as string[]).push( - ...endpointPackagePolicies.map((packagePolicy) => packagePolicy.id) - ); return { items: [agentPolicy], total: 10, @@ -146,6 +144,13 @@ const endpointListApiPathHandlerMocks = ({ }; }, + // List of Policies (package policies) for onboarding + [`${INGEST_API_PACKAGE_POLICIES}/_bulk_get`]: (): BulkGetPackagePoliciesResponse => { + return { + items: endpointPackagePolicies, + }; + }, + // List of Agents using Endpoint [INGEST_API_FLEET_AGENTS]: (): GetAgentsResponse => { return { @@ -209,4 +214,15 @@ export const setEndpointListApiMockImplementation: ( throw new Error(`MOCK: api request does not have a mocked handler: ${path}`); }); + + mockedHttpService.post.mockImplementation(async (...args) => { + const [path] = args; + if (typeof path === 'string') { + if (apiHandlers[path]) { + return apiHandlers[path](); + } + } + + throw new Error(`MOCK: api request does not have a mocked handler: ${path}`); + }); }; diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/endpoint_details.tsx b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/endpoint_details.tsx index a8f343290677e7..3a15b6b3873a55 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/endpoint_details.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/endpoint_details.tsx @@ -7,7 +7,7 @@ import { EuiFlyoutBody, EuiFlyoutFooter, EuiLoadingContent, EuiSpacer } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import React, { memo, useCallback, useEffect, useMemo } from 'react'; -import { ResponseActionsList } from '../../../../components/endpoint_response_actions_list/response_actions_list'; +import { ResponseActionsLog } from '../../../../components/endpoint_response_actions_list/response_actions_log'; import { PolicyResponseWrapper } from '../../../../components/policy_response'; import type { HostMetadata } from '../../../../../../common/endpoint/types'; import { useToasts } from '../../../../../common/lib/kibana'; @@ -82,7 +82,7 @@ export const EndpointDetails = memo(() => { name: 'endpointActivityLog', selected_endpoint: id, }), - content: , + content: , }, ], [ContentLoadingMarkup, hostDetails, policyInfo, hostStatus, queryParams] diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.test.tsx b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.test.tsx index 132b5684fa8c0a..1d47f70227df37 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.test.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.test.tsx @@ -1066,9 +1066,11 @@ describe('when on the endpoint list page', () => { const packagePolicy = docGenerator.generatePolicyPackagePolicy(); packagePolicy.id = hosts[0].metadata.Endpoint.policy.applied.id; + const agentPolicy = generator.generateAgentPolicy(); agentPolicyId = agentPolicy.id; agentId = hosts[0].metadata.elastic.agent.id; + packagePolicy.policy_id = agentPolicyId; setEndpointListApiMockImplementation(coreStart.http, { endpointsResults: hostInfo, diff --git a/x-pack/plugins/security_solution/public/management/pages/event_filters/view/components/form.test.tsx b/x-pack/plugins/security_solution/public/management/pages/event_filters/view/components/form.test.tsx index bc8ce0c6a32168..f4eac8de488058 100644 --- a/x-pack/plugins/security_solution/public/management/pages/event_filters/view/components/form.test.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/event_filters/view/components/form.test.tsx @@ -5,8 +5,7 @@ * 2.0. */ import React from 'react'; -import { act, cleanup } from '@testing-library/react'; -import { fireEvent } from '@testing-library/dom'; +import { act, cleanup, fireEvent } from '@testing-library/react'; import { stubIndexPattern } from '@kbn/data-plugin/common/stubs'; import { useFetchIndex } from '../../../../../common/containers/source'; import { NAME_ERROR } from '../event_filters_list'; @@ -187,9 +186,7 @@ describe('Event filter form', () => { render(); expect(renderResult.queryByText(NAME_ERROR)).toBeNull(); const nameInput = renderResult.getByTestId(`${formPrefix}-name-input`); - act(() => { - fireEvent.blur(nameInput); - }); + fireEvent.blur(nameInput); rerenderWithLatestProps(); expect(renderResult.queryByText(NAME_ERROR)).not.toBeNull(); }); diff --git a/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/view/components/form.test.tsx b/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/view/components/form.test.tsx index 43245b340e47c7..b60cdf6040b1d6 100644 --- a/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/view/components/form.test.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/view/components/form.test.tsx @@ -63,24 +63,12 @@ describe('When on the host isolation exceptions entry form', () => { ).resolves.toHaveLength(10); }); - await act(async () => { - await waitFor(() => { - userEvent.click( - renderResult.getByTestId('hostIsolationExceptionsListPage-pageAddButton') - ); - }); - }); - - await act(async () => { - await waitFor(() => { - expect(renderResult.getByTestId('hostIsolationExceptions-form')).toBeTruthy(); - }); + userEvent.click(renderResult.getByTestId('hostIsolationExceptionsListPage-pageAddButton')); - await waitFor(() => { - expect(fleetApiMock.responseProvider.endpointPackagePolicyList).toHaveBeenCalled(); - }); + await waitFor(() => { + expect(renderResult.getByTestId('hostIsolationExceptions-form')).toBeTruthy(); + expect(fleetApiMock.responseProvider.endpointPackagePolicyList).toHaveBeenCalled(); }); - return renderResult; }; diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/artifacts/delete_modal/policy_artifacts_delete_modal.test.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/artifacts/delete_modal/policy_artifacts_delete_modal.test.tsx index 6bb63fb96c62ab..37f04ff804c1dc 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/artifacts/delete_modal/policy_artifacts_delete_modal.test.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/artifacts/delete_modal/policy_artifacts_delete_modal.test.tsx @@ -20,6 +20,7 @@ import { PolicyArtifactsDeleteModal } from './policy_artifacts_delete_modal'; import { exceptionsListAllHttpMocks } from '../../../../../mocks/exceptions_list_http_mocks'; import { ExceptionsListApiClient } from '../../../../../services/exceptions_list/exceptions_list_api_client'; import { POLICY_ARTIFACT_DELETE_MODAL_LABELS } from './translations'; +import { getDeferred } from '../../../../../components/mocks'; const listType: Array = [ 'endpoint_events', @@ -80,6 +81,8 @@ describe.each(listType)('Policy details %s artifact delete modal', (type) => { }); it('should disable the submit button while deleting ', async () => { + const deferred = getDeferred(); + mockedApi.responseProvider.exceptionUpdate.mockDelay.mockReturnValue(deferred.promise); await render(); const confirmButton = renderResult.getByTestId('confirmModalConfirmButton'); userEvent.click(confirmButton); @@ -87,6 +90,10 @@ describe.each(listType)('Policy details %s artifact delete modal', (type) => { await waitFor(() => { expect(confirmButton).toBeDisabled(); }); + + await act(async () => { + deferred.resolve(); // cleanup + }); }); it('should call the API with the removed policy from the exception tags', async () => { diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/artifacts/delete_modal/policy_artifacts_delete_modal.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/artifacts/delete_modal/policy_artifacts_delete_modal.tsx index beee26506cd9ea..b37fbfe95bd596 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/artifacts/delete_modal/policy_artifacts_delete_modal.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/artifacts/delete_modal/policy_artifacts_delete_modal.tsx @@ -6,7 +6,7 @@ */ import { EuiCallOut, EuiConfirmModal, EuiSpacer, EuiText } from '@elastic/eui'; -import { useQueryClient } from 'react-query'; +import { useQueryClient } from '@tanstack/react-query'; import type { IHttpFetchError } from '@kbn/core-http-browser'; import type { ExceptionListItemSchema } from '@kbn/securitysolution-io-ts-list-types'; import React, { useCallback } from 'react'; diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/artifacts/flyout/policy_artifacts_flyout.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/artifacts/flyout/policy_artifacts_flyout.tsx index c13c351f935ac5..d4adb3b53b23ae 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/artifacts/flyout/policy_artifacts_flyout.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/artifacts/flyout/policy_artifacts_flyout.tsx @@ -6,7 +6,7 @@ */ import React, { useCallback, useMemo, useState } from 'react'; -import { useQueryClient } from 'react-query'; +import { useQueryClient } from '@tanstack/react-query'; import { isEmpty, without } from 'lodash/fp'; import type { ExceptionListItemSchema } from '@kbn/securitysolution-io-ts-list-types'; import { diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/artifacts/list/policy_artifacts_list.test.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/artifacts/list/policy_artifacts_list.test.tsx index 2ccfaff3c8b2b6..80e31db13af974 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/artifacts/list/policy_artifacts_list.test.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/artifacts/list/policy_artifacts_list.test.tsx @@ -36,7 +36,8 @@ const getDefaultQueryParameters = (customFilter: string | undefined = '') => ({ }, }); -describe('Policy details artifacts list', () => { +// FLAKY: https://github.com/elastic/kibana/issues/139183 +describe.skip('Policy details artifacts list', () => { let render: (externalPrivileges?: boolean) => Promise>; let renderResult: ReturnType; let history: AppContextTestRender['history']; @@ -67,7 +68,7 @@ describe('Policy details artifacts list', () => { getArtifactPath={getEventFiltersListPath} /> ); - await waitFor(mockedApi.responseProvider.eventFiltersList); + await waitFor(() => expect(mockedApi.responseProvider.eventFiltersList).toHaveBeenCalled()); }); return renderResult; }; @@ -99,7 +100,9 @@ describe('Policy details artifacts list', () => { it('should expand an item when expand is clicked', async () => { await render(); - expect(renderResult.getAllByTestId('artifacts-collapsed-list-card')).toHaveLength(1); + await waitFor(() => { + expect(renderResult.getAllByTestId('artifacts-collapsed-list-card')).toHaveLength(1); + }); userEvent.click( renderResult.getByTestId('artifacts-collapsed-list-card-header-expandCollapse') diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/endpoint_package_custom_extension/components/fleet_integration_artifacts_card.test.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/endpoint_package_custom_extension/components/fleet_integration_artifacts_card.test.tsx index 2e662b393c92f1..2ac194b39bd8e2 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/endpoint_package_custom_extension/components/fleet_integration_artifacts_card.test.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/endpoint_package_custom_extension/components/fleet_integration_artifacts_card.test.tsx @@ -69,9 +69,11 @@ describe('Fleet integration policy endpoint security event filters card', () => ); await render(); - expect(renderResult.getByTestId('artifacts-fleet-integration-card')).toHaveTextContent( - 'Event filters3' - ); + await waitFor(() => { + expect(renderResult.getByTestId('artifacts-fleet-integration-card')).toHaveTextContent( + 'Event filters3' + ); + }); }); it('should show the card even when no event filters associated with the policy', async () => { diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_details.test.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_details.test.tsx index 227e4eb3a78cd6..eab38e3cdd7b58 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_details.test.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_details.test.tsx @@ -23,7 +23,9 @@ import { APP_UI_ID } from '../../../../../common/constants'; import { useIsExperimentalFeatureEnabled } from '../../../../common/hooks/use_experimental_features'; import { exceptionsFindHttpMocks } from '../../../mocks/exceptions_list_http_mocks'; -jest.mock('./policy_forms/components/policy_form_layout'); +jest.mock('./policy_forms/components/policy_form_layout', () => ({ + PolicyFormLayout: () => <>, +})); jest.mock('../../../../common/components/user_privileges'); jest.mock('../../../../common/hooks/use_experimental_features'); diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_list.test.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_list.test.tsx index 122ef57fa4a3e9..5b74d99d6abcdf 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_list.test.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_list.test.tsx @@ -12,7 +12,7 @@ import { createAppRootMockRenderer } from '../../../../common/mock/endpoint'; import { sendGetEndpointSpecificPackagePolicies } from '../../../services/policies/policies'; import { sendGetEndpointSpecificPackagePoliciesMock } from '../../../services/policies/test_mock_utils'; import { PolicyList } from './policy_list'; -import { sendGetAgentPolicyList } from '../../../services/policies/ingest'; +import { sendBulkGetAgentPolicyList } from '../../../services/policies/ingest'; import type { GetPolicyListResponse } from '../types'; import { getEndpointListPath, getPoliciesPath } from '../../../common/routing'; import { APP_UI_ID } from '../../../../../common/constants'; @@ -22,7 +22,7 @@ jest.mock('../../../services/policies/ingest'); const getPackagePolicies = sendGetEndpointSpecificPackagePolicies as jest.Mock; -const getAgentPolicies = sendGetAgentPolicyList as jest.Mock; +const mockedSendBulkGetAgentPolicies = sendBulkGetAgentPolicyList as jest.Mock; describe('When on the policy list page', () => { let render: () => ReturnType; @@ -42,7 +42,7 @@ describe('When on the policy list page', () => { describe('and there are no policies', () => { beforeEach(async () => { - getPackagePolicies.mockImplementation(() => + getPackagePolicies.mockResolvedValue( sendGetEndpointSpecificPackagePoliciesMock({ page: 1, perPage: 20, @@ -60,36 +60,36 @@ describe('When on the policy list page', () => { it('should show the empty page', () => { expect(renderResult.getByTestId('emptyPolicyTable')).toBeTruthy(); }); - it('should show instruction text and a button to add the Endpoint Security integration', () => { + it('should show instruction text and a button to add the Endpoint Security integration', async () => { expect( renderResult.findByText( 'From this page, you’ll be able to view and manage the Endpoint and Cloud Security Integration policies in your environment running Endpoint and Cloud Security.' ) ).toBeTruthy(); - expect(renderResult.getByTestId('onboardingStartButton')).toBeTruthy(); + await waitFor(() => { + expect(renderResult.getByTestId('onboardingStartButton')).toBeTruthy(); + }); }); }); describe('and data exists', () => { - let policies: GetPolicyListResponse; + const policies: GetPolicyListResponse = sendGetEndpointSpecificPackagePoliciesMock(); + beforeEach(async () => { - policies = await sendGetEndpointSpecificPackagePoliciesMock(); - getPackagePolicies.mockImplementation(async () => { - return policies; - }); - getAgentPolicies.mockResolvedValue({ + getPackagePolicies.mockReturnValue(policies); + mockedSendBulkGetAgentPolicies.mockReturnValue({ items: [ - { package_policies: [policies.items[0].id], agents: 4 }, - { package_policies: [policies.items[1].id], agents: 2 }, - { package_policies: [policies.items[2].id], agents: 5 }, - { package_policies: [policies.items[3].id], agents: 1 }, - { package_policies: [policies.items[4].id], agents: 3 }, + { package_policies: [{ id: policies.items[0].id }], agents: 4 }, + { package_policies: [{ id: policies.items[1].id }], agents: 2 }, + { package_policies: [{ id: policies.items[2].id }], agents: 5 }, + { package_policies: [{ id: policies.items[3].id }], agents: 1 }, + { package_policies: [{ id: policies.items[4].id }], agents: 3 }, ], }); render(); await waitFor(() => { expect(sendGetEndpointSpecificPackagePolicies).toHaveBeenCalled(); - expect(sendGetAgentPolicyList).toHaveBeenCalled(); + expect(sendBulkGetAgentPolicyList).toHaveBeenCalled(); }); }); it('should display the policy list table', () => { @@ -118,7 +118,7 @@ describe('When on the policy list page', () => { expect(updatedByCells[0].textContent).toEqual(expectedAvatarName.charAt(0)); expect(firstUpdatedByName.textContent).toEqual(expectedAvatarName); }); - it('should show the correct endpoint count', () => { + it('should show the correct endpoint count', async () => { const endpointCount = renderResult.getAllByTestId('policyEndpointCountLink'); expect(endpointCount[0].textContent).toBe('4'); }); @@ -149,26 +149,31 @@ describe('When on the policy list page', () => { render(); }); }); - describe('pagination', () => { + // FLAKY: https://github.com/elastic/kibana/issues/139207 + describe.skip('pagination', () => { beforeEach(async () => { - getPackagePolicies.mockImplementation(async ({ page, perPage }) => { + getPackagePolicies.mockImplementation(({ page, perPage }) => { // # policies = 100 to trigger UI to show pagination - const response = await sendGetEndpointSpecificPackagePoliciesMock({ + return sendGetEndpointSpecificPackagePoliciesMock({ page, perPage, count: 100, }); - return response; }); render(); await waitFor(() => { expect(getPackagePolicies).toHaveBeenCalled(); + expect(sendGetEndpointSpecificPackagePolicies).toHaveBeenCalled(); + expect(mockedSendBulkGetAgentPolicies).toHaveBeenCalled(); }); }); afterEach(() => { getPackagePolicies.mockReset(); }); it('should pass the correct page value to the api', async () => { + await waitFor(() => { + expect(renderResult.getByTestId('pagination-button-next')).toBeTruthy(); + }); act(() => { renderResult.getByTestId('pagination-button-next').click(); }); @@ -181,6 +186,9 @@ describe('When on the policy list page', () => { }); }); it('should pass the correct pageSize value to the api', async () => { + await waitFor(() => { + expect(renderResult.getByTestId('tablePaginationPopoverButton')).toBeTruthy(); + }); act(() => { renderResult.getByTestId('tablePaginationPopoverButton').click(); }); @@ -203,10 +211,10 @@ describe('When on the policy list page', () => { }); await waitFor(() => { expect(getPackagePolicies).toHaveBeenCalledTimes(2); - }); - expect(getPackagePolicies.mock.calls[1][1].query).toEqual({ - page: 3, - perPage: 50, + expect(getPackagePolicies.mock.calls[1][1].query).toEqual({ + page: 3, + perPage: 50, + }); }); }); it('should reset page back to 1 if the user is on a page > 1 and they change page size', async () => { @@ -215,24 +223,23 @@ describe('When on the policy list page', () => { history.push('/administration/policies?page=2&pageSize=20'); }); await waitFor(() => { - expect(getPackagePolicies).toHaveBeenCalledTimes(2); + expect(getPackagePolicies).toHaveBeenCalled(); }); // change pageSize - act(() => { - renderResult.getByTestId('tablePaginationPopoverButton').click(); + await act(async () => { + (await renderResult.getByTestId('tablePaginationPopoverButton')).click(); }); const pageSize10 = await renderResult.findByTestId('tablePagination-10-rows'); act(() => { pageSize10.click(); }); - await waitFor(() => { - expect(getPackagePolicies).toHaveBeenCalledTimes(3); - }); - expect(getPackagePolicies.mock.calls[2][1].query).toEqual({ - page: 1, - perPage: 10, + expect(sendGetEndpointSpecificPackagePolicies).toHaveBeenLastCalledWith(expect.any(Object), { + query: { + page: 1, + perPage: 10, + }, }); }); it('should set page to 1 if user tries to force an invalid page number', async () => { diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_list.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_list.tsx index 43a7223260f28c..33fd25d0d15cf4 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_list.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_list.tsx @@ -19,7 +19,6 @@ import { import { FormattedMessage } from '@kbn/i18n-react'; import { i18n } from '@kbn/i18n'; import { useLocation } from 'react-router-dom'; -import type { AgentPolicy } from '@kbn/fleet-plugin/common'; import type { CreatePackagePolicyRouteState } from '@kbn/fleet-plugin/public'; import { pagePathGetters } from '@kbn/fleet-plugin/public'; import { AdministrationListPage } from '../../../components/administration_list_page'; @@ -58,10 +57,14 @@ export const PolicyList = memo(() => { // endpoint count per policy const policyIds = useMemo(() => data?.items.map((policies) => policies.id) ?? [], [data]); + const agentPolicyIds = useMemo( + () => data?.items.map((policies) => policies.policy_id) ?? [], + [data] + ); const { data: endpointCount = { items: [] } } = useGetAgentCountForPolicy({ - policyIds, + agentPolicyIds, customQueryOptions: { - enabled: policyIds.length > 0, + enabled: agentPolicyIds.length > 0, onError: (err) => { toasts.addDanger( i18n.translate('xpack.securitySolution.policyList.endpointCountError', { @@ -76,7 +79,7 @@ export const PolicyList = memo(() => { const { data: endpointPackageInfo, isFetching: packageIsFetching } = useGetEndpointSecurityPackage({ customQueryOptions: { - enabled: policyIds.length === 0, + enabled: agentPolicyIds.length === 0, onError: (err) => { toasts.addDanger( i18n.translate('xpack.securitySolution.policyList.packageVersionError', { @@ -88,11 +91,14 @@ export const PolicyList = memo(() => { }); const policyIdToEndpointCount = useMemo(() => { - const map = new Map(); - for (const policy of endpointCount?.items) { - for (const packagePolicyId of policy.package_policies) { - if (policyIds.includes(packagePolicyId as string)) { - map.set(packagePolicyId, policy.agents ?? 0); + const map = new Map(); + + for (const agentPolicy of endpointCount?.items) { + if (agentPolicy.package_policies) { + for (const packagePolicy of agentPolicy.package_policies) { + if (policyIds.includes(packagePolicy.id)) { + map.set(packagePolicy.id, agentPolicy.agents ?? 0); + } } } } diff --git a/x-pack/plugins/security_solution/public/management/pages/response_actions/view/response_actions_list_page.tsx b/x-pack/plugins/security_solution/public/management/pages/response_actions/view/response_actions_list_page.tsx index cb1c7d53e05a68..c72e69023af770 100644 --- a/x-pack/plugins/security_solution/public/management/pages/response_actions/view/response_actions_list_page.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/response_actions/view/response_actions_list_page.tsx @@ -7,13 +7,13 @@ import React from 'react'; import { AdministrationListPage } from '../../../components/administration_list_page'; -import { ResponseActionsList } from '../../../components/endpoint_response_actions_list/response_actions_list'; +import { ResponseActionsLog } from '../../../components/endpoint_response_actions_list/response_actions_log'; import { UX_MESSAGES } from '../../../components/endpoint_response_actions_list/translations'; export const ResponseActionsListPage = () => { return ( - + ); }; diff --git a/x-pack/plugins/security_solution/public/management/services/policies/hooks.test.ts b/x-pack/plugins/security_solution/public/management/services/policies/hooks.test.ts index b591051d72c945..8bd8c4c72efea5 100644 --- a/x-pack/plugins/security_solution/public/management/services/policies/hooks.test.ts +++ b/x-pack/plugins/security_solution/public/management/services/policies/hooks.test.ts @@ -5,7 +5,7 @@ * 2.0. */ -import type { UseQueryOptions } from 'react-query'; +import type { UseQueryOptions } from '@tanstack/react-query'; import type { IHttpFetchError, HttpSetup } from '@kbn/core-http-browser'; import type { GetPackagesResponse } from '@kbn/fleet-plugin/common'; import { useGetEndpointSecurityPackage } from './hooks'; diff --git a/x-pack/plugins/security_solution/public/management/services/policies/hooks.ts b/x-pack/plugins/security_solution/public/management/services/policies/hooks.ts index 6b2c7268758270..3c0810b0d551b7 100644 --- a/x-pack/plugins/security_solution/public/management/services/policies/hooks.ts +++ b/x-pack/plugins/security_solution/public/management/services/policies/hooks.ts @@ -4,14 +4,13 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import type { QueryObserverResult, UseQueryOptions } from 'react-query'; -import { useQuery } from 'react-query'; +import type { QueryObserverResult, UseQueryOptions } from '@tanstack/react-query'; +import { useQuery } from '@tanstack/react-query'; import type { IHttpFetchError } from '@kbn/core-http-browser'; import type { GetAgentPoliciesResponse, GetPackagesResponse } from '@kbn/fleet-plugin/common'; -import { AGENT_POLICY_SAVED_OBJECT_TYPE } from '@kbn/fleet-plugin/common'; import { useHttp } from '../../../common/lib/kibana'; import { MANAGEMENT_DEFAULT_PAGE_SIZE } from '../../common/constants'; -import { sendGetAgentPolicyList, sendGetEndpointSecurityPackage } from './ingest'; +import { sendBulkGetAgentPolicyList, sendGetEndpointSecurityPackage } from './ingest'; import type { GetPolicyListResponse } from '../../pages/policy/types'; import { sendGetEndpointSpecificPackagePolicies } from './policies'; import type { ServerApiError } from '../../../common/types'; @@ -53,22 +52,17 @@ export function useGetEndpointSpecificPolicies( * This hook returns the fleet agent policies list filtered by policy id */ export function useGetAgentCountForPolicy({ - policyIds, + agentPolicyIds, customQueryOptions, }: { - policyIds: string[]; + agentPolicyIds: string[]; customQueryOptions?: UseQueryOptions; }): QueryObserverResult { const http = useHttp(); return useQuery( - ['endpointCountForPolicy', policyIds], + ['endpointCountForPolicy', agentPolicyIds], () => { - return sendGetAgentPolicyList(http, { - query: { - perPage: 50, - kuery: `${AGENT_POLICY_SAVED_OBJECT_TYPE}.package_policies: (${policyIds.join(' or ')})`, - }, - }); + return sendBulkGetAgentPolicyList(http, agentPolicyIds); }, customQueryOptions ); diff --git a/x-pack/plugins/security_solution/public/management/services/policies/ingest.ts b/x-pack/plugins/security_solution/public/management/services/policies/ingest.ts index b77ab8a725ecf6..7690348391ad76 100644 --- a/x-pack/plugins/security_solution/public/management/services/policies/ingest.ts +++ b/x-pack/plugins/security_solution/public/management/services/policies/ingest.ts @@ -12,6 +12,7 @@ import type { GetPackagesResponse, GetAgentPoliciesRequest, GetAgentPoliciesResponse, + GetPackagePoliciesResponse, } from '@kbn/fleet-plugin/common'; import type { NewPolicyData } from '../../../../common/endpoint/types'; import type { GetPolicyResponse, UpdatePolicyResponse } from '../../pages/policy/types'; @@ -37,6 +38,26 @@ export const sendGetPackagePolicy = ( return http.get(`${INGEST_API_PACKAGE_POLICIES}/${packagePolicyId}`, options); }; +/** + * Retrieves multiple package policies by ids + * @param http + * @param packagePolicyIds + * @param options + */ +export const sendBulkGetPackagePolicies = ( + http: HttpStart, + packagePolicyIds: string[], + options?: HttpFetchOptions +) => { + return http.post(`${INGEST_API_PACKAGE_POLICIES}/_bulk_get`, { + ...options, + body: JSON.stringify({ + ids: packagePolicyIds, + ignoreMissing: true, + }), + }); +}; + /** * Retrieve a list of Agent Policies * @param http @@ -49,6 +70,26 @@ export const sendGetAgentPolicyList = ( return http.get(INGEST_API_AGENT_POLICIES, options); }; +/** + * Retrieve a list of Agent Policies + * @param http + * @param options + */ +export const sendBulkGetAgentPolicyList = ( + http: HttpStart, + ids: string[], + options: HttpFetchOptions = {} +) => { + return http.post(`${INGEST_API_AGENT_POLICIES}/_bulk_get`, { + ...options, + body: JSON.stringify({ + ids, + ignoreMissing: true, + full: true, + }), + }); +}; + /** * Updates a package policy * diff --git a/x-pack/plugins/security_solution/public/management/services/policies/test_mock_utils.ts b/x-pack/plugins/security_solution/public/management/services/policies/test_mock_utils.ts index b415fceedc0cde..af7a531d5a3520 100644 --- a/x-pack/plugins/security_solution/public/management/services/policies/test_mock_utils.ts +++ b/x-pack/plugins/security_solution/public/management/services/policies/test_mock_utils.ts @@ -7,13 +7,13 @@ import { FleetPackagePolicyGenerator } from '../../../../common/endpoint/data_generators/fleet_package_policy_generator'; import type { GetPolicyListResponse } from '../../pages/policy/types'; -export const sendGetEndpointSpecificPackagePoliciesMock = async ( +export const sendGetEndpointSpecificPackagePoliciesMock = ( params: { page: number; perPage: number; count: number; } = { page: 1, perPage: 20, count: 5 } -): Promise => { +): GetPolicyListResponse => { const { page, perPage, count } = params; const generator = new FleetPackagePolicyGenerator(); const items = Array.from({ length: count }, (_, index) => { diff --git a/x-pack/plugins/security_solution/public/network/components/embeddables/embedded_map.tsx b/x-pack/plugins/security_solution/public/network/components/embeddables/embedded_map.tsx index a7e2f67e5f5869..53c69b5b47afd0 100644 --- a/x-pack/plugins/security_solution/public/network/components/embeddables/embedded_map.tsx +++ b/x-pack/plugins/security_solution/public/network/components/embeddables/embedded_map.tsx @@ -8,7 +8,7 @@ import { EuiAccordion, EuiLink, EuiText } from '@elastic/eui'; import deepEqual from 'fast-deep-equal'; import React, { useCallback, useEffect, useState, useMemo } from 'react'; -import { createPortalNode, InPortal } from 'react-reverse-portal'; +import { createHtmlPortalNode, InPortal } from 'react-reverse-portal'; import styled, { css } from 'styled-components'; import type { Filter, Query } from '@kbn/es-query'; @@ -127,7 +127,7 @@ export const EmbeddedMapComponent = ({ // own component tree instead of the embeddables (default). This is necessary to have access to // the Redux store, theme provider, etc, which is required to register and un-register the draggable // Search InPortal/OutPortal for implementation touch points - const portalNode = React.useMemo(() => createPortalNode(), []); + const portalNode = React.useMemo(() => createHtmlPortalNode(), []); useEffect(() => { setMapIndexPatterns((prevMapIndexPatterns) => { diff --git a/x-pack/plugins/security_solution/public/network/components/embeddables/embedded_map_helpers.test.tsx b/x-pack/plugins/security_solution/public/network/components/embeddables/embedded_map_helpers.test.tsx index b7e27b24224510..c82051b11769c1 100644 --- a/x-pack/plugins/security_solution/public/network/components/embeddables/embedded_map_helpers.test.tsx +++ b/x-pack/plugins/security_solution/public/network/components/embeddables/embedded_map_helpers.test.tsx @@ -7,7 +7,7 @@ import { embeddablePluginMock } from '@kbn/embeddable-plugin/public/mocks'; import { createEmbeddable, findMatchingIndexPatterns } from './embedded_map_helpers'; -import { createPortalNode } from 'react-reverse-portal'; +import { createHtmlPortalNode } from 'react-reverse-portal'; import { mockAPMIndexPattern, mockAPMRegexIndexPattern, @@ -43,7 +43,7 @@ describe('embedded_map_helpers', () => { '2020-07-07T08:20:18.966Z', '2020-07-08T08:20:18.966Z', setQueryMock, - createPortalNode(), + createHtmlPortalNode(), mockEmbeddable ); expect(setQueryMock).toHaveBeenCalledTimes(1); @@ -58,7 +58,7 @@ describe('embedded_map_helpers', () => { '2020-07-07T08:20:18.966Z', '2020-07-08T08:20:18.966Z', setQueryMock, - createPortalNode(), + createHtmlPortalNode(), mockEmbeddable ); expect(setQueryMock.mock.calls[0][0].refetch).not.toBe(embeddable.reload); diff --git a/x-pack/plugins/security_solution/public/network/components/embeddables/embedded_map_helpers.tsx b/x-pack/plugins/security_solution/public/network/components/embeddables/embedded_map_helpers.tsx index 731adaa9b50815..3583e54f4c980e 100644 --- a/x-pack/plugins/security_solution/public/network/components/embeddables/embedded_map_helpers.tsx +++ b/x-pack/plugins/security_solution/public/network/components/embeddables/embedded_map_helpers.tsx @@ -7,7 +7,7 @@ import uuid from 'uuid'; import React from 'react'; -import type { PortalNode } from 'react-reverse-portal'; +import type { HtmlPortalNode } from 'react-reverse-portal'; import { OutPortal } from 'react-reverse-portal'; import minimatch from 'minimatch'; import type { Filter, Query } from '@kbn/es-query'; @@ -51,7 +51,7 @@ export const createEmbeddable = async ( startDate: GlobalTimeArgs['from'], endDate: GlobalTimeArgs['to'], setQuery: GlobalTimeArgs['setQuery'], - portalNode: PortalNode, + portalNode: HtmlPortalNode, embeddableApi: EmbeddableStart ): Promise => { const factory = embeddableApi.getEmbeddableFactory< diff --git a/x-pack/plugins/security_solution/public/network/containers/network_dns/index.test.tsx b/x-pack/plugins/security_solution/public/network/containers/network_dns/index.test.tsx index 34272cd7cbccfe..aa260236da39d1 100644 --- a/x-pack/plugins/security_solution/public/network/containers/network_dns/index.test.tsx +++ b/x-pack/plugins/security_solution/public/network/containers/network_dns/index.test.tsx @@ -17,7 +17,6 @@ const mockUseSearchStrategy = useSearchStrategy as jest.Mock; const mockSearch = jest.fn(); const props = { - docValueFields: [], endDate: '2020-07-08T08:20:18.966Z', id: ID, indexNames: ['auditbeat-*'], diff --git a/x-pack/plugins/security_solution/public/network/containers/network_dns/index.tsx b/x-pack/plugins/security_solution/public/network/containers/network_dns/index.tsx index 28dc7e657191c8..833efc839b600f 100644 --- a/x-pack/plugins/security_solution/public/network/containers/network_dns/index.tsx +++ b/x-pack/plugins/security_solution/public/network/containers/network_dns/index.tsx @@ -15,7 +15,6 @@ import { createFilter } from '../../../common/containers/helpers'; import { generateTablePaginationOptions } from '../../../common/components/paginated_table/helpers'; import { networkSelectors } from '../../store'; import type { - DocValueFields, NetworkDnsRequestOptions, NetworkDnsEdges, PageInfoPaginated, @@ -41,7 +40,6 @@ export interface NetworkDnsResponse { interface UseNetworkDns { id: string; - docValueFields: DocValueFields[]; indexNames: string[]; filterQuery?: ESTermQuery | string; endDate: string; @@ -50,7 +48,6 @@ interface UseNetworkDns { } export const useNetworkDns = ({ - docValueFields, endDate, filterQuery, id, @@ -119,7 +116,6 @@ export const useNetworkDns = ({ const myRequest = { ...(prevRequest ?? {}), defaultIndex: indexNames, - docValueFields: docValueFields ?? [], isPtrIncluded, factoryQueryType: NetworkQueries.dns, filterQuery: createFilter(filterQuery), @@ -136,17 +132,7 @@ export const useNetworkDns = ({ } return prevRequest; }); - }, [ - activePage, - indexNames, - endDate, - filterQuery, - limit, - startDate, - sort, - isPtrIncluded, - docValueFields, - ]); + }, [activePage, indexNames, endDate, filterQuery, limit, startDate, sort, isPtrIncluded]); useEffect(() => { if (!skip && networkDnsRequest) { diff --git a/x-pack/plugins/security_solution/public/network/pages/navigation/dns_query_tab_body.tsx b/x-pack/plugins/security_solution/public/network/pages/navigation/dns_query_tab_body.tsx index ee423b0343088e..54bdb1acd81b67 100644 --- a/x-pack/plugins/security_solution/public/network/pages/navigation/dns_query_tab_body.tsx +++ b/x-pack/plugins/security_solution/public/network/pages/navigation/dns_query_tab_body.tsx @@ -51,7 +51,6 @@ export const histogramConfigs: Omit = { const DnsQueryTabBodyComponent: React.FC = ({ deleteQuery, - docValueFields, endDate, filterQuery, indexNames, @@ -82,7 +81,6 @@ const DnsQueryTabBodyComponent: React.FC = ({ loading, { totalCount, networkDns, pageInfo, loadPage, id, inspect, isInspected, refetch }, ] = useNetworkDns({ - docValueFields: docValueFields ?? [], endDate, filterQuery, id: queryId, @@ -109,7 +107,6 @@ const DnsQueryTabBodyComponent: React.FC = ({ ( - ({ - docValueFields, - type, - to, - filterQuery, - isInitializing, - from, - indexPattern, - indexNames, - setQuery, - }) => { + ({ type, to, filterQuery, isInitializing, from, indexPattern, indexNames, setQuery }) => { const networkAnomaliesFilterQuery = { bool: { should: [ @@ -83,7 +73,7 @@ export const NetworkRoutes = React.memo( return ( - + <> diff --git a/x-pack/plugins/security_solution/public/network/pages/navigation/types.ts b/x-pack/plugins/security_solution/public/network/pages/navigation/types.ts index e2b96fce68b6e6..941ace5049cdfe 100644 --- a/x-pack/plugins/security_solution/public/network/pages/navigation/types.ts +++ b/x-pack/plugins/security_solution/public/network/pages/navigation/types.ts @@ -15,8 +15,6 @@ import type { FlowTargetSourceDest } from '../../../../common/search_strategy/se import type { networkModel } from '../../store'; import type { GlobalTimeArgs } from '../../../common/containers/use_global_time'; -import type { DocValueFields } from '../../../common/containers/source'; - export interface QueryTabBodyProps extends Pick { endDate: string; filterQuery?: string | ESTermQuery; @@ -27,9 +25,7 @@ export interface QueryTabBodyProps extends Pick( [dispatch] ); - const { docValueFields, indicesExist, indexPattern, selectedPatterns } = useSourcererDataView(); + const { indicesExist, indexPattern, selectedPatterns } = useSourcererDataView(); const onSkipFocusBeforeEventsTable = useCallback(() => { containerElement.current @@ -214,7 +214,6 @@ const NetworkComponent = React.memo( { beforeEach(() => { jest.clearAllMocks(); }); - test('init', async () => { - await act(async () => { - const { result, waitForNextUpdate } = renderHook< - UseCasesByStatusProps, - UseCasesByStatusResults - >(() => useCasesByStatus({ skip: false }), { + test('init', () => { + const { result } = renderHook( + () => useCasesByStatus({}), + { wrapper: TestProviders, - }); - await waitForNextUpdate(); - expect(result.current).toEqual({ - closed: 0, - inProgress: 0, - isLoading: true, - open: 0, - totalCounts: 0, - updatedAt: dateNow, - }); + } + ); + expect(result.current).toEqual({ + closed: 0, + inProgress: 0, + isLoading: true, + open: 0, + totalCounts: 0, + updatedAt: dateNow, }); }); test('fetch data', async () => { - await act(async () => { - const { result, waitForNextUpdate } = renderHook< - UseCasesByStatusProps, - UseCasesByStatusResults - >(() => useCasesByStatus({ skip: false }), { - wrapper: TestProviders, - }); - await waitForNextUpdate(); - await waitForNextUpdate(); - expect(result.current).toEqual({ - closed: 3, - inProgress: 2, - isLoading: false, - open: 1, - totalCounts: 6, - updatedAt: dateNow, - }); + const { result, waitForNextUpdate } = renderHook< + UseCasesByStatusProps, + UseCasesByStatusResults + >(() => useCasesByStatus({ skip: false }), { + wrapper: TestProviders, + }); + await waitForNextUpdate(); + expect(result.current).toEqual({ + closed: 3, + inProgress: 2, + isLoading: false, + open: 1, + totalCounts: 6, + updatedAt: dateNow, }); }); test('it should call setQuery when fetching', async () => { - await act(async () => { - const { waitForNextUpdate } = renderHook( - () => useCasesByStatus({ skip: false }), - { - wrapper: TestProviders, - } - ); - await waitForNextUpdate(); - await waitForNextUpdate(); - expect(mockSetQuery).toHaveBeenCalled(); - }); + const { waitForNextUpdate } = renderHook( + () => useCasesByStatus({ skip: false }), + { + wrapper: TestProviders, + } + ); + await waitForNextUpdate(); + expect(mockSetQuery).toHaveBeenCalled(); }); test('it should call deleteQuery when unmounting', async () => { - await act(async () => { - const { waitForNextUpdate, unmount } = renderHook< - UseCasesByStatusProps, - UseCasesByStatusResults - >(() => useCasesByStatus({ skip: false }), { - wrapper: TestProviders, - }); - await waitForNextUpdate(); + const { waitForNextUpdate, unmount } = renderHook< + UseCasesByStatusProps, + UseCasesByStatusResults + >(() => useCasesByStatus({ skip: false }), { + wrapper: TestProviders, + }); + await waitForNextUpdate(); - unmount(); + unmount(); - expect(mockDeleteQuery).toHaveBeenCalled(); - }); + expect(mockDeleteQuery).toHaveBeenCalled(); }); test('skip', async () => { const abortSpy = jest.spyOn(AbortController.prototype, 'abort'); - await act(async () => { - const localProps = { skip: false }; + const localProps = { skip: false }; - const { rerender, waitForNextUpdate } = renderHook< - UseCasesByStatusProps, - UseCasesByStatusResults - >(() => useCasesByStatus(localProps), { - wrapper: TestProviders, - }); - await waitForNextUpdate(); - await waitForNextUpdate(); - - localProps.skip = true; - act(() => rerender()); - act(() => rerender()); - expect(abortSpy).toHaveBeenCalledTimes(2); + const { rerender, waitForNextUpdate } = renderHook< + UseCasesByStatusProps, + UseCasesByStatusResults + >(() => useCasesByStatus(localProps), { + wrapper: TestProviders, }); + await waitForNextUpdate(); + + localProps.skip = true; + act(() => rerender()); + act(() => rerender()); + expect(abortSpy).toHaveBeenCalledTimes(2); }); }); diff --git a/x-pack/plugins/security_solution/public/overview/components/detection_response/cases_table/use_case_items.test.ts b/x-pack/plugins/security_solution/public/overview/components/detection_response/cases_table/use_case_items.test.ts index 1e9b742f706008..036ed835b46cfc 100644 --- a/x-pack/plugins/security_solution/public/overview/components/detection_response/cases_table/use_case_items.test.ts +++ b/x-pack/plugins/security_solution/public/overview/components/detection_response/cases_table/use_case_items.test.ts @@ -63,17 +63,14 @@ describe('useCaseItems', () => { }); it('should return default values', async () => { - await act(async () => { - const { result, waitForNextUpdate } = renderUseCaseItems(); + const { result, waitForNextUpdate } = renderUseCaseItems(); - await waitForNextUpdate(); - await waitForNextUpdate(); + await waitForNextUpdate(); - expect(result.current).toEqual({ - items: [], - isLoading: false, - updatedAt: dateNow, - }); + expect(result.current).toEqual({ + items: [], + isLoading: false, + updatedAt: dateNow, }); expect(mockCasesApi).toBeCalledWith({ @@ -89,44 +86,36 @@ describe('useCaseItems', () => { it('should return parsed items', async () => { mockCasesApi.mockReturnValue(mockCasesResult); + const { result, waitForNextUpdate } = renderUseCaseItems(); - await act(async () => { - const { result, waitForNextUpdate } = renderUseCaseItems(); + await waitForNextUpdate(); - await waitForNextUpdate(); - await waitForNextUpdate(); - - expect(result.current).toEqual({ - items: parsedCasesItems, - isLoading: false, - updatedAt: dateNow, - }); + expect(result.current).toEqual({ + items: parsedCasesItems, + isLoading: false, + updatedAt: dateNow, }); }); test('it should call setQuery when fetching', async () => { mockCasesApi.mockReturnValue(mockCasesResult); - await act(async () => { - const { waitForNextUpdate } = renderUseCaseItems(); + const { waitForNextUpdate } = renderUseCaseItems(); - await waitForNextUpdate(); - await waitForNextUpdate(); + await waitForNextUpdate(); - expect(mockSetQuery).toHaveBeenCalled(); - }); + expect(mockSetQuery).toHaveBeenCalled(); }); test('it should call deleteQuery when unmounting', async () => { - await act(async () => { - const { waitForNextUpdate, unmount } = renderUseCaseItems(); + const { waitForNextUpdate, unmount } = renderUseCaseItems(); - await waitForNextUpdate(); - await waitForNextUpdate(); + await waitForNextUpdate(); + act(() => { unmount(); - - expect(mockDeleteQuery).toHaveBeenCalled(); }); + + expect(mockDeleteQuery).toHaveBeenCalled(); }); it('should return new updatedAt', async () => { @@ -135,18 +124,15 @@ describe('useCaseItems', () => { mockDateNow.mockReturnValueOnce(dateNow); mockCasesApi.mockReturnValue(mockCasesResult); - await act(async () => { - const { result, waitForNextUpdate } = renderUseCaseItems(); + const { result, waitForNextUpdate } = renderUseCaseItems(); - await waitForNextUpdate(); - await waitForNextUpdate(); + await waitForNextUpdate(); - expect(mockDateNow).toHaveBeenCalled(); - expect(result.current).toEqual({ - items: parsedCasesItems, - isLoading: false, - updatedAt: newDateNow, - }); + expect(mockDateNow).toHaveBeenCalled(); + expect(result.current).toEqual({ + items: parsedCasesItems, + isLoading: false, + updatedAt: newDateNow, }); }); diff --git a/x-pack/plugins/security_solution/public/threat_intelligence/routes.tsx b/x-pack/plugins/security_solution/public/threat_intelligence/routes.tsx index a6189921665eb0..167f2c8d674762 100644 --- a/x-pack/plugins/security_solution/public/threat_intelligence/routes.tsx +++ b/x-pack/plugins/security_solution/public/threat_intelligence/routes.tsx @@ -8,8 +8,9 @@ import React, { memo } from 'react'; import { Redirect } from 'react-router-dom'; import { TrackApplicationView } from '@kbn/usage-collection-plugin/public'; -import type { ThreatIntelligenceSecuritySolutionContext } from '@kbn/threat-intelligence-plugin/public'; +import type { SecuritySolutionPluginContext } from '@kbn/threat-intelligence-plugin/public'; import { THREAT_INTELLIGENCE_BASE_PATH } from '@kbn/threat-intelligence-plugin/public'; +import type { SourcererDataView } from '@kbn/threat-intelligence-plugin/public/types'; import { useKibana } from '../common/lib/kibana'; import { FiltersGlobal } from '../common/components/filters_global'; import { SpyRoute } from '../common/utils/route/spy_routes'; @@ -18,19 +19,23 @@ import { useIsExperimentalFeatureEnabled } from '../common/hooks/use_experimenta import { licenseService } from '../common/hooks/use_license'; import { SecurityPageName } from '../app/types'; import type { SecuritySubPluginRoutes } from '../app/types'; +import { useSourcererDataView } from '../common/containers/sourcerer'; const ThreatIntelligence = memo(() => { const { threatIntelligence } = useKibana().services; const ThreatIntelligencePlugin = threatIntelligence.getComponent(); + const sourcererDataView = useSourcererDataView(); + const enabled = useIsExperimentalFeatureEnabled('threatIntelligenceEnabled'); if (!enabled) { return ; } - const securitySolutionContext: ThreatIntelligenceSecuritySolutionContext = { + const securitySolutionContext: SecuritySolutionPluginContext = { getFiltersGlobalComponent: () => FiltersGlobal, licenseService, + sourcererDataView: sourcererDataView as unknown as SourcererDataView, }; return ( diff --git a/x-pack/plugins/security_solution/public/timelines/components/flyout/add_timeline_button/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/flyout/add_timeline_button/index.tsx index 04bd9d506b63e3..74662e75632017 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/flyout/add_timeline_button/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/flyout/add_timeline_button/index.tsx @@ -57,6 +57,9 @@ const AddTimelineButtonComponent: React.FC = ({ anchorPosition="downRight" button={PopoverButtonIcon} id="timelineSettingsPopover" + panelProps={{ + 'data-test-subj': 'timeline-addPopupPanel', + }} isOpen={showActions} closePopover={onClosePopover} ownFocus diff --git a/x-pack/plugins/security_solution/public/timelines/components/flyout/header/index.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/flyout/header/index.test.tsx index 42306a7d3d2052..79ef41a070574b 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/flyout/header/index.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/flyout/header/index.test.tsx @@ -14,7 +14,7 @@ import { TimelineId } from '../../../../../common/types/timeline'; import { useTimelineKpis } from '../../../containers/kpis'; import { FlyoutHeader } from '.'; import { useSourcererDataView } from '../../../../common/containers/sourcerer'; -import { mockBrowserFields, mockDocValueFields } from '../../../../common/containers/source/mock'; +import { mockBrowserFields } from '../../../../common/containers/source/mock'; import { getEmptyValue } from '../../../../common/components/empty_value'; import { allCasesPermissions, readCasesPermissions } from '../../../../cases_test_utils'; @@ -53,7 +53,6 @@ const mockUseTimelineLargeKpiResponse = { }; const defaultMocks = { browserFields: mockBrowserFields, - docValueFields: mockDocValueFields, indexPattern: mockIndexPattern, loading: false, selectedPatterns: mockIndexNames, diff --git a/x-pack/plugins/security_solution/public/timelines/components/flyout/header/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/flyout/header/index.tsx index 4dc62c43e7f1e6..743a1e87f9f8aa 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/flyout/header/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/flyout/header/index.tsx @@ -345,7 +345,7 @@ const TimelineStatusInfoComponent: React.FC = ({ timelineId } const TimelineStatusInfo = React.memo(TimelineStatusInfoComponent); const FlyoutHeaderComponent: React.FC = ({ timelineId }) => { - const { selectedPatterns, indexPattern, docValueFields, browserFields } = useSourcererDataView( + const { selectedPatterns, indexPattern, browserFields } = useSourcererDataView( SourcererScopeName.timeline ); const getStartSelector = useMemo(() => startSelector(), []); @@ -409,7 +409,6 @@ const FlyoutHeaderComponent: React.FC = ({ timelineId }) => { const [loading, kpis] = useTimelineKpis({ defaultIndex: selectedPatterns, - docValueFields, timerange, isBlankTimeline, filterQuery: combinedQueries?.filterQuery ?? '', diff --git a/x-pack/plugins/security_solution/public/timelines/components/graph_overlay/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/graph_overlay/index.tsx index 6ecaa56bc12db8..681de8ac4cb0c9 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/graph_overlay/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/graph_overlay/index.tsx @@ -84,11 +84,8 @@ const GraphOverlayComponent: React.FC = ({ const { timelineFullScreen } = useTimelineFullScreen(); const getTimeline = useMemo(() => timelineSelectors.getTimelineByIdSelector(), []); - const graphEventId = useDeepEqualSelector( - (state) => (getTimeline(state, timelineId) ?? timelineDefaults).graphEventId - ); - const sessionViewConfig = useDeepEqualSelector( - (state) => (getTimeline(state, timelineId) ?? timelineDefaults).sessionViewConfig + const { graphEventId, sessionViewConfig } = useDeepEqualSelector( + (state) => getTimeline(state, timelineId) ?? timelineDefaults ); const fullScreen = useMemo( diff --git a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/helpers.ts b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/helpers.ts index 8c69ae2df30daa..0d560b600ae341 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/helpers.ts +++ b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/helpers.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { set } from '@elastic/safer-lodash-set/fp'; +import { set } from '@kbn/safer-lodash-set/fp'; import { getOr, isEmpty } from 'lodash/fp'; import type { Action } from 'typescript-fsa'; import uuid from 'uuid'; diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/eql_tab_content/index.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/eql_tab_content/index.test.tsx index c2036263ec28d6..aae85b19bfd05c 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/eql_tab_content/index.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/eql_tab_content/index.test.tsx @@ -194,7 +194,6 @@ describe('Timeline', () => { test('it does render the timeline table when the source is loading with no events', () => { (useSourcererDataView as jest.Mock).mockReturnValue({ browserFields: {}, - docValueFields: [], loading: true, indexPattern: {}, selectedPatterns: [], diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/index.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/index.test.tsx index d8c7c5e34c9083..310849aee4c095 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/index.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/index.test.tsx @@ -11,7 +11,7 @@ import useResizeObserver from 'use-resize-observer/polyfilled'; import { DragDropContextWrapper } from '../../../common/components/drag_and_drop/drag_drop_context_wrapper'; import '../../../common/mock/match_media'; -import { mockBrowserFields, mockDocValueFields } from '../../../common/containers/source/mock'; +import { mockBrowserFields } from '../../../common/containers/source/mock'; import { TimelineId } from '../../../../common/types/timeline'; import { createSecuritySolutionStorageMock, @@ -38,7 +38,9 @@ jest.mock('../../containers', () => ({ useTimelineEvents: jest.fn(), })); -jest.mock('./tabs_content'); +jest.mock('./tabs_content', () => ({ + TabsContent: () =>
, +})); jest.mock('../../../common/lib/kibana'); const originalKibanaLib = jest.requireActual('../../../common/lib/kibana'); @@ -92,7 +94,6 @@ jest.mock('../../../common/containers/sourcerer'); const mockDataView = { dataViewId: mockGlobalState.timeline.timelineById.test?.dataViewId, browserFields: mockBrowserFields, - docValueFields: mockDocValueFields, loading: false, indexPattern: mockIndexPattern, pageInfo: { activePage: 0, querySize: 0 }, diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/properties/helpers.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/properties/helpers.test.tsx index 76d3ceb2408835..b7f9d74a9019c1 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/properties/helpers.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/properties/helpers.test.tsx @@ -40,7 +40,7 @@ jest.mock('../../../../common/lib/kibana', () => ({ })); describe('NewTimeline', () => { - const mockGetButton = jest.fn(); + const mockGetButton = jest.fn().mockReturnValue('<>'); const props: NewTimelineProps = { closeGearMenu: jest.fn(), diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/query_tab_content/index.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/query_tab_content/index.test.tsx index 831b8358bad26d..c7a30a4f501b8b 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/query_tab_content/index.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/query_tab_content/index.test.tsx @@ -206,7 +206,6 @@ describe('Timeline', () => { test('it does render the timeline table when the source is loading with no events', () => { (useSourcererDataView as jest.Mock).mockReturnValue({ browserFields: {}, - docValueFields: [], loading: true, indexPattern: {}, selectedPatterns: [], diff --git a/x-pack/plugins/security_solution/public/timelines/containers/kpis/index.tsx b/x-pack/plugins/security_solution/public/timelines/containers/kpis/index.tsx index 5a4a61e809bd11..5bd71f4f7be948 100644 --- a/x-pack/plugins/security_solution/public/timelines/containers/kpis/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/containers/kpis/index.tsx @@ -14,7 +14,6 @@ import { isCompleteResponse, isErrorResponse } from '@kbn/data-plugin/public'; import type { inputsModel } from '../../../common/store'; import { useKibana } from '../../../common/lib/kibana'; import type { - DocValueFields, TimelineKpiStrategyRequest, TimelineKpiStrategyResponse, TimerangeInput, @@ -28,14 +27,12 @@ export interface UseTimelineKpiProps { timerange: TimerangeInput; filterQuery?: ESQuery | string | undefined; defaultIndex: string[]; - docValueFields?: DocValueFields[]; isBlankTimeline: boolean; } export const useTimelineKpis = ({ timerange, filterQuery, - docValueFields, defaultIndex, isBlankTimeline, }: UseTimelineKpiProps): [boolean, TimelineKpiStrategyResponse | null] => { @@ -96,7 +93,6 @@ export const useTimelineKpis = ({ setTimelineKpiRequest((prevRequest) => { const myRequest = { ...(prevRequest ?? {}), - docValueFields, defaultIndex, timerange, filterQuery, @@ -107,7 +103,7 @@ export const useTimelineKpis = ({ } return prevRequest; }); - }, [docValueFields, defaultIndex, timerange, filterQuery]); + }, [defaultIndex, timerange, filterQuery]); useEffect(() => { if (!isBlankTimeline) { diff --git a/x-pack/plugins/security_solution/public/users/pages/navigation/all_users_query_tab_body.tsx b/x-pack/plugins/security_solution/public/users/pages/navigation/all_users_query_tab_body.tsx index 0030391a2b54a0..7c203d59207066 100644 --- a/x-pack/plugins/security_solution/public/users/pages/navigation/all_users_query_tab_body.tsx +++ b/x-pack/plugins/security_solution/public/users/pages/navigation/all_users_query_tab_body.tsx @@ -32,7 +32,6 @@ export const AllUsersQueryTabBody = ({ setQuery, startDate, type, - docValueFields, deleteQuery, }: UsersComponentsQueryProps) => { const { toggleStatus } = useQueryToggle(QUERY_ID); @@ -70,7 +69,6 @@ export const AllUsersQueryTabBody = ({ search({ filterQuery, defaultIndex: indexNames, - docValueFields, timerange: { interval: '12h', from: startDate, @@ -80,18 +78,7 @@ export const AllUsersQueryTabBody = ({ sort, }); } - }, [ - search, - startDate, - endDate, - filterQuery, - indexNames, - querySkip, - docValueFields, - activePage, - limit, - sort, - ]); + }, [search, startDate, endDate, filterQuery, indexNames, querySkip, activePage, limit, sort]); return ( { @@ -47,7 +46,6 @@ export const AuthenticationsQueryTabBody = ({ startDate={startDate} type={type} skip={skip} - docValueFields={docValueFields} userName={userName} /> diff --git a/x-pack/plugins/security_solution/public/users/pages/navigation/types.ts b/x-pack/plugins/security_solution/public/users/pages/navigation/types.ts index aeac9326a1f938..4bc79174beba67 100644 --- a/x-pack/plugins/security_solution/public/users/pages/navigation/types.ts +++ b/x-pack/plugins/security_solution/public/users/pages/navigation/types.ts @@ -4,7 +4,6 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import type { DocValueFields } from '@kbn/timelines-plugin/common'; import type { UsersTableType, UsersType } from '../../store/model'; import type { GlobalTimeArgs } from '../../../common/containers/use_global_time'; import type { ESTermQuery } from '../../../../common/typed_json'; @@ -22,7 +21,6 @@ export interface QueryTabBodyProps { export type UsersComponentsQueryProps = QueryTabBodyProps & { deleteQuery?: GlobalTimeArgs['deleteQuery']; - docValueFields?: DocValueFields[]; indexNames: string[]; skip: boolean; setQuery: GlobalTimeArgs['setQuery']; diff --git a/x-pack/plugins/security_solution/public/users/pages/types.ts b/x-pack/plugins/security_solution/public/users/pages/types.ts index b7af4c3c54d22f..955b565b328a8e 100644 --- a/x-pack/plugins/security_solution/public/users/pages/types.ts +++ b/x-pack/plugins/security_solution/public/users/pages/types.ts @@ -6,13 +6,11 @@ */ import type { Filter } from '@kbn/es-query'; -import type { DocValueFields } from '@kbn/timelines-plugin/common'; import type { GlobalTimeArgs } from '../../common/containers/use_global_time'; import type { usersModel } from '../store'; export type UsersTabsProps = GlobalTimeArgs & { - docValueFields: DocValueFields[]; filterQuery: string; pageFilters?: Filter[]; indexNames: string[]; diff --git a/x-pack/plugins/security_solution/public/users/pages/users.tsx b/x-pack/plugins/security_solution/public/users/pages/users.tsx index 9d567e76050749..1f87ec55f808d1 100644 --- a/x-pack/plugins/security_solution/public/users/pages/users.tsx +++ b/x-pack/plugins/security_solution/public/users/pages/users.tsx @@ -102,7 +102,7 @@ const UsersComponent = () => { return filters; }, [severitySelection, tabName, filters]); - const { docValueFields, indicesExist, indexPattern, selectedPatterns } = useSourcererDataView(); + const { indicesExist, indexPattern, selectedPatterns } = useSourcererDataView(); const [filterQuery, kqlError] = useMemo( () => convertToBuildEsQuery({ @@ -210,7 +210,6 @@ const UsersComponent = () => { String(id) !== ''); +} + +/** + * Returns the resolver fields filter to use in queries to limit the number of fields returned in the + * query response. * @param schema is the node schema information describing how relationships are formed between nodes * in the resolver graph. */ -export function docValueFields(schema: ResolverSchema): Array<{ field: string }> { +export function resolverFields(schema: ResolverSchema): Array<{ field: string }> { const filter = [{ field: '@timestamp' }, { field: schema.id }, { field: schema.parent }]; if (schema.ancestry) { filter.push({ field: schema.ancestry }); @@ -40,12 +45,3 @@ export function docValueFields(schema: ResolverSchema): Array<{ field: string }> } return filter; } - -/** - * Returns valid IDs that can be used in a search. - * - * @param ids array of ids - */ -export function validIDs(ids: NodeID[]): NodeID[] { - return ids.filter((id) => String(id) !== ''); -} diff --git a/x-pack/plugins/security_solution/server/endpoint/services/metadata/endpoint_metadata_service.ts b/x-pack/plugins/security_solution/server/endpoint/services/metadata/endpoint_metadata_service.ts index fc95c7a025393d..d99b6594398591 100644 --- a/x-pack/plugins/security_solution/server/endpoint/services/metadata/endpoint_metadata_service.ts +++ b/x-pack/plugins/security_solution/server/endpoint/services/metadata/endpoint_metadata_service.ts @@ -64,14 +64,7 @@ type AgentPolicyWithPackagePolicies = Omit & { const isAgentPolicyWithPackagePolicies = ( agentPolicy: AgentPolicy | AgentPolicyWithPackagePolicies ): agentPolicy is AgentPolicyWithPackagePolicies => { - if ( - agentPolicy.package_policies.length === 0 || - typeof agentPolicy.package_policies[0] !== 'string' - ) { - return true; - } - - return false; + return agentPolicy.package_policies ? true : false; }; export class EndpointMetadataService { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/__mocks__/es_results.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/__mocks__/es_results.ts index ebdf002986ffb5..6c7d5d581ce613 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/__mocks__/es_results.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/__mocks__/es_results.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { set } from '@elastic/safer-lodash-set'; +import { set } from '@kbn/safer-lodash-set'; import type { SignalSourceHit, SignalSearchResponse, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/reason_formatter.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/reason_formatter.test.ts index 67deaec8e1d239..42c18e523f3d32 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/reason_formatter.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/reason_formatter.test.ts @@ -5,39 +5,50 @@ * 2.0. */ -import { buildReasonMessageUtil } from './reason_formatters'; -import type { SignalSourceHit } from './types'; +import { buildReasonMessageForThresholdAlert, buildReasonMessageUtil } from './reason_formatters'; + +const mergedDoc = { + _index: 'index-1', + _id: 'id-1', + fields: { + 'destination.address': ['9.99.99.9'], + 'destination.port': ['6789'], + 'event.category': ['test'], + 'file.name': ['sample'], + 'host.name': ['host'], + 'process.name': ['doingThings.exe'], + 'process.parent.name': ['didThings.exe'], + 'source.address': ['1.11.11.1'], + 'source.port': ['1234'], + 'user.name': ['test-user'], + '@timestamp': '2021-08-11T02:28:59.101Z', + }, +}; + +const genThresholdMergedDoc = (groupedKeys: Record) => ({ + _index: 'index-1', + _id: 'some-id', + _source: { + '@timestamp': '2022-08-16T11:01:09.848Z', + threshold_result: [Object], + ...groupedKeys, + }, +}); describe('reason_formatter', () => { - let name: string; + let ruleName: string; let severity: string; - let mergedDoc: SignalSourceHit; beforeAll(() => { - name = 'my-rule'; + ruleName = 'my-rule'; severity = 'medium'; - mergedDoc = { - _index: 'index-1', - _id: 'id-1', - fields: { - 'destination.address': ['9.99.99.9'], - 'destination.port': ['6789'], - 'event.category': ['test'], - 'file.name': ['sample'], - 'host.name': ['host'], - 'process.name': ['doingThings.exe'], - 'process.parent.name': ['didThings.exe'], - 'source.address': ['1.11.11.1'], - 'source.port': ['1234'], - 'user.name': ['test-user'], - '@timestamp': '2021-08-11T02:28:59.101Z', - }, - }; }); describe('buildReasonMessageUtil', () => { describe('when rule and mergedDoc are provided', () => { it('should return the full reason message', () => { - expect(buildReasonMessageUtil({ name, severity, mergedDoc })).toMatchInlineSnapshot( + expect( + buildReasonMessageUtil({ name: ruleName, severity, mergedDoc }) + ).toMatchInlineSnapshot( `"test event with process doingThings.exe, parent process didThings.exe, file sample, source 1.11.11.1:1234, destination 9.99.99.9:6789, by test-user on host created medium alert my-rule."` ); }); @@ -52,7 +63,7 @@ describe('reason_formatter', () => { }, }; expect( - buildReasonMessageUtil({ name, severity, mergedDoc: updatedMergedDoc }) + buildReasonMessageUtil({ name: ruleName, severity, mergedDoc: updatedMergedDoc }) ).toMatchInlineSnapshot( `"item one, item two event with process doingThings.exe, parent process didThings.exe, file sample, source 1.11.11.1:1234, destination 9.99.99.9:6789, by test-user on host created medium alert my-rule."` ); @@ -68,7 +79,7 @@ describe('reason_formatter', () => { }, }; expect( - buildReasonMessageUtil({ name, severity, mergedDoc: updatedMergedDoc }) + buildReasonMessageUtil({ name: ruleName, severity, mergedDoc: updatedMergedDoc }) ).toMatchInlineSnapshot( `"test event with process doingThings.exe, parent process didThings.exe, file sample, source 1.11.11.1:1234, destination 9.99.99.9:6789, by test-user created medium alert my-rule."` ); @@ -84,7 +95,7 @@ describe('reason_formatter', () => { }, }; expect( - buildReasonMessageUtil({ name, severity, mergedDoc: updatedMergedDoc }) + buildReasonMessageUtil({ name: ruleName, severity, mergedDoc: updatedMergedDoc }) ).toMatchInlineSnapshot( `"test event with process doingThings.exe, parent process didThings.exe, file sample, source 1.11.11.1:1234, destination 9.99.99.9:6789, on host created medium alert my-rule."` ); @@ -100,7 +111,7 @@ describe('reason_formatter', () => { }, }; expect( - buildReasonMessageUtil({ name, severity, mergedDoc: noDestinationPortDoc }) + buildReasonMessageUtil({ name: ruleName, severity, mergedDoc: noDestinationPortDoc }) ).toMatchInlineSnapshot( `"test event with process doingThings.exe, parent process didThings.exe, file sample, source 1.11.11.1:1234, destination 9.99.99.9 by test-user on host created medium alert my-rule."` ); @@ -115,7 +126,7 @@ describe('reason_formatter', () => { }, }; expect( - buildReasonMessageUtil({ name, severity, mergedDoc: noDestinationPortDoc }) + buildReasonMessageUtil({ name: ruleName, severity, mergedDoc: noDestinationPortDoc }) ).toMatchInlineSnapshot( `"test event with process doingThings.exe, parent process didThings.exe, file sample, source 1.11.11.1:1234, by test-user on host created medium alert my-rule."` ); @@ -131,7 +142,7 @@ describe('reason_formatter', () => { }, }; expect( - buildReasonMessageUtil({ name, severity, mergedDoc: noSourcePortDoc }) + buildReasonMessageUtil({ name: ruleName, severity, mergedDoc: noSourcePortDoc }) ).toMatchInlineSnapshot( `"test event with process doingThings.exe, parent process didThings.exe, file sample, source 1.11.11.1 destination 9.99.99.9:6789, by test-user on host created medium alert my-rule."` ); @@ -146,7 +157,7 @@ describe('reason_formatter', () => { }, }; expect( - buildReasonMessageUtil({ name, severity, mergedDoc: noSourcePortDoc }) + buildReasonMessageUtil({ name: ruleName, severity, mergedDoc: noSourcePortDoc }) ).toMatchInlineSnapshot( `"test event with process doingThings.exe, parent process didThings.exe, file sample, destination 9.99.99.9:6789, by test-user on host created medium alert my-rule."` ); @@ -163,7 +174,7 @@ describe('reason_formatter', () => { }, }; expect( - buildReasonMessageUtil({ name, severity, mergedDoc: updatedMergedDoc }) + buildReasonMessageUtil({ name: ruleName, severity, mergedDoc: updatedMergedDoc }) ).toMatchInlineSnapshot( `"test event with file sample, source 1.11.11.1:1234, destination 9.99.99.9:6789, by test-user on host created medium alert my-rule."` ); @@ -180,14 +191,61 @@ describe('reason_formatter', () => { }, }; expect( - buildReasonMessageUtil({ name, severity, mergedDoc: updatedMergedDoc }) + buildReasonMessageUtil({ name: ruleName, severity, mergedDoc: updatedMergedDoc }) ).toMatchInlineSnapshot(`"test event by test-user created medium alert my-rule."`); }); }); describe('when only rule is provided', () => { it('should return the reason message without host name or user name', () => { - expect(buildReasonMessageUtil({ name, severity })).toMatchInlineSnapshot(`""`); + expect(buildReasonMessageUtil({ name: ruleName, severity })).toMatchInlineSnapshot(`""`); + }); + }); + }); + + describe(`buildReasonMessageForThresholdAlert`, () => { + it('When thresold rule is grouped by user.name', () => { + const userName = 'Some User Name'; + const thresholdMergedDoc = genThresholdMergedDoc({ + 'user.name': userName, + }); + expect( + buildReasonMessageForThresholdAlert({ + name: ruleName, + severity, + mergedDoc: thresholdMergedDoc, + }) + ).toEqual(`event by ${userName} created ${severity} alert ${ruleName}.`); + }); + + it('When threshold rule is grouped by host.name', () => { + const hostName = 'Some Host Name'; + const thresholdMergedDoc = genThresholdMergedDoc({ + 'host.name': hostName, }); + + expect( + buildReasonMessageForThresholdAlert({ + name: ruleName, + severity, + mergedDoc: thresholdMergedDoc, + }) + ).toEqual(`event on ${hostName} created ${severity} alert ${ruleName}.`); + }); + it('When threshold rule is grouped by host.name and user.name', () => { + const hostName = 'Some Host Name'; + const userName = 'Some User Name'; + const thresholdMergedDoc = genThresholdMergedDoc({ + 'host.name': hostName, + 'user.name': userName, + }); + + expect( + buildReasonMessageForThresholdAlert({ + name: ruleName, + severity, + mergedDoc: thresholdMergedDoc, + }) + ).toEqual(`event by ${userName} on ${hostName} created ${severity} alert ${ruleName}.`); }); }); }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/reason_formatters.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/reason_formatters.ts index 0b9148d995c74f..88aa69186e58a6 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/reason_formatters.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/reason_formatters.ts @@ -35,7 +35,7 @@ interface ReasonFields { } const getFieldsFromDoc = (mergedDoc: SignalSourceHit) => { const reasonFields: ReasonFields = {}; - const docToUse = mergedDoc?.fields || mergedDoc; + const docToUse = mergedDoc?.fields || mergedDoc?._source || mergedDoc; reasonFields.destinationAddress = getOr(null, 'destination.address', docToUse); reasonFields.destinationPort = getOr(null, 'destination.port', docToUse); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/source_fields_merging/strategies/merge_all_fields_with_source.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/source_fields_merging/strategies/merge_all_fields_with_source.ts index f4851e77f2048f..e3c7f8f5ee50ed 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/source_fields_merging/strategies/merge_all_fields_with_source.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/source_fields_merging/strategies/merge_all_fields_with_source.ts @@ -6,7 +6,7 @@ */ import { get } from 'lodash/fp'; -import { set } from '@elastic/safer-lodash-set/fp'; +import { set } from '@kbn/safer-lodash-set/fp'; import type { SignalSource } from '../../types'; import { filterFieldEntries } from '../utils/filter_field_entries'; import type { FieldsType, MergeStrategyFunction } from '../types'; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/source_fields_merging/strategies/merge_missing_fields_with_source.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/source_fields_merging/strategies/merge_missing_fields_with_source.test.ts index a5c811bc1a5c18..f5863533ea2832 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/source_fields_merging/strategies/merge_missing_fields_with_source.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/source_fields_merging/strategies/merge_missing_fields_with_source.test.ts @@ -370,9 +370,9 @@ describe('merge_missing_fields_with_source', () => { /** * tests for https://github.com/elastic/kibana/issues/135963 * This test will fail when we replace the import - * import { set } from '@elastic/safer-lodash-set'; + * import { set } from '@kbn/safer-lodash-set'; * to use the fp version - * import { set } from '@elastic/safer-lodash-set/fp'; + * import { set } from '@kbn/safer-lodash-set/fp'; * and switch around the return inside of filteredEntries.reduce * to be the following: * return set(fieldsKey, valueToMerge, merged); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/source_fields_merging/strategies/merge_missing_fields_with_source.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/source_fields_merging/strategies/merge_missing_fields_with_source.ts index 89695f6b562b01..c20f6b55301bda 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/source_fields_merging/strategies/merge_missing_fields_with_source.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/source_fields_merging/strategies/merge_missing_fields_with_source.ts @@ -6,7 +6,7 @@ */ import { get } from 'lodash/fp'; -import { set } from '@elastic/safer-lodash-set'; +import { set } from '@kbn/safer-lodash-set'; import type { SignalSource } from '../../types'; import { filterFieldEntries } from '../utils/filter_field_entries'; import type { FieldsType, MergeStrategyFunction } from '../types'; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/source_fields_merging/utils/recursive_unboxing_fields.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/source_fields_merging/utils/recursive_unboxing_fields.ts index cc5096825951f5..8bb490c2d62dfb 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/source_fields_merging/utils/recursive_unboxing_fields.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/source_fields_merging/utils/recursive_unboxing_fields.ts @@ -6,7 +6,7 @@ */ import { get } from 'lodash/fp'; -import { set } from '@elastic/safer-lodash-set/fp'; +import { set } from '@kbn/safer-lodash-set/fp'; import type { SearchTypes } from '../../../../../../common/detection_engine/types'; import type { FieldsType } from '../types'; diff --git a/x-pack/plugins/security_solution/server/lib/timeline/utils/common.ts b/x-pack/plugins/security_solution/server/lib/timeline/utils/common.ts index 0d5cf7684f02ba..97b6ec743d1092 100644 --- a/x-pack/plugins/security_solution/server/lib/timeline/utils/common.ts +++ b/x-pack/plugins/security_solution/server/lib/timeline/utils/common.ts @@ -5,7 +5,7 @@ * 2.0. */ import type * as rt from 'io-ts'; -import { set } from '@elastic/safer-lodash-set/fp'; +import { set } from '@kbn/safer-lodash-set/fp'; import readline from 'readline'; import fs from 'fs'; import type { Readable } from 'stream'; diff --git a/x-pack/plugins/security_solution/server/lib/timeline/utils/migrator.ts b/x-pack/plugins/security_solution/server/lib/timeline/utils/migrator.ts index c97f7053a50989..fa9c9250e2190f 100644 --- a/x-pack/plugins/security_solution/server/lib/timeline/utils/migrator.ts +++ b/x-pack/plugins/security_solution/server/lib/timeline/utils/migrator.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { set } from '@elastic/safer-lodash-set'; +import { set } from '@kbn/safer-lodash-set'; import _ from 'lodash'; import type { SavedObject, diff --git a/x-pack/plugins/security_solution/server/lists_integration/endpoint/validators/base_validator.test.ts b/x-pack/plugins/security_solution/server/lists_integration/endpoint/validators/base_validator.test.ts index d149b8c0fd7ba9..a1918b628c1d42 100644 --- a/x-pack/plugins/security_solution/server/lists_integration/endpoint/validators/base_validator.test.ts +++ b/x-pack/plugins/security_solution/server/lists_integration/endpoint/validators/base_validator.test.ts @@ -144,12 +144,7 @@ describe('When using Artifacts Exceptions BaseValidator', () => { }); it('should throw if policy ids for by policy artifacts are not valid', async () => { - packagePolicyService.getByIDs.mockResolvedValue([ - { - id: '123', - version: undefined, - } as PackagePolicy, - ]); + packagePolicyService.getByIDs.mockResolvedValue([]); await expect(initValidator()._validateByPolicyItem(exceptionLikeItem)).rejects.toBeInstanceOf( EndpointArtifactExceptionValidationError diff --git a/x-pack/plugins/security_solution/server/lists_integration/endpoint/validators/base_validator.ts b/x-pack/plugins/security_solution/server/lists_integration/endpoint/validators/base_validator.ts index 04a7d5a09875b7..872d8da7cdb3da 100644 --- a/x-pack/plugins/security_solution/server/lists_integration/endpoint/validators/base_validator.ts +++ b/x-pack/plugins/security_solution/server/lists_integration/endpoint/validators/base_validator.ts @@ -131,7 +131,9 @@ export class BaseValidator { return; } - const policiesFromFleet = await packagePolicy.getByIDs(internalReadonlySoClient, policyIds); + const policiesFromFleet = await packagePolicy.getByIDs(internalReadonlySoClient, policyIds, { + ignoreMissing: true, + }); if (!policiesFromFleet) { throw new EndpointArtifactExceptionValidationError( @@ -139,9 +141,9 @@ export class BaseValidator { ); } - const invalidPolicyIds = policiesFromFleet - .filter((policy) => policy.version === undefined) - .map((policy) => policy.id); + const invalidPolicyIds = policyIds.filter( + (policyId) => !policiesFromFleet.some((policy) => policyId === policy.id) + ); if (invalidPolicyIds.length) { throw new EndpointArtifactExceptionValidationError( diff --git a/x-pack/plugins/security_solution/server/search_strategy/helpers/format_response_object_values.ts b/x-pack/plugins/security_solution/server/search_strategy/helpers/format_response_object_values.ts index a20e5aba9fda1d..f44ad77e67929b 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/helpers/format_response_object_values.ts +++ b/x-pack/plugins/security_solution/server/search_strategy/helpers/format_response_object_values.ts @@ -6,7 +6,7 @@ */ import { mapValues, isObject, isArray } from 'lodash/fp'; -import { set } from '@elastic/safer-lodash-set'; +import { set } from '@kbn/safer-lodash-set'; import { toArray } from '../../../common/utils/to_array'; import { isGeoField } from '../../../common/utils/field_formatters'; diff --git a/x-pack/plugins/security_solution/server/search_strategy/helpers/get_flattened_fields.ts b/x-pack/plugins/security_solution/server/search_strategy/helpers/get_flattened_fields.ts index d0a9991f866dbf..f40edfc5914df5 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/helpers/get_flattened_fields.ts +++ b/x-pack/plugins/security_solution/server/search_strategy/helpers/get_flattened_fields.ts @@ -4,7 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { set } from '@elastic/safer-lodash-set'; +import { set } from '@kbn/safer-lodash-set'; import { get, isEmpty } from 'lodash/fp'; import { toObjectArrayOfStrings } from '../../../common/utils/to_array'; diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/all/helpers.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/all/helpers.ts index 3e92a733d12bd8..93ce3a15009b7a 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/all/helpers.ts +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/all/helpers.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { set } from '@elastic/safer-lodash-set/fp'; +import { set } from '@kbn/safer-lodash-set/fp'; import { get, has } from 'lodash/fp'; import { hostFieldsMap } from '../../../../../../common/ecs/ecs_fields'; import type { diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/details/helpers.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/details/helpers.ts index 3f2a052ffc1b1e..0c1ef643e663f3 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/details/helpers.ts +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/details/helpers.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { set } from '@elastic/safer-lodash-set/fp'; +import { set } from '@kbn/safer-lodash-set/fp'; import { get, has, head } from 'lodash/fp'; import type { IScopedClusterClient, diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/uncommon_processes/helpers.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/uncommon_processes/helpers.ts index 15d1b3029a96d1..3cae17446439f6 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/uncommon_processes/helpers.ts +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/uncommon_processes/helpers.ts @@ -6,7 +6,7 @@ */ import { get } from 'lodash/fp'; -import { set } from '@elastic/safer-lodash-set/fp'; +import { set } from '@kbn/safer-lodash-set/fp'; import type { ProcessHits, diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/matrix_histogram/dns/query.dns_histogram.dsl.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/matrix_histogram/dns/query.dns_histogram.dsl.ts index 17f083eeca9c18..c547f0a6ada3fd 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/matrix_histogram/dns/query.dns_histogram.dsl.ts +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/matrix_histogram/dns/query.dns_histogram.dsl.ts @@ -5,8 +5,6 @@ * 2.0. */ -import { isEmpty } from 'lodash/fp'; - import moment from 'moment'; import type { MatrixHistogramRequestOptions } from '../../../../../../common/search_strategy'; @@ -57,7 +55,6 @@ const getHistogramAggregation = ({ from, to }: { from: string; to: string }) => export const buildDnsHistogramQuery = ({ defaultIndex, - docValueFields, filterQuery, isPtrIncluded = false, stackByField = 'dns.question.registered_domain', @@ -81,7 +78,6 @@ export const buildDnsHistogramQuery = ({ index: defaultIndex, ignore_unavailable: true, body: { - ...(!isEmpty(docValueFields) ? { docvalue_fields: docValueFields } : {}), aggregations: { ...getCountAgg(), dns_name_query_count: { diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/authentications/helpers.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/authentications/helpers.ts index 60cd5704784881..53623d44205b37 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/authentications/helpers.ts +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/authentications/helpers.ts @@ -6,7 +6,7 @@ */ import { get, getOr, isEmpty } from 'lodash/fp'; -import { set } from '@elastic/safer-lodash-set/fp'; +import { set } from '@kbn/safer-lodash-set/fp'; import { toObjectArrayOfStrings } from '../../../../../../common/utils/to_array'; import { sourceFieldsMap, hostFieldsMap } from '../../../../../../common/ecs/ecs_fields'; import type { diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/details/helpers.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/details/helpers.ts index cf18f08476fcdc..f6c9f1d1942151 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/details/helpers.ts +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/details/helpers.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { set } from '@elastic/safer-lodash-set/fp'; +import { set } from '@kbn/safer-lodash-set/fp'; import { get, has } from 'lodash/fp'; import type { UserAggEsItem, diff --git a/x-pack/plugins/session_view/common/constants.ts b/x-pack/plugins/session_view/common/constants.ts index 5bf0dc53701fc0..538605bb591b0c 100644 --- a/x-pack/plugins/session_view/common/constants.ts +++ b/x-pack/plugins/session_view/common/constants.ts @@ -43,7 +43,15 @@ export const ALERT_STATUS = { export const LOCAL_STORAGE_DISPLAY_OPTIONS_KEY = 'sessionView:displayOptions'; export const MOUSE_EVENT_PLACEHOLDER = { stopPropagation: () => undefined } as React.MouseEvent; export const DEBOUNCE_TIMEOUT = 500; -export const DEFAULT_TTY_PLAYSPEED_MS = 40; // milli seconds per line of tty output. +export const DEFAULT_TTY_PLAYSPEED_MS = 80; // milli seconds per line of tty output. +export const DEFAULT_TTY_FONT_SIZE = 11; + +// we split terminal output on both newlines and cursor movements. +export const TTY_LINE_SPLITTER_REGEX = /(\r?\n|\x1b\[\d+;\d+[Hf])/gi; + +// used when searching output +export const TTY_STRIP_CONTROL_CODES_REGEX = + /[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/gi; // when showing the count of alerts in details panel tab, if the number // exceeds ALERT_COUNT_THRESHOLD we put a + next to it, e.g 999+ diff --git a/x-pack/plugins/session_view/common/mocks/responses/session_view_io_events.mock.ts b/x-pack/plugins/session_view/common/mocks/responses/session_view_io_events.mock.ts index 33b9ac56b035df..c14dccc2bc3d65 100644 --- a/x-pack/plugins/session_view/common/mocks/responses/session_view_io_events.mock.ts +++ b/x-pack/plugins/session_view/common/mocks/responses/session_view_io_events.mock.ts @@ -17,6 +17,7 @@ export const sessionViewIOEventsMock: ProcessEventResults = { message: 'hello world security', event: { action: 'text_output', + id: '1', }, process: { entity_id: '1', @@ -30,7 +31,15 @@ export const sessionViewIOEventsMock: ProcessEventResults = { total_bytes_captured: 1024, total_bytes_skipped: 0, bytes_skipped: [], - text: "256\n,\n Some Companies Puppet instance\n | | | CentOS Stream release 8 on x86_64\n .=/ = = =| =| = === = Load average: 1.23, 1.01, 0.63\n | || || || || || | | | | \n /= = = =' =' =' ' =' Hostname ********\n \\ Type xyz\n o Datacenter ********\n Cluster ********\n\n\n\n\n,0 loaded units listed. Pass --all to see loaded but inactive units, too.\nTo show all installed unit files use 'systemctl list-unit-files'.\n", + text: "256\n,\n Some Companies Puppet instance\n | | | CentOS Stream release 8 on x86_64\n *********************** Load average: 1.23, 1.01, 0.63\n ************************ \n ************************ Hostname ********\n \\ Type xyz\n o Datacenter ********\n Cluster ********\n\n\n\n\n,0 loaded units listed. Pass --all to see loaded but inactive units, too.\nTo show all installed unit files use 'systemctl list-unit-files'.\n", + }, + tty: { + char_device: { + major: 4, + minor: 1, + }, + rows: 59, + columns: 173, }, }, }, @@ -44,6 +53,7 @@ export const sessionViewIOEventsMock: ProcessEventResults = { message: 'hello world security', event: { action: 'text_output', + id: '1', }, process: { entity_id: '2', @@ -57,7 +67,15 @@ export const sessionViewIOEventsMock: ProcessEventResults = { total_bytes_captured: 1024, total_bytes_skipped: 0, bytes_skipped: [], - text: ',\u001b[?2004h\u001b[?1049h\u001b[22;0;0t\u001b[?1h\u001b=\u001b[?2004h\u001b[1;59r\u001b[?12h\u001b[?12l\u001b[27m\u001b[29m\u001b[m\u001b[H\u001b[2J\u001b[?25l\u001b[59;1H"/usr/local/bin/galera_traffic_start.sh" [readonly] 14L, 397C\u001b[1;1H#!/bin/env bash\n# Copyright (C) 2022, ********(R) Corporation. All rights reserved.\n\n# Script for setting the reject of queries in Galera\n\nmysql -h127.0.0.1 -P6033 -uroot -e "set global wsrep_reject_queries=\'NONE\'" 2>&1\nRC=$?\n\nif [[ $RC != 0 ]]; then\n >&2 echo "Failed to unset the reject of queries on Galera node, exiting."\n exit $RC\nelse\n echo "Successfully unset the reject of queries."\nfi\n\u001b[94m~ \u001b[16;1H~ \u001b[17;1H~ \u001b[18;1H~ \u001b[19;1H~ \u001b[20;1H~ \u001b[21;1H~ \u001b[22;1H~ \u001b[23;1H~ \u001b[24;1H~ \u001b[25;1H~ \u001b[26;1H~ \u001b[27;1H~ \u001b[28;1H~ \u001b[29;1H~ \u001b[30;1H~ \u001b[31;1H~ \u001b[32;1H~ \u001b[33;1H~ \u001b[34;1H~ \u001b[35;1H~ \u001b[36;1H~ \u001b[37;1H~ \u001b[38;1H~ \u001b[39;1H~ \u001b[40;1H~ \u001b[41;1H~ \u001b[42;1H~ \u001b[43;1H~ \u001b[44;1H~ \u001b[45;1H~ \u001b[46;1H~ \u001b[47;1H~ \u001b[48;1H~ \u001b[49;1H~ \u001b[50;1H~ \u001b[51;1H~ \u001b[52;1H~ \u001b[53;1H~ \u001b[54;1H~ \u001b[55;1H~ \u001b[56;1H~ \u001b[57;1H~ \u001b[58;1H~ \u001b[1;1H\u001b[?25h\u0007\u001b[?25l\u001b[m\u001b[59;1H\u001b[K\u001b[59;1H:\u001b[?2004h\u001b[?25hq\r\u001b[?25l\u001b[?2004l\u001b[59;1H\u001b[K\u001b[59;1H\u001b[?2004l\u001b[?1l\u001b>\u001b[?25h\u001b[?1049l\u001b[23;0;0t,\u001b[?2004h\u001b[?1049h\u001b[22;0;0t\u001b[?1h\u001b=\u001b[?2004h\u001b[1;59r\u001b[?12h\u001b[?12l\u001b[27m\u001b[29m\u001b[m\u001b[H\u001b[2J\u001b[?25l\u001b[59;1H"/usr/local/bin/galera_traffic_stop.sh" [readonly] 115L, 3570C\u001b[1;1H#!/bin/env bash\n# Copyright (C) 2022, ********(R) Corporation. All rights reserved.\n\n# Script for rejecting connection on Galera cluster node, either gracefully or not,\n# depending on supplied arguments.\n\nfunction usage() {\n echo "\n This script disables DB connections to Galera node.\n The default is to stop them gracefully.\n\n Usage: $0 [-h] [-w ] [-s ] [-x]\n\n Options:\n -h Prints this help.\n -w Number of seconds for waiting to close the connections.\u001b[17;11HDefault value is to wait for mysql-wait_timeout.\n -s Sleep interval between connections checks.\n -x Kills all connections immediately. Other options are ignored."\n exit\n}\n', + text: ',\u001b[?2004h\u001b[?1049h\u001b[22;0;0t\u001b[?1h\u001b=\u001b[?2004h\u001b[1;59r\u001b[?12h\u001b[?12l\u001b[27m\u001b[29m\u001b[m\u001b[H\u001b[2J\u001b[?25l\u001b[59;1H"/usr/local/bin/script_one.sh" [readonly] 14L, 397C\u001b[1;1H#!/bin/env bash\n# Copyright (C) 2022, ********(R) Corporation. All rights reserved.\n\n# Script for setting the reject of queries in Mysql\n\nmysql -h127.0.0.1 -P6033 -uroot -e "set global wsrep_reject_queries=\'NONE\'" 2>&1\nRC=$?\n\nif [[ $RC != 0 ]]; then\n >&2 echo "Failed to unset the reject of queries on Mysql node, exiting."\n exit $RC\nelse\n echo "Successfully unset the reject of queries."\nfi\n\u001b[94m~ \u001b[16;1H~ \u001b[17;1H~ \u001b[18;1H~ \u001b[19;1H~ \u001b[20;1H~ \u001b[21;1H~ \u001b[22;1H~ \u001b[23;1H~ \u001b[24;1H~ \u001b[25;1H~ \u001b[26;1H~ \u001b[27;1H~ \u001b[28;1H~ \u001b[29;1H~ \u001b[30;1H~ \u001b[31;1H~ \u001b[32;1H~ \u001b[33;1H~ \u001b[34;1H~ \u001b[35;1H~ \u001b[36;1H~ \u001b[37;1H~ \u001b[38;1H~ \u001b[39;1H~ \u001b[40;1H~ \u001b[41;1H~ \u001b[42;1H~ \u001b[43;1H~ \u001b[44;1H~ \u001b[45;1H~ \u001b[46;1H~ \u001b[47;1H~ \u001b[48;1H~ \u001b[49;1H~ \u001b[50;1H~ \u001b[51;1H~ \u001b[52;1H~ \u001b[53;1H~ \u001b[54;1H~ \u001b[55;1H~ \u001b[56;1H~ \u001b[57;1H~ \u001b[58;1H~ \u001b[1;1H\u001b[?25h\u0007\u001b[?25l\u001b[m\u001b[59;1H\u001b[K\u001b[59;1H:\u001b[?2004h\u001b[?25hq\r\u001b[?25l\u001b[?2004l\u001b[59;1H\u001b[K\u001b[59;1H\u001b[?2004l\u001b[?1l\u001b>\u001b[?25h\u001b[?1049l\u001b[23;0;0t,\u001b[?2004h\u001b[?1049h\u001b[22;0;0t\u001b[?1h\u001b=\u001b[?2004h\u001b[1;59r\u001b[?12h\u001b[?12l\u001b[27m\u001b[29m\u001b[m\u001b[H\u001b[2J\u001b[?25l\u001b[59;1H"/usr/local/bin/script_two.sh" [readonly] 115L, 3570C\u001b[1;1H#!/bin/env bash\n# Copyright (C) 2022, ********(R) Corporation. All rights reserved.\n\n# Script for rejecting connection on Mysql cluster node, either gracefully or not,\n# depending on supplied arguments.\n\nfunction usage() {\n echo "\n This script disables DB connections to Mysql node.\n The default is to stop them gracefully.\n\n Usage: $0 [-h] [-w ] [-s ] [-x]\n\n Options:\n -h Prints this help.\n -w Number of seconds for waiting to close the connections.\u001b[17;11HDefault value is to wait for mysql-wait_timeout.\n -s Sleep interval between connections checks.\n -x Kills all connections immediately. Other options are ignored."\n exit\n}\n', + }, + tty: { + char_device: { + major: 4, + minor: 1, + }, + rows: 59, + columns: 173, }, }, }, @@ -71,6 +89,7 @@ export const sessionViewIOEventsMock: ProcessEventResults = { message: 'hello world security', event: { action: 'text_output', + id: '1', }, process: { entity_id: '2', @@ -84,7 +103,15 @@ export const sessionViewIOEventsMock: ProcessEventResults = { total_bytes_captured: 1024, total_bytes_skipped: 0, bytes_skipped: [], - text: '\nfunction get_number_db_connections() {\n # count current\n DB_CONNECTIONS_NUMBER=$(mysql -h127.0.0.1 -P6032 -uadmin -N --silent -e "select count(1) from stats_mysql_processlist where user = \'$DB_USER\' and db like \'db\\_%\' escapee\u001b[26;1H \'\\\'")\n}\n\nfunction set_number_grace_seconds() {\n local mysql_wait_timeout_ms=$(mysql -h127.0.0.1 -P6032 -uadmin -N --silent -e "select variable_value from global_variables where variable_name = \'mysql-wait_timeout\'")\n GRACE_PERIOD=$((($mysql_wait_timeout_ms+1000-1)/1000))\n}\n\nfunction wait_for_connections() {\n local number_of_loops=$(((($GRACE_PERIOD+$SLEEP_INTERVAL-1)/$SLEEP_INTERVAL)))\u001b[37;5Hecho "Waiting for connections to close for up to $GRACE_PERIOD seconds"\u001b[39;5Hfor i in $(seq 0 $number_of_loops); do\u001b[40;9Hget_number_db_connections\u001b[41;9Hif [[ $DB_CONNECTIONS_NUMBER -eq 0 ]]; then\u001b[42;13Hecho "No connection found for user $DB_USER to this node"\u001b[43;13Hbreak\u001b[44;9Helse\u001b[45;13Hecho "$DB_CONNECTIONS_NUMBER connection(s) found, waiting for ${SLEEP_INTERVAL}s, round $i"\u001b[46;13Hsleep $SLEEP_INTERVAL\u001b[47;9Hfi\n done\n}\n\nfunction parse_args() {\n while getopts \'hs:w:x\' opt; do\u001b[53;9Hcase "$opt" in\u001b[54;9Hh)\u001b[55;13Husage\u001b[56;13H;;\u001b[57;9Hs)\u001b[58;13Hif ! [[ $OPTARG =~ ^[0-9]+$ ]]; then\u001b[1;1H\u001b[?25h\u001b[?25l\u001b[59;1H\u001b[K\u001b[59;1H:\u001b[?2004h\u001b[?25hset number\r\u001b[?25l\u001b[1;1H\u001b[38;5;130m 1 \u001b[m#!/bin/env bash\n\u001b[38;5;130m 2 \u001b[m# Copyright (C) 2022, ********(R) Corporation. All rights reserved.\n\u001b[38;5;130m 3 \n 4 \u001b[m# Script for rejecting connection on Galera cluster node, either gracefully or not,\n\u001b[38;5;130m 5 \u001b[m# depending on supplied arguments.\n\u001b[38;5;130m 6 \n 7 \u001b[mfunction usage() {\n\u001b[38;5;130m 8 \u001b[m echo "\n\u001b[38;5;130m 9 \u001b[m This script disables DB connections to Galera node.\n\u001b[38;5;130m 10 \u001b[m The default is to stop them gracefully.\n\u001b[38;5;130m 11 \n 12 \u001b[m Usage: $0 [-h] [-w ] [-s ] [-x]\n\u001b[38;5;130m 13 \n 14 \u001b[m Options:\n\u001b[38;5;130m 15 \u001b[m -h Prints this help.\n\u001b[38;5;130m 16 \u001b[m -w Number of seconds for waiting to close the connections.\n\u001b[38;5;130m 17 \u001b[m Default value is to wait for mysql-wait_timeout.\n\u001b[38;5;130m 18 \u001b[m -s Sleep interval between connections checks.\n\u001b[38;5;130m 19 \u001b[m -x Kills all connections immediately. Other options are ignored."\n\u001b[38;5;130m 20 \u001b[m exit\n\u001b[38;5;130m 21 \u001b[m}\n\u001b[38;5;130m 22 \n 23 \u001b[mfunction get_number_db_connections() {\n\u001b[38;5;130m 24 \u001b[m # count current\n\u001b[38;5;130m 25 \u001b[m DB_CONNECTIONS_NUMBER=$(mysql -h127.0.0.1 -P6032 -uadmin -N --silent -e "select count(1) from stats_mysql_processlist where user = \'$DB_USER\' and db like \'db\\_%%\u001b[26;1H\u001b[38;5;130m \u001b[m\' escape \'\\\'")\n\u001b[38;5;130m 26 \u001b[m}\n\u001b[38;5;130m 27 \n 28 \u001b[mfunction set_number_grace_seconds() {\n\u001b[38;5;130m 29 \u001b[m local mysql_wait_timeout_ms=$(mysql -h127.0.0.1 -P6032 -uadmin -N --silent -e "select variable_value from global_variables where variable_name = \'mysql-wait_timm\u001b[31;1H\u001b[38;5;130m \u001b[meout\'")\u001b[31;16H\u001b[K\u001b[32;1H\u001b[38;5;130m 30 \u001b[m GRACE_PERIOD=$((($mysql_wait_timeout_ms+1000-1)/1000))\n\u001b[38;5;130m 31 \u001b[m}\n\u001b[38;5;130m 32 \u001b[m\u001b[34;10H\u001b[K\u001b[35;1H\u001b[38;5;130m 33 \u001b[mfunction wait_for_connections() {\u001b[35;42H\u001b[K\u001b[36;1H\u001b[38;5;130m 34 \u001b[m local number_of_loops=$(((($GRACE_PERIOD+$SLEEP_INTERVAL-1)/$SLEEP_INTERVAL)))\n\u001b[38;5;130m 35 \u001b[m\u001b[37;10H\u001b[K\u001b[38;1H\u001b[38;5;130m 36 \u001b[m echo "Waiting for connections to close for up to $GRACE_PERIOD seconds"\n\u001b[38;5;130m 37 \u001b[m\u001b[39;9H\u001b[K\u001b[40;1H\u001b[38;5;130m 38 \u001b[m for i in $(seq 0 $number_of_loops); do\n', + text: '\nfunction get_number_db_connections() {\n # count current\n DB_CONNECTIONS_NUMBER=$(mysql -h127.0.0.1 -P6032 -uadmin -N --silent -e "select count(1) from stats_mysql_processlist where user = \'$DB_USER\' and db like \'db\\_%\' escapee\u001b[26;1H \'\\\'")\n}\n\nfunction set_number_grace_seconds() {\n local mysql_wait_timeout_ms=$(mysql -h127.0.0.1 -P6032 -uadmin -N --silent -e "select variable_value from global_variables where variable_name = \'mysql-wait_timeout\'")\n GRACE_PERIOD=$((($mysql_wait_timeout_ms+1000-1)/1000))\n}\n\nfunction wait_for_connections() {\n local number_of_loops=$(((($GRACE_PERIOD+$SLEEP_INTERVAL-1)/$SLEEP_INTERVAL)))\u001b[37;5Hecho "Waiting for connections to close for up to $GRACE_PERIOD seconds"\u001b[39;5Hfor i in $(seq 0 $number_of_loops); do\u001b[40;9Hget_number_db_connections\u001b[41;9Hif [[ $DB_CONNECTIONS_NUMBER -eq 0 ]]; then\u001b[42;13Hecho "No connection found for user $DB_USER to this node"\u001b[43;13Hbreak\u001b[44;9Helse\u001b[45;13Hecho "$DB_CONNECTIONS_NUMBER connection(s) found, waiting for ${SLEEP_INTERVAL}s, round $i"\u001b[46;13Hsleep $SLEEP_INTERVAL\u001b[47;9Hfi\n done\n}\n\nfunction parse_args() {\n while getopts \'hs:w:x\' opt; do\u001b[53;9Hcase "$opt" in\u001b[54;9Hh)\u001b[55;13Husage\u001b[56;13H;;\u001b[57;9Hs)\u001b[58;13Hif ! [[ $OPTARG =~ ^[0-9]+$ ]]; then\u001b[1;1H\u001b[?25h\u001b[?25l\u001b[59;1H\u001b[K\u001b[59;1H:\u001b[?2004h\u001b[?25hset number\r\u001b[?25l\u001b[1;1H\u001b[38;5;130m 1 \u001b[m#!/bin/env bash\n\u001b[38;5;130m 2 \u001b[m# Copyright (C) 2022, ********(R) Corporation. All rights reserved.\n\u001b[38;5;130m 3 \n 4 \u001b[m# Script for rejecting connection on Mysql cluster node, either gracefully or not,\n\u001b[38;5;130m 5 \u001b[m# depending on supplied arguments.\n\u001b[38;5;130m 6 \n 7 \u001b[mfunction usage() {\n\u001b[38;5;130m 8 \u001b[m echo "\n\u001b[38;5;130m 9 \u001b[m This script disables DB connections to Mysql node.\n\u001b[38;5;130m 10 \u001b[m The default is to stop them gracefully.\n\u001b[38;5;130m 11 \n 12 \u001b[m Usage: $0 [-h] [-w ] [-s ] [-x]\n\u001b[38;5;130m 13 \n 14 \u001b[m Options:\n\u001b[38;5;130m 15 \u001b[m -h Prints this help.\n\u001b[38;5;130m 16 \u001b[m -w Number of seconds for waiting to close the connections.\n\u001b[38;5;130m 17 \u001b[m Default value is to wait for mysql-wait_timeout.\n\u001b[38;5;130m 18 \u001b[m -s Sleep interval between connections checks.\n\u001b[38;5;130m 19 \u001b[m -x Kills all connections immediately. Other options are ignored."\n\u001b[38;5;130m 20 \u001b[m exit\n\u001b[38;5;130m 21 \u001b[m}\n\u001b[38;5;130m 22 \n 23 \u001b[mfunction get_number_db_connections() {\n\u001b[38;5;130m 24 \u001b[m # count current\n\u001b[38;5;130m 25 \u001b[m DB_CONNECTIONS_NUMBER=$(mysql -h127.0.0.1 -P6032 -uadmin -N --silent -e "select count(1) from stats_mysql_processlist where user = \'$DB_USER\' and db like \'db\\_%%\u001b[26;1H\u001b[38;5;130m \u001b[m\' escape \'\\\'")\n\u001b[38;5;130m 26 \u001b[m}\n\u001b[38;5;130m 27 \n 28 \u001b[mfunction set_number_grace_seconds() {\n\u001b[38;5;130m 29 \u001b[m local mysql_wait_timeout_ms=$(mysql -h127.0.0.1 -P6032 -uadmin -N --silent -e "select variable_value from global_variables where variable_name = \'mysql-wait_timm\u001b[31;1H\u001b[38;5;130m \u001b[meout\'")\u001b[31;16H\u001b[K\u001b[32;1H\u001b[38;5;130m 30 \u001b[m GRACE_PERIOD=$((($mysql_wait_timeout_ms+1000-1)/1000))\n\u001b[38;5;130m 31 \u001b[m}\n\u001b[38;5;130m 32 \u001b[m\u001b[34;10H\u001b[K\u001b[35;1H\u001b[38;5;130m 33 \u001b[mfunction wait_for_connections() {\u001b[35;42H\u001b[K\u001b[36;1H\u001b[38;5;130m 34 \u001b[m local number_of_loops=$(((($GRACE_PERIOD+$SLEEP_INTERVAL-1)/$SLEEP_INTERVAL)))\n\u001b[38;5;130m 35 \u001b[m\u001b[37;10H\u001b[K\u001b[38;1H\u001b[38;5;130m 36 \u001b[m echo "Waiting for connections to close for up to $GRACE_PERIOD seconds"\n\u001b[38;5;130m 37 \u001b[m\u001b[39;9H\u001b[K\u001b[40;1H\u001b[38;5;130m 38 \u001b[m for i in $(seq 0 $number_of_loops); do\n', + }, + tty: { + char_device: { + major: 4, + minor: 1, + }, + rows: 59, + columns: 173, }, }, }, @@ -98,6 +125,7 @@ export const sessionViewIOEventsMock: ProcessEventResults = { message: 'hello world security', event: { action: 'text_output', + id: '1', }, process: { entity_id: '2', @@ -113,6 +141,14 @@ export const sessionViewIOEventsMock: ProcessEventResults = { bytes_skipped: [], text: '\u001b[38;5;130m 39 \u001b[m get_number_db_connections\u001b[41;42H\u001b[K\u001b[42;1H\u001b[38;5;130m 40 \u001b[m if [[ $DB_CONNECTIONS_NUMBER -eq 0 ]]; then\u001b[42;60H\u001b[K\u001b[43;1H\u001b[38;5;130m 41 \u001b[m echo "No connection found for user $DB_USER to this node"\n\u001b[38;5;130m 42 \u001b[m \u001b[8Cbreak\n\u001b[38;5;130m 43 \u001b[m else\u001b[45;21H\u001b[K\u001b[46;1H\u001b[38;5;130m 44 \u001b[m echo "$DB_CONNECTIONS_NUMBER connection(s) found, waiting for ${SLEEP_INTERVAL}s, round $i"\n\u001b[38;5;130m 45 \u001b[m \u001b[10Csleep $SLEEP_INTERVAL\n\u001b[38;5;130m 46 \u001b[m\u001b[8Cfi\n\u001b[38;5;130m 47 \u001b[m done\n\u001b[38;5;130m 48 \u001b[m}\n\u001b[38;5;130m 49 \u001b[m\u001b[51;10H\u001b[K\u001b[52;1H\u001b[38;5;130m 50 \u001b[mfunction parse_args() {\u001b[52;33H\u001b[K\u001b[53;1H\u001b[38;5;130m 51 \u001b[m while getopts \'hs:w:x\' opt; do\n\u001b[38;5;130m 52 \u001b[m case "$opt" in\n\u001b[38;5;130m 53 \u001b[m h)\n\u001b[38;5;130m 54 \u001b[m usage\n\u001b[38;5;130m 55 \u001b[m \u001b[10C;;\n\u001b[38;5;130m 56 \u001b[m s)\u001b[58;19H\u001b[K\u001b[1;9H\u001b[?25h\u001b[?25l\u001b[27m\u001b[29m\u001b[m\u001b[H\u001b[2J\u001b[1;1H\u001b[38;5;130m 58 \u001b[m\u001b[16C>&2 echo "Sleep interval (-s) must be a number"\n\u001b[38;5;130m 59 \u001b[m\u001b[16Cexit 1\n\u001b[38;5;130m 60 \u001b[m\u001b[12Cfi\n\u001b[38;5;130m 61 \u001b[m\u001b[12CARG_SLEEP_INTERVAL="$OPTARG"\n\u001b[38;5;130m 62 \u001b[m\u001b[12C;;\n\u001b[38;5;130m 63 \u001b[m\u001b[8Cw)\n\u001b[38;5;130m 64 \u001b[m\u001b[12Cif ! [[ $OPTARG =~ ^[0-9]+$ ]]; then\n\u001b[38;5;130m 65 \u001b[m\u001b[16C>&2 echo "Wait timeout (-w) must be a number"\n\u001b[38;5;130m 66 \u001b[m\u001b[16Cexit 1\n\u001b[38;5;130m 67 \u001b[m\u001b[12Cfi\n\u001b[38;5;130m 68 \u001b[m\u001b[12CARG_GRACE_PERIOD="$OPTARG"\n\u001b[38;5;130m 69 \u001b[m\u001b[12C;;\n\u001b[38;5;130m 70 \u001b[m\u001b[8Cx)\n\u001b[38;5;130m 71 \u001b[m\u001b[12CARG_KILL_IMMEDIATELY=1\n\u001b[38;5;130m 72 \u001b[m\u001b[12C;;\n\u001b[38;5;130m 73 \u001b[m\u001b[8Cesac\n\u001b[38;5;130m 74 \u001b[m done\n\u001b[38;5;130m 75 \n 76 \u001b[m GRACE_PERIOD=${ARG_GRACE_PERIOD:--1}\n\u001b[38;5;130m 77 \u001b[m SLEEP_INTERVAL=${ARG_SLEEP_INTERVAL:-30}\n\u001b[38;5;130m 78 \u001b[m KILL_IMMEDIATELY=${ARG_KILL_IMMEDIATELY:-0}\n\u001b[38;5;130m 79 \u001b[m}\n\u001b[38;5;130m 80 \n 81 \u001b[mDB_USER="rolap01"\n\u001b[38;5;130m 82 \n 83 \u001b[mparse_args $@\n\u001b[38;5;130m 84 \n 85 \u001b[mif [[ $KILL_IMMEDIATELY == 1 ]]; then\n\u001b[38;5;130m 86 \u001b[m echo "WARNING: Not waiting for connections to close gracefully"\n\u001b[38;5;130m 87 \u001b[m echo "Press any key to continue... wsrep_reject_queries will be set to \'ALL_KILL\'"\n\u001b[38;5;130m 88 \u001b[m read a\n\u001b[38;5;130m 89 \u001b[m mysql -h127.0.0.1 -P3306 -uroot -e "set global wsrep_reject_queries=\'ALL_KILL\'"\n\u001b[38;5;130m 90 \u001b[melse\n\u001b[38;5;130m 91 \u001b[m # Stop accepting queries in mariadb, do not kill opened connections\n\u001b[38;5;130m 92 \u001b[m mysql -h127.0.0.1 -P3306 -uroot -e "set global wsrep_reject_queries=\'ALL\'"\n\u001b[38;5;130m 93 \u001b[mfi\n\u001b[38;5;130m 94 \n 95 \u001b[mexit_code=$?\n', }, + tty: { + char_device: { + major: 4, + minor: 1, + }, + rows: 59, + columns: 173, + }, }, }, }, @@ -125,6 +161,7 @@ export const sessionViewIOEventsMock: ProcessEventResults = { message: 'hello world security', event: { action: 'text_output', + id: '1', }, process: { entity_id: '2', @@ -138,7 +175,15 @@ export const sessionViewIOEventsMock: ProcessEventResults = { total_bytes_captured: 1024, total_bytes_skipped: 0, bytes_skipped: [], - text: '\u001b[38;5;130m 96 \u001b[mif [[ $exit_code != 0 ]]; then\n\u001b[38;5;130m 97 \u001b[m >&2 echo "Failed to set the reject of queries on Galera node, exiting."\n\u001b[38;5;130m 98 \u001b[m exit $exit_code\n\u001b[38;5;130m 99 \u001b[melse\n\u001b[38;5;130m 100 \u001b[m echo "Successfully stopped accepting queries."\n\u001b[38;5;130m 101 \u001b[m if [[ $KILL_IMMEDIATELY == 1 ]]; then\n\u001b[38;5;130m 102 \u001b[m\u001b[8Cexit\n\u001b[38;5;130m 103 \u001b[m fi\n\u001b[38;5;130m 104 \u001b[mfi\n\u001b[38;5;130m 105 \n 106 \u001b[mif [[ $GRACE_PERIOD == -1 ]]; then\n\u001b[38;5;130m 107 \u001b[m set_number_grace_seconds\n\u001b[38;5;130m 108 \u001b[mfi\n\u001b[38;5;130m 109 \n 110 \u001b[mwait_for_connections\n\u001b[38;5;130m 111 \u001b[mif [[ $DB_CONNECTIONS_NUMBER != 0 ]]; then\n\u001b[38;5;130m 112 \u001b[m get_number_db_connections\n\u001b[38;5;130m 113 \u001b[m >&2 echo "ERROR: There are still $DB_CONNECTIONS_NUMBER opened DB connections."\n\u001b[38;5;130m 114 \u001b[m exit 3\n\u001b[38;5;130m 115 \u001b[mfi\b\b\u001b[?25h\u001b[?25l\u001b[27m\u001b[29m\u001b[m\u001b[H\u001b[2J\u001b[1;1H\u001b[38;5;130m 1 \u001b[m#!/bin/env bash\n\u001b[38;5;130m 2 \u001b[m# Copyright (C) 2022, ********(R) Corporation. All rights reserved.\n\u001b[38;5;130m 3 \n 4 \u001b[m# Script for rejecting connection on Galera cluster node, either gracefully or not,\n\u001b[38;5;130m 5 \u001b[m# depending on supplied arguments.\n\u001b[38;5;130m 6 \n 7 \u001b[mfunction usage() {\n\u001b[38;5;130m 8 \u001b[m echo "\n\u001b[38;5;130m 9 \u001b[m This script disables DB connections to Galera node.\n\u001b[38;5;130m 10 \u001b[m The default is to stop them gracefully.\n\u001b[38;5;130m 11 \n 12 \u001b[m Usage: $0 [-h] [-w ] [-s ] [-x]\n\u001b[38;5;130m 13 \n 14 \u001b[m Options:\n\u001b[38;5;130m 15 \u001b[m -h Prints this help.\n\u001b[38;5;130m 16 \u001b[m -w Number of seconds for waiting to close the connections.\n\u001b[38;5;130m 17 \u001b[m\u001b[10CDefault value is to wait for mysql-wait_timeout.\n\u001b[38;5;130m 18 \u001b[m -s Sleep interval between connections checks.\n\u001b[38;5;130m 19 \u001b[m -x Kills all connections immediately. Other options are ignored."\n\u001b[38;5;130m 20 \u001b[m exit\n\u001b[38;5;130m 21 \u001b[m}\n\u001b[38;5;130m 22 \n 23 \u001b[mfunction get_number_db_connections() {\n\u001b[38;5;130m 24 \u001b[m # count current\n\u001b[38;5;130m 25 \u001b[m DB_CONNECTIONS_NUMBER=$(mysql -h127.0.0.1 -P6032 -uadmin -N --silent -e "select count(1) from stats_mysql_processlist where user = \'$DB_USER\' and db like \'db\\_%%\u001b[26;1H\u001b[38;5;130m \u001b[m\' escape \'\\\'")\n\u001b[38;5;130m 26 \u001b[m}\n\u001b[38;5;130m 27 \n 28 \u001b[mfunction set_number_grace_seconds() {\n\u001b[38;5;130m 29 \u001b[m local mysql_wait_timeout_ms=$(mysql -h127.0.0.1 -P6032 -uadmin -N --silent -e "select variable_value from global_variables where variable_name = \'mysql-wait_timm\u001b[31;1H\u001b[38;5;130m \u001b[meout\'")\n\u001b[38;5;130m 30 \u001b[m GRACE_PERIOD=$((($mysql_wait_timeout_ms+1000-1)/1000))\n\u001b[38;5;130m 31 \u001b[m}\n\u001b[38;5;130m 32 \n', + text: '\u001b[38;5;130m 96 \u001b[mif [[ $exit_code != 0 ]]; then\n\u001b[38;5;130m 97 \u001b[m >&2 echo "Failed to set the reject of queries on Mysql node, exiting."\n\u001b[38;5;130m 98 \u001b[m exit $exit_code\n\u001b[38;5;130m 99 \u001b[melse\n\u001b[38;5;130m 100 \u001b[m echo "Successfully stopped accepting queries."\n\u001b[38;5;130m 101 \u001b[m if [[ $KILL_IMMEDIATELY == 1 ]]; then\n\u001b[38;5;130m 102 \u001b[m\u001b[8Cexit\n\u001b[38;5;130m 103 \u001b[m fi\n\u001b[38;5;130m 104 \u001b[mfi\n\u001b[38;5;130m 105 \n 106 \u001b[mif [[ $GRACE_PERIOD == -1 ]]; then\n\u001b[38;5;130m 107 \u001b[m set_number_grace_seconds\n\u001b[38;5;130m 108 \u001b[mfi\n\u001b[38;5;130m 109 \n 110 \u001b[mwait_for_connections\n\u001b[38;5;130m 111 \u001b[mif [[ $DB_CONNECTIONS_NUMBER != 0 ]]; then\n\u001b[38;5;130m 112 \u001b[m get_number_db_connections\n\u001b[38;5;130m 113 \u001b[m >&2 echo "ERROR: There are still $DB_CONNECTIONS_NUMBER opened DB connections."\n\u001b[38;5;130m 114 \u001b[m exit 3\n\u001b[38;5;130m 115 \u001b[mfi\b\b\u001b[?25h\u001b[?25l\u001b[27m\u001b[29m\u001b[m\u001b[H\u001b[2J\u001b[1;1H\u001b[38;5;130m 1 \u001b[m#!/bin/env bash\n\u001b[38;5;130m 2 \u001b[m# Copyright (C) 2022, ********(R) Corporation. All rights reserved.\n\u001b[38;5;130m 3 \n 4 \u001b[m# Script for rejecting connection on Mysql cluster node, either gracefully or not,\n\u001b[38;5;130m 5 \u001b[m# depending on supplied arguments.\n\u001b[38;5;130m 6 \n 7 \u001b[mfunction usage() {\n\u001b[38;5;130m 8 \u001b[m echo "\n\u001b[38;5;130m 9 \u001b[m This script disables DB connections to Mysql node.\n\u001b[38;5;130m 10 \u001b[m The default is to stop them gracefully.\n\u001b[38;5;130m 11 \n 12 \u001b[m Usage: $0 [-h] [-w ] [-s ] [-x]\n\u001b[38;5;130m 13 \n 14 \u001b[m Options:\n\u001b[38;5;130m 15 \u001b[m -h Prints this help.\n\u001b[38;5;130m 16 \u001b[m -w Number of seconds for waiting to close the connections.\n\u001b[38;5;130m 17 \u001b[m\u001b[10CDefault value is to wait for mysql-wait_timeout.\n\u001b[38;5;130m 18 \u001b[m -s Sleep interval between connections checks.\n\u001b[38;5;130m 19 \u001b[m -x Kills all connections immediately. Other options are ignored."\n\u001b[38;5;130m 20 \u001b[m exit\n\u001b[38;5;130m 21 \u001b[m}\n\u001b[38;5;130m 22 \n 23 \u001b[mfunction get_number_db_connections() {\n\u001b[38;5;130m 24 \u001b[m # count current\n\u001b[38;5;130m 25 \u001b[m DB_CONNECTIONS_NUMBER=$(mysql -h127.0.0.1 -P6032 -uadmin -N --silent -e "select count(1) from stats_mysql_processlist where user = \'$DB_USER\' and db like \'db\\_%%\u001b[26;1H\u001b[38;5;130m \u001b[m\' escape \'\\\'")\n\u001b[38;5;130m 26 \u001b[m}\n\u001b[38;5;130m 27 \n 28 \u001b[mfunction set_number_grace_seconds() {\n\u001b[38;5;130m 29 \u001b[m local mysql_wait_timeout_ms=$(mysql -h127.0.0.1 -P6032 -uadmin -N --silent -e "select variable_value from global_variables where variable_name = \'mysql-wait_timm\u001b[31;1H\u001b[38;5;130m \u001b[meout\'")\n\u001b[38;5;130m 30 \u001b[m GRACE_PERIOD=$((($mysql_wait_timeout_ms+1000-1)/1000))\n\u001b[38;5;130m 31 \u001b[m}\n\u001b[38;5;130m 32 \n', + }, + tty: { + char_device: { + major: 4, + minor: 1, + }, + rows: 59, + columns: 173, }, }, }, @@ -152,6 +197,7 @@ export const sessionViewIOEventsMock: ProcessEventResults = { message: 'hello world security', event: { action: 'text_output', + id: '1', }, process: { entity_id: '2', @@ -167,6 +213,14 @@ export const sessionViewIOEventsMock: ProcessEventResults = { bytes_skipped: [], text: ' 33 \u001b[mfunction wait_for_connections() {\n\u001b[38;5;130m 34 \u001b[m local number_of_loops=$(((($GRACE_PERIOD+$SLEEP_INTERVAL-1)/$SLEEP_INTERVAL)))\n\u001b[38;5;130m 35 \n 36 \u001b[m echo "Waiting for connections to close for up to $GRACE_PERIOD seconds"\n\u001b[38;5;130m 37 \n 38 \u001b[m for i in $(seq 0 $number_of_loops); do\n\u001b[38;5;130m 39 \u001b[m\u001b[8Cget_number_db_connections\n\u001b[38;5;130m 40 \u001b[m\u001b[8Cif [[ $DB_CONNECTIONS_NUMBER -eq 0 ]]; then\n\u001b[38;5;130m 41 \u001b[m\u001b[12Cecho "No connection found for user $DB_USER to this node"\n\u001b[38;5;130m 42 \u001b[m\u001b[12Cbreak\n\u001b[38;5;130m 43 \u001b[m\u001b[8Celse\n\u001b[38;5;130m 44 \u001b[m\u001b[12Cecho "$DB_CONNECTIONS_NUMBER connection(s) found, waiting for ${SLEEP_INTERVAL}s, round $i"\n\u001b[38;5;130m 45 \u001b[m\u001b[12Csleep $SLEEP_INTERVAL\n\u001b[38;5;130m 46 \u001b[m\u001b[8Cfi\n\u001b[38;5;130m 47 \u001b[m done\n\u001b[38;5;130m 48 \u001b[m}\n\u001b[38;5;130m 49 \n 50 \u001b[mfunction parse_args() {\n\u001b[38;5;130m 51 \u001b[m while getopts \'hs:w:x\' opt; do\n\u001b[38;5;130m 52 \u001b[m\u001b[8Ccase "$opt" in\n\u001b[38;5;130m 53 \u001b[m\u001b[8Ch)\n\u001b[38;5;130m 54 \u001b[m\u001b[12Cusage\n\u001b[38;5;130m 55 \u001b[m\u001b[12C;;\n\u001b[38;5;130m 56 \u001b[m\u001b[8Cs)\u001b[1;9H\u001b[?25h\u001b[?25l\u001b[27m\u001b[29m\u001b[m\u001b[H\u001b[2J\u001b[1;1H\u001b[38;5;130m 58 \u001b[m\u001b[16C>&2 echo "Sleep interval (-s) must be a number"\n\u001b[38;5;130m 59 \u001b[m\u001b[16Cexit 1\n\u001b[38;5;130m 60 \u001b[m\u001b[12Cfi\n\u001b[38;5;130m 61 \u001b[m\u001b[12CARG_SLEEP_INTERVAL="$OPTARG"\n\u001b[38;5;130m 62 \u001b[m\u001b[12C;;\n\u001b[38;5;130m 63 \u001b[m\u001b[8Cw)\n\u001b[38;5;130m 64 \u001b[m\u001b[12Cif ! [[ $OPTARG =~ ^[0-9]+$ ]]; then\n\u001b[38;5;130m 65 \u001b[m\u001b[16C>&2 echo "Wait timeout (-w) must be a number"\n\u001b[38;5;130m 66 \u001b[m\u001b[16Cexit 1\n\u001b[38;5;130m 67 \u001b[m\u001b[12Cfi\n\u001b[38;5;130m 68 \u001b[m\u001b[12CARG_GRACE_PERIOD="$OPTARG"\n\u001b[38;5;130m 69 \u001b[m\u001b[12C;;\n\u001b[38;5;130m 70 \u001b[m\u001b[8Cx)\n\u001b[38;5;130m 71 \u001b[m\u001b[12CARG_KILL_IMMEDIATELY=1\n\u001b[38;5;130m 72 \u001b[m\u001b[12C;;\n\u001b[38;5;130m 73 \u001b[m\u001b[8Cesac\n\u001b[38;5;130m 74 \u001b[m done\n\u001b[38;5;130m 75 \n 76 \u001b[m GRACE_PERIOD=${ARG_GRACE_PERIOD:--1}\n\u001b[38;5;130m 77 \u001b[m SLEEP_INTERVAL=${ARG_SLEEP_INTERVAL:-30}\n\u001b[38;5;130m 78 \u001b[m KILL_IMMEDIATELY=${ARG_KILL_IMMEDIATELY:-0}\n\u001b[38;5;130m 79 \u001b[m}\n\u001b[38;5;130m 80 \n 81 \u001b[mDB_USER="rolap01"\n\u001b[38;5;130m 82 \n 83 \u001b[mparse_args $@\n', }, + tty: { + char_device: { + major: 4, + minor: 1, + }, + rows: 59, + columns: 173, + }, }, }, }, @@ -179,6 +233,7 @@ export const sessionViewIOEventsMock: ProcessEventResults = { message: 'hello world security', event: { action: 'text_output', + id: '1', }, process: { entity_id: '2', @@ -192,7 +247,15 @@ export const sessionViewIOEventsMock: ProcessEventResults = { total_bytes_captured: 1024, total_bytes_skipped: 0, bytes_skipped: [], - text: '\u001b[38;5;130m 84 \n 85 \u001b[mif [[ $KILL_IMMEDIATELY == 1 ]]; then\n\u001b[38;5;130m 86 \u001b[m echo "WARNING: Not waiting for connections to close gracefully"\n\u001b[38;5;130m 87 \u001b[m echo "Press any key to continue... wsrep_reject_queries will be set to \'ALL_KILL\'"\n\u001b[38;5;130m 88 \u001b[m read a\n\u001b[38;5;130m 89 \u001b[m mysql -h127.0.0.1 -P3306 -uroot -e "set global wsrep_reject_queries=\'ALL_KILL\'"\n\u001b[38;5;130m 90 \u001b[melse\n\u001b[38;5;130m 91 \u001b[m # Stop accepting queries in mariadb, do not kill opened connections\n\u001b[38;5;130m 92 \u001b[m mysql -h127.0.0.1 -P3306 -uroot -e "set global wsrep_reject_queries=\'ALL\'"\n\u001b[38;5;130m 93 \u001b[mfi\n\u001b[38;5;130m 94 \n 95 \u001b[mexit_code=$?\n\u001b[38;5;130m 96 \u001b[mif [[ $exit_code != 0 ]]; then\n\u001b[38;5;130m 97 \u001b[m >&2 echo "Failed to set the reject of queries on Galera node, exiting."\n\u001b[38;5;130m 98 \u001b[m exit $exit_code\n\u001b[38;5;130m 99 \u001b[melse\n\u001b[38;5;130m 100 \u001b[m echo "Successfully stopped accepting queries."\n\u001b[38;5;130m 101 \u001b[m if [[ $KILL_IMMEDIATELY == 1 ]]; then\n\u001b[38;5;130m 102 \u001b[m\u001b[8Cexit\n\u001b[38;5;130m 103 \u001b[m fi\n\u001b[38;5;130m 104 \u001b[mfi\n\u001b[38;5;130m 105 \n 106 \u001b[mif [[ $GRACE_PERIOD == -1 ]]; then\n\u001b[38;5;130m 107 \u001b[m set_number_grace_seconds\n\u001b[38;5;130m 108 \u001b[mfi\n\u001b[38;5;130m 109 \n 110 \u001b[mwait_for_connections\n\u001b[38;5;130m 111 \u001b[mif [[ $DB_CONNECTIONS_NUMBER != 0 ]]; then\n\u001b[38;5;130m 112 \u001b[m get_number_db_connections\n\u001b[38;5;130m 113 \u001b[m >&2 echo "ERROR: There are still $DB_CONNECTIONS_NUMBER opened DB connections."\n\u001b[38;5;130m 114 \u001b[m exit 3\n\u001b[38;5;130m 115 \u001b[mfi\b\b\u001b[?25h\u001b[?25l\nType :qa! and press to abandon all changes and exit Vim\u0007\u001b[58;9H\u001b[?25h\u0007\u001b[?25l\u001b[59;1H\u001b[K\u001b[59;1H:\u001b[?2004h\u001b[?25hqa!\r\u001b[?25l\u001b[?2004l\u001b[59;1H\u001b[K\u001b[59;1H\u001b[?2004l\u001b[?1l\u001b>\u001b[?25h\u001b[?1049l\u001b[23;0;0t,\u001bkroot@staging-host:~\u001b\\\n', + text: '\u001b[38;5;130m 84 \n 85 \u001b[mif [[ $KILL_IMMEDIATELY == 1 ]]; then\n\u001b[38;5;130m 86 \u001b[m echo "WARNING: Not waiting for connections to close gracefully"\n\u001b[38;5;130m 87 \u001b[m echo "Press any key to continue... wsrep_reject_queries will be set to \'ALL_KILL\'"\n\u001b[38;5;130m 88 \u001b[m read a\n\u001b[38;5;130m 89 \u001b[m mysql -h127.0.0.1 -P3306 -uroot -e "set global wsrep_reject_queries=\'ALL_KILL\'"\n\u001b[38;5;130m 90 \u001b[melse\n\u001b[38;5;130m 91 \u001b[m # Stop accepting queries in mariadb, do not kill opened connections\n\u001b[38;5;130m 92 \u001b[m mysql -h127.0.0.1 -P3306 -uroot -e "set global wsrep_reject_queries=\'ALL\'"\n\u001b[38;5;130m 93 \u001b[mfi\n\u001b[38;5;130m 94 \n 95 \u001b[mexit_code=$?\n\u001b[38;5;130m 96 \u001b[mif [[ $exit_code != 0 ]]; then\n\u001b[38;5;130m 97 \u001b[m >&2 echo "Failed to set the reject of queries on Mysql node, exiting."\n\u001b[38;5;130m 98 \u001b[m exit $exit_code\n\u001b[38;5;130m 99 \u001b[melse\n\u001b[38;5;130m 100 \u001b[m echo "Successfully stopped accepting queries."\n\u001b[38;5;130m 101 \u001b[m if [[ $KILL_IMMEDIATELY == 1 ]]; then\n\u001b[38;5;130m 102 \u001b[m\u001b[8Cexit\n\u001b[38;5;130m 103 \u001b[m fi\n\u001b[38;5;130m 104 \u001b[mfi\n\u001b[38;5;130m 105 \n 106 \u001b[mif [[ $GRACE_PERIOD == -1 ]]; then\n\u001b[38;5;130m 107 \u001b[m set_number_grace_seconds\n\u001b[38;5;130m 108 \u001b[mfi\n\u001b[38;5;130m 109 \n 110 \u001b[mwait_for_connections\n\u001b[38;5;130m 111 \u001b[mif [[ $DB_CONNECTIONS_NUMBER != 0 ]]; then\n\u001b[38;5;130m 112 \u001b[m get_number_db_connections\n\u001b[38;5;130m 113 \u001b[m >&2 echo "ERROR: There are still $DB_CONNECTIONS_NUMBER opened DB connections."\n\u001b[38;5;130m 114 \u001b[m exit 3\n\u001b[38;5;130m 115 \u001b[mfi\b\b\u001b[?25h\u001b[?25l\nType :qa! and press to abandon all changes and exit Vim\u0007\u001b[58;9H\u001b[?25h\u0007\u001b[?25l\u001b[59;1H\u001b[K\u001b[59;1H:\u001b[?2004h\u001b[?25hqa!\r\u001b[?25l\u001b[?2004l\u001b[59;1H\u001b[K\u001b[59;1H\u001b[?2004l\u001b[?1l\u001b>\u001b[?25h\u001b[?1049l\u001b[23;0;0t,\u001bkroot@staging-host:~\u001b\\\n', + }, + tty: { + char_device: { + major: 4, + minor: 1, + }, + rows: 59, + columns: 173, }, }, }, @@ -206,6 +269,7 @@ export const sessionViewIOEventsMock: ProcessEventResults = { message: 'hello world security', event: { action: 'text_output', + id: '1', }, process: { entity_id: '1', @@ -219,7 +283,15 @@ export const sessionViewIOEventsMock: ProcessEventResults = { total_bytes_captured: 1024, total_bytes_skipped: 0, bytes_skipped: [], - text: '\u001bkroot@staging-host:~\u001b\\\b\b\b\b\u001b[1P\b\b\b\b\u001b[1P\b\b\b\b\u001b[1P\b\b\b\b\b\b\b\b\b\n\u001bkroot@staging-host:~\u001b\\\b\u001b[K\b\u001b[K\b\u001b[K\n,\n22/05/26 09:24:09 rack-na/cl_md (md), Cluster ********\n[root@staging-host:~] vi -R /usr/local/bin/galera_traffic_start.sh\u0007\n22/05/26 09:25:32 rack-na/cl_md (md), Cluster ********\n[root@staging-host:~] vi -R /usr/local/bin/galera_traffic_start.sh.sh.sh.sho.shp.sh\n22/05/26 09:30:08 rack-na/cl_md (md), Cluster ********\n[root@staging-host:~] exi\u0007\u0007\u0007exitlogout\n,\u001bec2-user@staging-host:~\u001b\\\n\u001bec2-user@staging-host:~\u001b\\\n,\n22/05/26 09:24:01 rack-na/cl_md (md), Cluster ********\n[ec2-user@staging-host:~] sudo -i\n22/05/26 10:11:37 rack-na/cl_md (md), Cluster ********\n[ec2-user@staging-host:~] exitlogout\n\n', + text: '\u001bkroot@staging-host:~\u001b\\\b\b\b\b\u001b[1P\b\b\b\b\u001b[1P\b\b\b\b\u001b[1P\b\b\b\b\b\b\b\b\b\n\u001bkroot@staging-host:~\u001b\\\b\u001b[K\b\u001b[K\b\u001b[K\n,\n22/05/26 09:24:09 rack-na/cl_md (md), Cluster ********\n[root@staging-host:~] vi -R /usr/local/bin/script_one.sh\u0007\n22/05/26 09:25:32 rack-na/cl_md (md), Cluster ********\n[root@staging-host:~] vi -R /usr/local/bin/script_one.sh.sh.sh.sho.shp.sh\n22/05/26 09:30:08 rack-na/cl_md (md), Cluster ********\n[root@staging-host:~] exi\u0007\u0007\u0007exitlogout\n,\u001bec2-user@staging-host:~\u001b\\\n\u001bec2-user@staging-host:~\u001b\\\n,\n22/05/26 09:24:01 rack-na/cl_md (md), Cluster ********\n[ec2-user@staging-host:~] sudo -i\n22/05/26 10:11:37 rack-na/cl_md (md), Cluster ********\n[ec2-user@staging-host:~] exitlogout\n\n', + }, + tty: { + char_device: { + major: 4, + minor: 1, + }, + rows: 59, + columns: 173, }, }, }, diff --git a/x-pack/plugins/session_view/common/types/process_tree/index.ts b/x-pack/plugins/session_view/common/types/process_tree/index.ts index e620b654db16ff..a2b40347f1b5f6 100644 --- a/x-pack/plugins/session_view/common/types/process_tree/index.ts +++ b/x-pack/plugins/session_view/common/types/process_tree/index.ts @@ -60,16 +60,13 @@ export interface Teletype { major?: number; minor?: number; }; + rows?: number; + columns?: number; } -// used by tty_player component to split process.io.text into lines of IO export interface IOLine { - value?: string; - - // the following is only set client side for caching purposes - process_name?: string; - process_entity_id?: string; - process_entity_cursor?: string; + event: ProcessEvent; + value: string; } export interface IOFields { diff --git a/x-pack/plugins/session_view/public/components/session_view/hooks.ts b/x-pack/plugins/session_view/public/components/session_view/hooks.ts index 2d24305cc02d75..06a1e0125aea16 100644 --- a/x-pack/plugins/session_view/public/components/session_view/hooks.ts +++ b/x-pack/plugins/session_view/public/components/session_view/hooks.ts @@ -5,7 +5,7 @@ * 2.0. */ import { useEffect, useState, useMemo } from 'react'; -import { useQuery, useInfiniteQuery } from 'react-query'; +import { useQuery, useInfiniteQuery } from '@tanstack/react-query'; import { EuiSearchBarOnChangeArgs } from '@elastic/eui'; import { CoreStart } from '@kbn/core/public'; import { useKibana } from '@kbn/kibana-react-plugin/public'; diff --git a/x-pack/plugins/session_view/public/components/session_view/index.test.tsx b/x-pack/plugins/session_view/public/components/session_view/index.test.tsx index 26b5d9c3cc7f9a..215fa55747098f 100644 --- a/x-pack/plugins/session_view/public/components/session_view/index.test.tsx +++ b/x-pack/plugins/session_view/public/components/session_view/index.test.tsx @@ -23,8 +23,6 @@ describe('SessionView component', () => { let mockedContext: AppContextTestRender; let mockedApi: AppContextTestRender['coreStart']['http']['get']; - const waitForApiCall = () => waitFor(() => expect(mockedApi).toHaveBeenCalled()); - beforeEach(() => { mockedContext = createAppRootMockRenderer(); mockedApi = mockedContext.coreStart.http.get; @@ -47,10 +45,11 @@ describe('SessionView component', () => { // make the request wait mockedApi.mockReturnValue(new Promise((resolve) => (releaseApiResponse = resolve))); render(); - await waitForApiCall(); // see if loader is present - expect(renderResult.getByTestId('sectionLoading')).toBeTruthy(); + await waitFor(() => { + expect(renderResult.getByTestId('sectionLoading')).toBeTruthy(); + }); // release the request releaseApiResponse!(mockedApi); @@ -61,13 +60,15 @@ describe('SessionView component', () => { it('should show the Empty message', async () => { render(); - await waitForApiCall(); - expect(renderResult.getByTestId('sessionView:sessionViewProcessEventsEmpty')).toBeTruthy(); + await waitFor(() => { + expect( + renderResult.getByTestId('sessionView:sessionViewProcessEventsEmpty') + ).toBeTruthy(); + }); }); it('should not display the search bar', async () => { render(); - await waitForApiCall(); expect( renderResult.queryByTestId('sessionView:sessionViewProcessEventsSearch') ).toBeFalsy(); @@ -85,10 +86,11 @@ describe('SessionView component', () => { // make the request wait mockedApi.mockReturnValue(new Promise((resolve) => (releaseApiResponse = resolve))); render(); - await waitForApiCall(); // see if loader is present - expect(renderResult.getByTestId('sectionLoading')).toBeTruthy(); + await waitFor(() => { + expect(renderResult.getByTestId('sectionLoading')).toBeTruthy(); + }); // release the request releaseApiResponse!(mockedApi); @@ -99,20 +101,28 @@ describe('SessionView component', () => { it('should display the search bar', async () => { render(); - await waitForApiCall(); - expect(renderResult.getByTestId('sessionView:sessionViewProcessEventsSearch')).toBeTruthy(); + + await waitFor(() => { + expect( + renderResult.getByTestId('sessionView:sessionViewProcessEventsSearch') + ).toBeTruthy(); + }); }); it('should show items on the list, and auto selects session leader', async () => { render(); - await waitForApiCall(); - expect(renderResult.getAllByTestId('sessionView:processTreeNode')).toBeTruthy(); + await waitFor(() => { + expect(renderResult.getAllByTestId('sessionView:processTreeNode')).toBeTruthy(); + }); }); it('should toggle detail panel visibilty when detail button clicked', async () => { render(); - await waitForApiCall(); + + await waitFor(() => { + expect(renderResult.getByTestId('sessionView:sessionViewDetailPanelToggle')).toBeTruthy(); + }); userEvent.click(renderResult.getByTestId('sessionView:sessionViewDetailPanelToggle')); expect(renderResult.getByText('Process')).toBeTruthy(); @@ -122,7 +132,11 @@ describe('SessionView component', () => { it('should render session view options button and its options when clicked', async () => { render(); - await waitForApiCall(); + + await waitFor(() => { + expect(renderResult.getByTestId('sessionView:sessionViewOptionButton')).toBeTruthy(); + }); + userEvent.click(renderResult.getByTestId('sessionView:sessionViewOptionButton')); expect(renderResult.getByText('Display options')).toBeTruthy(); expect(renderResult.getByText('Timestamp')).toBeTruthy(); @@ -131,9 +145,10 @@ describe('SessionView component', () => { it('should show refresh button', async () => { render(); - await waitForApiCall(); - expect(renderResult.getAllByTestId('sessionView:sessionViewRefreshButton')).toBeTruthy(); + await waitFor(() => { + expect(renderResult.getAllByTestId('sessionView:sessionViewRefreshButton')).toBeTruthy(); + }); }); }); @@ -150,9 +165,10 @@ describe('SessionView component', () => { }); render(); - await waitForApiCall(); - expect(renderResult.queryByTestId('sessionView:TTYPlayerToggle')).toBeTruthy(); + await waitFor(() => { + expect(renderResult.queryByTestId('sessionView:TTYPlayerToggle')).toBeTruthy(); + }); }); it('should NOT show tty player button, if session has no output', async () => { @@ -171,9 +187,10 @@ describe('SessionView component', () => { }); render(); - await waitForApiCall(); - expect(renderResult.queryByTestId('sessionView:TTYPlayerToggle')).toBeFalsy(); + await waitFor(() => { + expect(renderResult.queryByTestId('sessionView:TTYPlayerToggle')).toBeFalsy(); + }); }); }); }); diff --git a/x-pack/plugins/session_view/public/components/session_view/index.tsx b/x-pack/plugins/session_view/public/components/session_view/index.tsx index e2d795283c7ce2..921a3f7ce8b9c4 100644 --- a/x-pack/plugins/session_view/public/components/session_view/index.tsx +++ b/x-pack/plugins/session_view/public/components/session_view/index.tsx @@ -133,8 +133,8 @@ export const SessionView = ({ } = useFetchSessionViewAlerts(sessionEntityId, investigatedAlertId); const handleRefresh = useCallback(() => { - refetch({ refetchPage: (page, index, allPages) => allPages.length - 1 === index }); - refetchAlerts({ refetchPage: (page, index, allPages) => allPages.length - 1 === index }); + refetch({ refetchPage: (_page, index, allPages) => allPages.length - 1 === index }); + refetchAlerts({ refetchPage: (_page, index, allPages) => allPages.length - 1 === index }); }, [refetch, refetchAlerts]); const alerts = useMemo(() => { diff --git a/x-pack/plugins/session_view/public/components/tty_player/hooks.test.tsx b/x-pack/plugins/session_view/public/components/tty_player/hooks.test.tsx index 23f81d7941439c..fb909518743859 100644 --- a/x-pack/plugins/session_view/public/components/tty_player/hooks.test.tsx +++ b/x-pack/plugins/session_view/public/components/tty_player/hooks.test.tsx @@ -8,7 +8,9 @@ import { renderHook, act } from '@testing-library/react-hooks'; import { sessionViewIOEventsMock } from '../../../common/mocks/responses/session_view_io_events.mock'; import { useIOLines, useXtermPlayer, XtermPlayerDeps } from './hooks'; import { ProcessEventsPage } from '../../../common/types/process_tree'; -import { DEFAULT_TTY_PLAYSPEED_MS } from '../../../common/constants'; +import { DEFAULT_TTY_FONT_SIZE, DEFAULT_TTY_PLAYSPEED_MS } from '../../../common/constants'; + +const VIM_LINE_START = 19; describe('TTYPlayer/hooks', () => { beforeAll(() => { @@ -66,10 +68,11 @@ describe('TTYPlayer/hooks', () => { initialProps = { ref: mockRef, isPlaying: false, + setIsPlaying: jest.fn(), lines, hasNextPage: false, fetchNextPage: () => null, - isFullscreen: false, + fontSize: DEFAULT_TTY_FONT_SIZE, }; }); @@ -88,7 +91,7 @@ describe('TTYPlayer/hooks', () => { expect(currentLine).toBe(0); act(() => { - seekToLine(17); // line where vim output starts + seekToLine(VIM_LINE_START); // line where vim output starts }); jest.advanceTimersByTime(100); @@ -102,14 +105,14 @@ describe('TTYPlayer/hooks', () => { }); act(() => { - xTermResult.current.seekToLine(17); // line where vim output starts + xTermResult.current.seekToLine(VIM_LINE_START); // line where vim output starts }); jest.advanceTimersByTime(100); const { terminal, currentLine } = xTermResult.current; - expect(currentLine).toBe(17); + expect(currentLine).toBe(VIM_LINE_START); expect(terminal.buffer.active.getLine(0)?.translateToString(true)).toBe('#!/bin/env bash'); }); @@ -152,7 +155,7 @@ describe('TTYPlayer/hooks', () => { act(() => { jest.advanceTimersByTime(DEFAULT_TTY_PLAYSPEED_MS * initialProps.lines.length + 100); }); - expect(result.current.currentLine).toBe(initialProps.lines.length); + expect(result.current.currentLine).toBe(initialProps.lines.length - 1); }); it('will allow a plain text search highlight on the last line printed', async () => { diff --git a/x-pack/plugins/session_view/public/components/tty_player/hooks.ts b/x-pack/plugins/session_view/public/components/tty_player/hooks.ts index a37f8899d0ed47..0138775199c6d0 100644 --- a/x-pack/plugins/session_view/public/components/tty_player/hooks.ts +++ b/x-pack/plugins/session_view/public/components/tty_player/hooks.ts @@ -6,13 +6,16 @@ */ import { Terminal } from 'xterm'; import 'xterm/css/xterm.css'; -import { FitAddon } from 'xterm-addon-fit'; import { useMemo, useState, useEffect, useCallback } from 'react'; -import { useInfiniteQuery } from 'react-query'; +import { useInfiniteQuery } from '@tanstack/react-query'; import { CoreStart } from '@kbn/core/public'; import { useKibana } from '@kbn/kibana-react-plugin/public'; import { SearchAddon } from './xterm_search'; import { useEuiTheme } from '../../hooks'; + +// eslint-disable-next-line @kbn/imports/no_boundary_crossing +import { sessionViewIOEventsMock } from '../../../common/mocks/responses/session_view_io_events.mock'; + import { IOLine, ProcessEvent, @@ -24,8 +27,12 @@ import { IO_EVENTS_PER_PAGE, QUERY_KEY_IO_EVENTS, DEFAULT_TTY_PLAYSPEED_MS, + DEFAULT_TTY_FONT_SIZE, + TTY_LINE_SPLITTER_REGEX, } from '../../../common/constants'; +const MOCK_DEBUG = false; // This code will be removed once we have an agent to test with. + export const useFetchIOEvents = (sessionEntityId: string) => { const { http } = useKibana().services; const cachingKeys = useMemo(() => [QUERY_KEY_IO_EVENTS, sessionEntityId], [sessionEntityId]); @@ -41,13 +48,18 @@ export const useFetchIOEvents = (sessionEntityId: string) => { }, }); + if (MOCK_DEBUG) { + res.events = sessionViewIOEventsMock.events; + res.total = res.events?.length || 0; + } + const events = res.events?.map((event: any) => event._source as ProcessEvent) ?? []; return { events, cursor, total: res.total }; }, { getNextPageParam: (lastPage) => { - if (lastPage.events.length >= IO_EVENTS_PER_PAGE) { + if (!MOCK_DEBUG && lastPage.events.length >= IO_EVENTS_PER_PAGE) { return { cursor: lastPage.events[lastPage.events.length - 1]['@timestamp'], }; @@ -77,9 +89,21 @@ export const useIOLines = (pages: ProcessEventsPage[] | undefined) => { return pages.reduce((previous, current) => { if (current.events) { current.events.forEach((event) => { - if (event?.process?.io?.text) { - const data: IOLine[] = event.process.io.text.split(/\n\r?/).map((line) => { + const { process } = event; + if (process?.io?.text !== undefined) { + const splitLines = process.io.text.split(TTY_LINE_SPLITTER_REGEX); + const combinedLines = [splitLines[0]]; + + // delimiters e.g \r\n or cursor movements are merged with their line text + // we start on an odd number so that cursor movements happen at the start of each line + // this is needed for the search to work accurately + for (let i = 1; i < splitLines.length - 1; i = i + 2) { + combinedLines.push(splitLines[i] + splitLines[i + 1]); + } + + const data: IOLine[] = combinedLines.map((line) => { return { + event, // pointer to the event so it's easy to look up other details for the line value: line, }; }); @@ -99,85 +123,94 @@ export const useIOLines = (pages: ProcessEventsPage[] | undefined) => { export interface XtermPlayerDeps { ref: React.RefObject; isPlaying: boolean; + setIsPlaying(value: boolean): void; lines: IOLine[]; + fontSize: number; hasNextPage?: boolean; fetchNextPage?: () => void; - isFullscreen?: boolean; } export const useXtermPlayer = ({ ref, isPlaying, + setIsPlaying, lines, + fontSize, hasNextPage, fetchNextPage, - isFullscreen, }: XtermPlayerDeps) => { const { euiTheme } = useEuiTheme(); const { font, colors } = euiTheme; const [currentLine, setCurrentLine] = useState(0); - const [userSeeked, setUserSeeked] = useState(false); const [playSpeed] = useState(DEFAULT_TTY_PLAYSPEED_MS); // potentially configurable + const tty = lines?.[currentLine]?.event.process?.tty; - const [terminal, fitAddon, searchAddon] = useMemo(() => { + const [terminal, searchAddon] = useMemo(() => { const term = new Terminal({ theme: { - background: 'rgba(0,0,0,0)', selection: colors.warning, }, fontFamily: font.familyCode, - fontSize: 11, - allowTransparency: true, + fontSize: DEFAULT_TTY_FONT_SIZE, + scrollback: 0, + convertEol: true, }); - const fitInstance = new FitAddon(); const searchInstance = new SearchAddon(); - - term.loadAddon(fitInstance); term.loadAddon(searchInstance); - return [term, fitInstance, searchInstance]; - }, [colors, font]); + return [term, searchInstance]; + }, [font, colors]); useEffect(() => { - if (ref.current) { + if (ref.current && !terminal.element) { terminal.open(ref.current); } }, [terminal, ref]); - useEffect(() => { - // isFullscreen check is there just to avoid the necessary "unnecessary" react-hook dep - // When isFullscreen changes, e.g goes from false to true and vice versa, we need to call fit. - if (isFullscreen !== undefined) { - fitAddon.fit(); - } - }, [isFullscreen, fitAddon]); - const render = useCallback( - (lineNumber: number) => { + (lineNumber: number, clear: boolean) => { if (lines.length === 0) { return; } let linesToPrint; - if (userSeeked) { - linesToPrint = lines.slice(0, lineNumber); + if (clear) { + linesToPrint = lines.slice(0, lineNumber + 1); + terminal.reset(); terminal.clear(); - setUserSeeked(false); } else { linesToPrint = [lines[lineNumber]]; } linesToPrint.forEach((line, index) => { if (line?.value !== undefined) { - terminal.writeln(line.value); + terminal.write(line.value); } }); }, - [terminal, lines, userSeeked] + [terminal, lines] ); + useEffect(() => { + const fontChanged = terminal.getOption('fontSize') !== fontSize; + const ttyChanged = tty && (terminal.rows !== tty?.rows || terminal.cols !== tty?.columns); + + if (fontChanged) { + terminal.setOption('fontSize', fontSize); + } + + if (tty?.rows && tty?.columns && ttyChanged) { + terminal.resize(tty.columns, tty.rows); + } + + if (fontChanged || ttyChanged) { + // clear and rerender + render(currentLine, true); + } + }, [currentLine, fontSize, terminal, render, tty]); + useEffect(() => { if (isPlaying) { const timer = setTimeout(() => { @@ -185,29 +218,32 @@ export const useXtermPlayer = ({ return; } - if (currentLine < lines.length) { + if (currentLine < lines.length - 1) { setCurrentLine(currentLine + 1); } + + render(currentLine, false); + + if (hasNextPage && fetchNextPage && currentLine === lines.length - 1) { + fetchNextPage(); + } }, playSpeed); return () => { - clearInterval(timer); + clearTimeout(timer); }; } - }, [lines, currentLine, isPlaying, playSpeed]); + }, [lines, currentLine, isPlaying, playSpeed, render, hasNextPage, fetchNextPage]); - useEffect(() => { - render(currentLine); - - if (hasNextPage && fetchNextPage && currentLine === lines.length - 1) { - fetchNextPage(); - } - }, [fetchNextPage, currentLine, lines, render, hasNextPage]); + const seekToLine = useCallback( + (index) => { + setCurrentLine(index); + setIsPlaying(false); - const seekToLine = useCallback((line) => { - setUserSeeked(true); - setCurrentLine(line); - }, []); + render(index, true); + }, + [setIsPlaying, render] + ); const search = useCallback( (query: string, startCol: number) => { @@ -216,15 +252,10 @@ export const useXtermPlayer = ({ [searchAddon] ); - const fit = useCallback(() => { - fitAddon.fit(); - }, [fitAddon]); - return { terminal, currentLine, seekToLine, search, - fit, }; }; diff --git a/x-pack/plugins/session_view/public/components/tty_player/index.tsx b/x-pack/plugins/session_view/public/components/tty_player/index.tsx index 48dbf82441e427..7d3656d8ba7b7f 100644 --- a/x-pack/plugins/session_view/public/components/tty_player/index.tsx +++ b/x-pack/plugins/session_view/public/components/tty_player/index.tsx @@ -7,6 +7,7 @@ import React, { useRef, useState, useCallback, ChangeEvent, MouseEvent } from 'react'; import { EuiPanel, EuiRange, EuiFlexGroup, EuiFlexItem, EuiButtonIcon } from '@elastic/eui'; import { TTYSearchBar } from '../tty_search_bar'; +import { TTYTextSizer } from '../tty_text_sizer'; import { useStyles } from './styles'; import { useFetchIOEvents, useIOLines, useXtermPlayer } from './hooks'; @@ -16,22 +17,31 @@ export interface TTYPlayerDeps { isFullscreen: boolean; } +const DEFAULT_FONT_SIZE = 11; + export const TTYPlayer = ({ sessionEntityId, onClose, isFullscreen }: TTYPlayerDeps) => { - const styles = useStyles(); - const ref = useRef(null); + const ref = useRef(null); + const scrollRef = useRef(null); const { data, fetchNextPage, hasNextPage } = useFetchIOEvents(sessionEntityId); const lines = useIOLines(data?.pages); + + const [fontSize, setFontSize] = useState(DEFAULT_FONT_SIZE); const [isPlaying, setIsPlaying] = useState(false); + const { search, currentLine, seekToLine } = useXtermPlayer({ ref, isPlaying, + setIsPlaying, lines, + fontSize, hasNextPage, fetchNextPage, - isFullscreen, }); + const tty = lines?.[currentLine]?.event?.process?.tty; + const styles = useStyles(tty); + const onLineChange = useCallback( (event: ChangeEvent | MouseEvent) => { const line = parseInt((event?.target as HTMLInputElement).value || '0', 10); @@ -65,7 +75,10 @@ export const TTYPlayer = ({ sessionEntityId, onClose, isFullscreen }: TTYPlayerD -
+ +
+
+
{/* the following will be replaced by a new component */} + + +
diff --git a/x-pack/plugins/session_view/public/components/tty_player/styles.ts b/x-pack/plugins/session_view/public/components/tty_player/styles.ts index c4061c8a64dce6..e1d18e30750273 100644 --- a/x-pack/plugins/session_view/public/components/tty_player/styles.ts +++ b/x-pack/plugins/session_view/public/components/tty_player/styles.ts @@ -7,15 +7,14 @@ import { useMemo } from 'react'; import { CSSObject, css } from '@emotion/react'; -import { transparentize, useEuiScrollBar } from '@elastic/eui'; +import { transparentize } from '@elastic/eui'; import { useEuiTheme } from '../../hooks'; +import { Teletype } from '../../../common/types/process_tree'; -export const useStyles = () => { +export const useStyles = (tty?: Teletype) => { const { euiTheme } = useEuiTheme(); - const euiScrollBar = useEuiScrollBar(); - const cached = useMemo(() => { - const { size, colors, border } = euiTheme; + const { size, font, colors, border } = euiTheme; const container: CSSObject = { position: 'absolute', @@ -23,6 +22,7 @@ export const useStyles = () => { width: '100%', height: '100%', overflow: 'hidden', + zIndex: 10, borderRadius: size.s, backgroundColor: colors.ink, '.euiRangeLevel--warning': { @@ -36,20 +36,47 @@ export const useStyles = () => { }, }; + const windowBoundsColor = transparentize(colors.ghost, 0.6); + const terminal: CSSObject = { + minHeight: '100%', + '.xterm': css` + display: inline-block; + `, + '.xterm-screen': css` + overflow-y: visible; + border: ${border.width.thin} dotted ${windowBoundsColor}; + border-top: 0; + border-left: 0; + box-sizing: content-box; + `, + }; + + if (tty?.rows) { + terminal['.xterm-screen:after'] = css` + position: absolute; + right: ${size.s}; + top: ${size.s}; + content: '${tty?.columns}x${tty?.rows}'; + color: ${windowBoundsColor}; + font-family: ${font.familyCode}; + font-size: ${size.m}; + `; + } + + const scrollPane: CSSObject = { width: '100%', height: 'calc(100% - 142px)', - '.xterm-viewport': css` - ${euiScrollBar} - `, border: border.thin, + overflow: 'auto', }; return { container, terminal, + scrollPane, }; - }, [euiScrollBar, euiTheme]); + }, [tty, euiTheme]); return cached; }; diff --git a/x-pack/plugins/session_view/public/components/tty_player/translations.ts b/x-pack/plugins/session_view/public/components/tty_player/translations.ts new file mode 100644 index 00000000000000..244a5a355b0ec7 --- /dev/null +++ b/x-pack/plugins/session_view/public/components/tty_player/translations.ts @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { i18n } from '@kbn/i18n'; + +export const BETA = i18n.translate('xpack.sessionView.beta', { + defaultMessage: 'Beta', +}); + +export const REFRESH_SESSION = i18n.translate('xpack.sessionView.refreshSession', { + defaultMessage: 'Refresh session', +}); + +export const OPEN_TTY_PLAYER = i18n.translate('xpack.sessionView.openTTYPlayer', { + defaultMessage: 'Open TTY player', +}); diff --git a/x-pack/plugins/session_view/public/components/tty_player/xterm_search.ts b/x-pack/plugins/session_view/public/components/tty_player/xterm_search.ts index 258920319676c9..3c430d691e3f7c 100644 --- a/x-pack/plugins/session_view/public/components/tty_player/xterm_search.ts +++ b/x-pack/plugins/session_view/public/components/tty_player/xterm_search.ts @@ -94,7 +94,7 @@ export class SearchAddon implements ITerminalAddon { } if (searchOptions?.lastLineOnly) { - startRow = this._terminal.buffer.active.cursorY - 1; + startRow = this._terminal.buffer.active.cursorY; startCol = searchOptions?.startCol || 0; } @@ -176,10 +176,9 @@ export class SearchAddon implements ITerminalAddon { // Start from selection start if there is a selection startRow = currentSelection.startRow; startCol = currentSelection.startColumn; - } - - if (searchOptions?.lastLineOnly) { + } else if (searchOptions?.lastLineOnly) { startRow = this._terminal.buffer.active.cursorY - 1; + startCol = this._terminal.cols; } this._initLinesCache(); diff --git a/x-pack/plugins/session_view/public/components/tty_search_bar/index.test.tsx b/x-pack/plugins/session_view/public/components/tty_search_bar/index.test.tsx index 4545acf1a45783..77e9c4576c5653 100644 --- a/x-pack/plugins/session_view/public/components/tty_search_bar/index.test.tsx +++ b/x-pack/plugins/session_view/public/components/tty_search_bar/index.test.tsx @@ -56,7 +56,9 @@ describe('TTYSearchBar component', () => { // there is a slight delay in the seek in xtermjs, so we wait 100ms before trying to highlight a result. await new Promise((r) => setTimeout(r, 100)); - expect(props.xTermSearchFn).toHaveBeenCalledTimes(1); + expect(props.xTermSearchFn).toHaveBeenCalledTimes(2); + expect(props.xTermSearchFn).toHaveBeenNthCalledWith(1, '', 0); + expect(props.xTermSearchFn).toHaveBeenNthCalledWith(2, '-h', 6); }); it('calls seekToline and xTermSearchFn when currentMatch changes', async () => { @@ -76,12 +78,13 @@ describe('TTYSearchBar component', () => { // two calls, first instance -h is at line 22, 2nd at line 42 expect(props.seekToLine).toHaveBeenCalledTimes(2); - expect(props.seekToLine).toHaveBeenNthCalledWith(1, 22); - expect(props.seekToLine).toHaveBeenNthCalledWith(2, 42); + expect(props.seekToLine).toHaveBeenNthCalledWith(1, 24); + expect(props.seekToLine).toHaveBeenNthCalledWith(2, 94); - expect(props.xTermSearchFn).toHaveBeenCalledTimes(2); - expect(props.xTermSearchFn).toHaveBeenNthCalledWith(1, '-h', 6); - expect(props.xTermSearchFn).toHaveBeenNthCalledWith(2, '-h', 13); + expect(props.xTermSearchFn).toHaveBeenCalledTimes(3); + expect(props.xTermSearchFn).toHaveBeenNthCalledWith(1, '', 0); + expect(props.xTermSearchFn).toHaveBeenNthCalledWith(2, '-h', 6); + expect(props.xTermSearchFn).toHaveBeenNthCalledWith(3, '-h', 13); }); it('calls xTermSearchFn with empty query when search is cleared', async () => { @@ -97,6 +100,6 @@ describe('TTYSearchBar component', () => { userEvent.click(renderResult.getByTestId('clearSearchButton')); await new Promise((r) => setTimeout(r, 100)); - expect(props.xTermSearchFn).toHaveBeenNthCalledWith(2, '', 0); + expect(props.xTermSearchFn).toHaveBeenNthCalledWith(3, '', 0); }); }); diff --git a/x-pack/plugins/session_view/public/components/tty_search_bar/index.tsx b/x-pack/plugins/session_view/public/components/tty_search_bar/index.tsx index af60bdf664f9d8..e5081a217dec13 100644 --- a/x-pack/plugins/session_view/public/components/tty_search_bar/index.tsx +++ b/x-pack/plugins/session_view/public/components/tty_search_bar/index.tsx @@ -4,9 +4,10 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import React, { useEffect, useMemo, useState, useCallback } from 'react'; +import React, { useMemo, useState, useCallback } from 'react'; import { SessionViewSearchBar } from '../session_view_search_bar'; import { IOLine } from '../../../common/types/process_tree'; +import { TTY_STRIP_CONTROL_CODES_REGEX } from '../../../common/constants'; interface SearchResult { line: IOLine; @@ -24,50 +25,71 @@ export const TTYSearchBar = ({ lines, seekToLine, xTermSearchFn }: TTYSearchBarD const [currentMatch, setCurrentMatch] = useState(null); const [searchQuery, setSearchQuery] = useState(''); - useEffect(() => { - if (currentMatch) { - const goToLine = lines.indexOf(currentMatch.line); - seekToLine(goToLine); - } + const jumpToMatch = useCallback( + (match) => { + if (match) { + const goToLine = lines.indexOf(match.line); + seekToLine(goToLine); + } - const timeout = setTimeout(() => { - return xTermSearchFn(searchQuery, currentMatch?.index || 0); - }, 100); + const timeout = setTimeout(() => { + return xTermSearchFn(searchQuery, match?.index || 0); + }, 100); - return () => { - clearTimeout(timeout); - }; - }, [currentMatch, searchQuery, lines, xTermSearchFn, seekToLine]); + return () => { + clearTimeout(timeout); + }; + }, + [lines, seekToLine, xTermSearchFn, searchQuery] + ); const searchResults = useMemo(() => { - if (searchQuery) { - const matches: SearchResult[] = []; + const matches: SearchResult[] = []; + if (searchQuery) { lines.reduce((previous: SearchResult[], current: IOLine) => { if (current.value) { + // check for cursor movement at the start of the line + const cursorMovement = current.value.match(/^\x1b\[\d+;(\d+)(H|d)/); const regex = new RegExp(searchQuery.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'ig'); - const lineMatches = current.value.matchAll(regex); + const lineMatches = current.value + .replace(TTY_STRIP_CONTROL_CODES_REGEX, '') + .replace(/^\r?\n/, '') + .matchAll(regex); + if (lineMatches) { for (const match of lineMatches) { - previous.push({ line: current, match: match[0], index: match.index || 0 }); + let matchOffset = 0; + + if (cursorMovement) { + // the column position 1 based e.g \x1b[39;5H means row 39 column 5 + matchOffset = parseInt(cursorMovement[1], 10) - 3; + } + + previous.push({ + line: current, + match: match[0], + index: matchOffset + (match.index || 0), + }); } } } return previous; }, matches); + } - if (matches.length > 0) { - setCurrentMatch(matches[0]); - } else { - setCurrentMatch(null); - } - - return matches; + if (matches.length > 0) { + const firstMatch = matches[0]; + setCurrentMatch(firstMatch); + jumpToMatch(firstMatch); + } else { + setCurrentMatch(null); + xTermSearchFn('', 0); } - return []; - }, [searchQuery, lines]); + return matches; + }, [searchQuery, lines, jumpToMatch, xTermSearchFn]); const onSearch = useCallback((query) => { setSearchQuery(query); @@ -80,9 +102,10 @@ export const TTYSearchBar = ({ lines, seekToLine, xTermSearchFn }: TTYSearchBarD if (match && currentMatch !== match) { setCurrentMatch(match); + jumpToMatch(match); } }, - [currentMatch, searchResults] + [jumpToMatch, currentMatch, searchResults] ); return ( diff --git a/x-pack/plugins/session_view/public/components/tty_text_sizer/index.test.tsx b/x-pack/plugins/session_view/public/components/tty_text_sizer/index.test.tsx new file mode 100644 index 00000000000000..ec9e8ffd3cab25 --- /dev/null +++ b/x-pack/plugins/session_view/public/components/tty_text_sizer/index.test.tsx @@ -0,0 +1,76 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import React from 'react'; +import userEvent from '@testing-library/user-event'; +import { AppContextTestRender, createAppRootMockRenderer } from '../../test'; +import { DEFAULT_TTY_FONT_SIZE } from '../../../common/constants'; +import { TTYTextSizer, TTYTextSizerDeps } from '.'; + +describe('TTYTextSizer component', () => { + let render: () => ReturnType; + let renderResult: ReturnType; + let mockedContext: AppContextTestRender; + let props: TTYTextSizerDeps; + + beforeEach(() => { + mockedContext = createAppRootMockRenderer(); + + props = { + tty: { + rows: 24, + columns: 80, + }, + containerHeight: 200, + fontSize: DEFAULT_TTY_FONT_SIZE, + onFontSizeChanged: jest.fn(), + }; + }); + + it('mounts and renders the text sizer controls', async () => { + renderResult = mockedContext.render(); + expect(renderResult.queryByTestId('sessionView:TTYTextSizer')).toBeTruthy(); + }); + + it('emits a fontSize which will fit the container when ZoomFit clicked', async () => { + renderResult = mockedContext.render(); + + const zoomFitBtn = renderResult.queryByTestId('sessionView:TTYZoomFit'); + + if (zoomFitBtn) { + userEvent.click(zoomFitBtn); + } + + expect(props.onFontSizeChanged).toHaveBeenCalledTimes(1); + expect(props.onFontSizeChanged).toHaveBeenCalledWith(6.41025641025641); + }); + + it('emits a larger fontSize when zoom in clicked', async () => { + renderResult = mockedContext.render(); + + const zoomInBtn = renderResult.queryByTestId('sessionView:TTYZoomIn'); + + if (zoomInBtn) { + userEvent.click(zoomInBtn); + } + + expect(props.onFontSizeChanged).toHaveBeenCalledTimes(1); + expect(props.onFontSizeChanged).toHaveBeenCalledWith(DEFAULT_TTY_FONT_SIZE + 1); + }); + + it('emits a smaller fontSize when zoom out clicked', async () => { + renderResult = mockedContext.render(); + + const zoomOutBtn = renderResult.queryByTestId('sessionView:TTYZoomOut'); + + if (zoomOutBtn) { + userEvent.click(zoomOutBtn); + } + + expect(props.onFontSizeChanged).toHaveBeenCalledTimes(1); + expect(props.onFontSizeChanged).toHaveBeenCalledWith(DEFAULT_TTY_FONT_SIZE - 1); + }); +}); diff --git a/x-pack/plugins/session_view/public/components/tty_text_sizer/index.tsx b/x-pack/plugins/session_view/public/components/tty_text_sizer/index.tsx new file mode 100644 index 00000000000000..463dbbbf80f698 --- /dev/null +++ b/x-pack/plugins/session_view/public/components/tty_text_sizer/index.tsx @@ -0,0 +1,89 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import React, { useCallback, useMemo } from 'react'; +import { EuiButtonIcon, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; +import { Teletype } from '../../../common/types/process_tree'; +import { DEFAULT_TTY_FONT_SIZE } from '../../../common/constants'; +import { ZOOM_IN, ZOOM_FIT, ZOOM_OUT } from './translations'; + +export interface TTYTextSizerDeps { + tty?: Teletype; + containerHeight: number; + fontSize: number; + onFontSizeChanged(newSize: number): void; +} + +const LINE_HEIGHT_SCALE_RATIO = 1.3; +const MINIMUM_FONT_SIZE = 2; +const MAXIMUM_FONT_SIZE = 20; + +export const TTYTextSizer = ({ + tty, + containerHeight, + fontSize, + onFontSizeChanged, +}: TTYTextSizerDeps) => { + const onFitFontSize = useMemo(() => { + if (tty?.rows && containerHeight) { + const lineHeight = DEFAULT_TTY_FONT_SIZE * LINE_HEIGHT_SCALE_RATIO; + const desiredHeight = tty.rows * lineHeight; + return DEFAULT_TTY_FONT_SIZE * (containerHeight / desiredHeight); + } + + return DEFAULT_TTY_FONT_SIZE; + }, [containerHeight, tty?.rows]); + + const onFit = useCallback(() => { + if (fontSize === onFitFontSize || onFitFontSize > DEFAULT_TTY_FONT_SIZE) { + onFontSizeChanged(DEFAULT_TTY_FONT_SIZE); + } else { + onFontSizeChanged(onFitFontSize); + } + }, [fontSize, onFontSizeChanged, onFitFontSize]); + + const onZoomOut = useCallback(() => { + onFontSizeChanged(Math.max(MINIMUM_FONT_SIZE, fontSize - 1)); + }, [fontSize, onFontSizeChanged]); + + const onZoomIn = useCallback(() => { + onFontSizeChanged(Math.min(MAXIMUM_FONT_SIZE, fontSize + 1)); + }, [fontSize, onFontSizeChanged]); + + return ( + + + + + + + + + + + + ); +}; diff --git a/x-pack/plugins/session_view/public/components/tty_text_sizer/translations.ts b/x-pack/plugins/session_view/public/components/tty_text_sizer/translations.ts new file mode 100644 index 00000000000000..0bec7775d43c50 --- /dev/null +++ b/x-pack/plugins/session_view/public/components/tty_text_sizer/translations.ts @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { i18n } from '@kbn/i18n'; + +export const ZOOM_IN = i18n.translate('xpack.sessionView.zoomIn', { + defaultMessage: 'Zoom in', +}); + +export const ZOOM_FIT = i18n.translate('xpack.sessionView.zoomFit', { + defaultMessage: 'Zoom fit', +}); + +export const ZOOM_OUT = i18n.translate('xpack.sessionView.zoomOut', { + defaultMessage: 'Zoom out', +}); diff --git a/x-pack/plugins/session_view/public/methods/index.tsx b/x-pack/plugins/session_view/public/methods/index.tsx index 3654e296e74129..b8a581ea3ba950 100644 --- a/x-pack/plugins/session_view/public/methods/index.tsx +++ b/x-pack/plugins/session_view/public/methods/index.tsx @@ -7,7 +7,7 @@ import React, { lazy, Suspense } from 'react'; import { EuiLoadingSpinner } from '@elastic/eui'; -import { QueryClient, QueryClientProvider } from 'react-query'; +import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { SessionViewDeps } from '../types'; // Initializing react-query diff --git a/x-pack/plugins/session_view/public/test/index.tsx b/x-pack/plugins/session_view/public/test/index.tsx index 6174925b6003c4..244560d366ac4b 100644 --- a/x-pack/plugins/session_view/public/test/index.tsx +++ b/x-pack/plugins/session_view/public/test/index.tsx @@ -8,7 +8,7 @@ import React, { memo, ReactNode, useMemo } from 'react'; import { createMemoryHistory, MemoryHistory } from 'history'; import { render as reactRender, RenderOptions, RenderResult } from '@testing-library/react'; -import { QueryClient, QueryClientProvider, setLogger } from 'react-query'; +import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { Router } from 'react-router-dom'; import { History } from 'history'; import useObservable from 'react-use/lib/useObservable'; @@ -20,15 +20,6 @@ import { EuiThemeProvider } from '@kbn/kibana-react-plugin/common'; type UiRender = (ui: React.ReactElement, options?: RenderOptions) => RenderResult; -// hide react-query output in console -setLogger({ - error: () => {}, - // eslint-disable-next-line no-console - log: console.log, - // eslint-disable-next-line no-console - warn: console.warn, -}); - /** * Mocked app root context renderer */ @@ -113,6 +104,14 @@ export const createAppRootMockRenderer = (): AppContextTestRender => { cacheTime: Infinity, }, }, + // hide react-query output in console + logger: { + error: () => {}, + // eslint-disable-next-line no-console + log: console.log, + // eslint-disable-next-line no-console + warn: console.warn, + }, }); const AppWrapper: React.FC<{ children: React.ReactElement }> = ({ children }) => ( diff --git a/x-pack/plugins/stack_alerts/common/build_sorted_events_query.ts b/x-pack/plugins/stack_alerts/common/build_sorted_events_query.ts index de9e2a32e5c27d..480bbd7e64e48b 100644 --- a/x-pack/plugins/stack_alerts/common/build_sorted_events_query.ts +++ b/x-pack/plugins/stack_alerts/common/build_sorted_events_query.ts @@ -21,6 +21,8 @@ export interface BuildSortedEventsQuery extends BuildSortedEventsQueryOpts { sortOrder?: 'asc' | 'desc'; searchAfterSortId: string | number | undefined; timeField: string; + fields?: string[]; + runtime_mappings?: unknown; } export const buildSortedEventsQuery = ({ @@ -35,6 +37,9 @@ export const buildSortedEventsQuery = ({ timeField, // eslint-disable-next-line @typescript-eslint/naming-convention track_total_hits, + fields, + // eslint-disable-next-line @typescript-eslint/naming-convention + runtime_mappings, }: BuildSortedEventsQuery): ESSearchRequest => { const sortField = timeField; const docFields = [timeField].map((tstamp) => ({ @@ -82,6 +87,8 @@ export const buildSortedEventsQuery = ({ }, ], }, + ...(runtime_mappings ? { runtime_mappings } : {}), + ...(fields ? { fields } : {}), }; if (searchAfterSortId) { diff --git a/x-pack/plugins/stack_alerts/server/alert_types/es_query/lib/fetch_es_query.ts b/x-pack/plugins/stack_alerts/server/alert_types/es_query/lib/fetch_es_query.ts index 97acd154166892..6a954a8efb3963 100644 --- a/x-pack/plugins/stack_alerts/server/alert_types/es_query/lib/fetch_es_query.ts +++ b/x-pack/plugins/stack_alerts/server/alert_types/es_query/lib/fetch_es_query.ts @@ -26,13 +26,18 @@ export async function fetchEsQuery( ) { const { scopedClusterClient, logger } = services; const esClient = scopedClusterClient.asCurrentUser; - const { parsedQuery, dateStart, dateEnd } = getSearchParams(params); + const { + // eslint-disable-next-line @typescript-eslint/naming-convention + parsedQuery: { query, fields, runtime_mappings }, + dateStart, + dateEnd, + } = getSearchParams(params); const filter = timestamp ? { bool: { filter: [ - parsedQuery.query, + query, { bool: { must_not: [ @@ -56,9 +61,9 @@ export async function fetchEsQuery( ], }, } - : parsedQuery.query; + : query; - const query = buildSortedEventsQuery({ + const sortedQuery = buildSortedEventsQuery({ index: params.index, from: dateStart, to: dateEnd, @@ -68,11 +73,15 @@ export async function fetchEsQuery( searchAfterSortId: undefined, timeField: params.timeField, track_total_hits: true, + fields, + runtime_mappings, }); - logger.debug(`es query rule ${ES_QUERY_ID}:${ruleId} "${name}" query - ${JSON.stringify(query)}`); + logger.debug( + `es query rule ${ES_QUERY_ID}:${ruleId} "${name}" query - ${JSON.stringify(sortedQuery)}` + ); - const { body: searchResult } = await esClient.search(query, { meta: true }); + const { body: searchResult } = await esClient.search(sortedQuery, { meta: true }); logger.debug( ` es query rule ${ES_QUERY_ID}:${ruleId} "${name}" result - ${JSON.stringify(searchResult)}` diff --git a/x-pack/plugins/synthetics/common/constants/monitor_defaults.ts b/x-pack/plugins/synthetics/common/constants/monitor_defaults.ts index bf5f56b81bd701..70b494a42f1210 100644 --- a/x-pack/plugins/synthetics/common/constants/monitor_defaults.ts +++ b/x-pack/plugins/synthetics/common/constants/monitor_defaults.ts @@ -9,6 +9,7 @@ import { BrowserSimpleFields, CommonFields, DataStream, + FormMonitorType, HTTPAdvancedFields, HTTPMethod, HTTPSimpleFields, @@ -31,6 +32,7 @@ export const DEFAULT_NAMESPACE_STRING = 'default'; export const DEFAULT_COMMON_FIELDS: CommonFields = { [ConfigKey.MONITOR_TYPE]: DataStream.HTTP, + [ConfigKey.FORM_MONITOR_TYPE]: FormMonitorType.MULTISTEP, [ConfigKey.ENABLED]: true, [ConfigKey.SCHEDULE]: { number: '3', @@ -85,6 +87,7 @@ export const DEFAULT_BROWSER_SIMPLE_FIELDS: BrowserSimpleFields = { [ConfigKey.SOURCE_ZIP_PASSWORD]: '', [ConfigKey.SOURCE_ZIP_FOLDER]: '', [ConfigKey.SOURCE_ZIP_PROXY_URL]: '', + [ConfigKey.TEXT_ASSERTION]: '', [ConfigKey.ZIP_URL_TLS_CERTIFICATE_AUTHORITIES]: undefined, [ConfigKey.ZIP_URL_TLS_CERTIFICATE]: undefined, [ConfigKey.ZIP_URL_TLS_KEY]: undefined, @@ -92,6 +95,7 @@ export const DEFAULT_BROWSER_SIMPLE_FIELDS: BrowserSimpleFields = { [ConfigKey.ZIP_URL_TLS_VERIFICATION_MODE]: undefined, [ConfigKey.ZIP_URL_TLS_VERSION]: undefined, [ConfigKey.URLS]: '', + [ConfigKey.FORM_MONITOR_TYPE]: FormMonitorType.MULTISTEP, }; export const DEFAULT_HTTP_SIMPLE_FIELDS: HTTPSimpleFields = { @@ -102,6 +106,7 @@ export const DEFAULT_HTTP_SIMPLE_FIELDS: HTTPSimpleFields = { [ConfigKey.URLS]: '', [ConfigKey.MAX_REDIRECTS]: '0', [ConfigKey.MONITOR_TYPE]: DataStream.HTTP, + [ConfigKey.FORM_MONITOR_TYPE]: FormMonitorType.HTTP, }; export const DEFAULT_HTTP_ADVANCED_FIELDS: HTTPAdvancedFields = { @@ -127,6 +132,7 @@ export const DEFAULT_ICMP_SIMPLE_FIELDS: ICMPSimpleFields = { [ConfigKey.HOSTS]: '', [ConfigKey.MONITOR_TYPE]: DataStream.ICMP, [ConfigKey.WAIT]: '1', + [ConfigKey.FORM_MONITOR_TYPE]: FormMonitorType.ICMP, }; export const DEFAULT_TCP_SIMPLE_FIELDS: TCPSimpleFields = { @@ -136,6 +142,7 @@ export const DEFAULT_TCP_SIMPLE_FIELDS: TCPSimpleFields = { }, [ConfigKey.HOSTS]: '', [ConfigKey.MONITOR_TYPE]: DataStream.TCP, + [ConfigKey.FORM_MONITOR_TYPE]: FormMonitorType.TCP, }; export const DEFAULT_TCP_ADVANCED_FIELDS: TCPAdvancedFields = { @@ -165,7 +172,9 @@ export const DEFAULT_FIELDS: MonitorDefaults = { ...DEFAULT_TCP_ADVANCED_FIELDS, ...DEFAULT_TLS_FIELDS, }, - [DataStream.ICMP]: DEFAULT_ICMP_SIMPLE_FIELDS, + [DataStream.ICMP]: { + ...DEFAULT_ICMP_SIMPLE_FIELDS, + }, [DataStream.BROWSER]: { ...DEFAULT_BROWSER_SIMPLE_FIELDS, ...DEFAULT_BROWSER_ADVANCED_FIELDS, diff --git a/x-pack/plugins/synthetics/common/constants/monitor_management.ts b/x-pack/plugins/synthetics/common/constants/monitor_management.ts index 598e985d3c3b06..d613d234fc3c17 100644 --- a/x-pack/plugins/synthetics/common/constants/monitor_management.ts +++ b/x-pack/plugins/synthetics/common/constants/monitor_management.ts @@ -11,6 +11,7 @@ export enum ConfigKey { CUSTOM_HEARTBEAT_ID = 'custom_heartbeat_id', CONFIG_ID = 'config_id', ENABLED = 'enabled', + FORM_MONITOR_TYPE = 'form_monitor_type', HOSTS = 'hosts', IGNORE_HTTPS_ERRORS = 'ignore_https_errors', MONITOR_SOURCE_TYPE = 'origin', @@ -53,6 +54,7 @@ export enum ConfigKey { SOURCE_ZIP_PROXY_URL = 'source.zip_url.proxy_url', PROJECT_ID = 'project_id', SYNTHETICS_ARGS = 'synthetics_args', + TEXT_ASSERTION = 'playwright_text_assertion', TLS_CERTIFICATE_AUTHORITIES = 'ssl.certificate_authorities', TLS_CERTIFICATE = 'ssl.certificate', TLS_KEY = 'ssl.key', diff --git a/x-pack/plugins/synthetics/common/formatters/browser/formatters.ts b/x-pack/plugins/synthetics/common/formatters/browser/formatters.ts index e5b9edf0edf7fb..1524e646bb5089 100644 --- a/x-pack/plugins/synthetics/common/formatters/browser/formatters.ts +++ b/x-pack/plugins/synthetics/common/formatters/browser/formatters.ts @@ -77,5 +77,6 @@ export const browserFormatters: BrowserFormatMap = { [ConfigKey.PLAYWRIGHT_OPTIONS]: null, [ConfigKey.CUSTOM_HEARTBEAT_ID]: null, [ConfigKey.ORIGINAL_SPACE]: null, + [ConfigKey.TEXT_ASSERTION]: null, ...commonFormatters, }; diff --git a/x-pack/plugins/synthetics/common/formatters/common/formatters.ts b/x-pack/plugins/synthetics/common/formatters/common/formatters.ts index 55fe80e3bba8d3..5a5fbb864ecb37 100644 --- a/x-pack/plugins/synthetics/common/formatters/common/formatters.ts +++ b/x-pack/plugins/synthetics/common/formatters/common/formatters.ts @@ -27,6 +27,7 @@ export const commonFormatters: CommonFormatMap = { [ConfigKey.NAMESPACE]: null, [ConfigKey.REVISION]: null, [ConfigKey.MONITOR_SOURCE_TYPE]: null, + [ConfigKey.FORM_MONITOR_TYPE]: null, }; export const arrayToJsonFormatter = (value: string[] = []) => diff --git a/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_configs.ts b/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_configs.ts index 4d1e22ffaea3b0..934c5347953016 100644 --- a/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_configs.ts +++ b/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_configs.ts @@ -126,3 +126,13 @@ export enum SourceType { } export const SourceTypeCodec = tEnum('SourceType', SourceType); + +export enum FormMonitorType { + SINGLE = 'single', + MULTISTEP = 'multistep', + HTTP = 'http', + TCP = 'tcp', + ICMP = 'icmp', +} + +export const FormMonitorTypeCodec = tEnum('FormMonitorType', FormMonitorType); diff --git a/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types.ts b/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types.ts index 2405fc1f966756..ebb5376792d704 100644 --- a/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types.ts +++ b/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types.ts @@ -16,6 +16,7 @@ import { import { DataStream, DataStreamCodec, + FormMonitorTypeCodec, ModeCodec, ResponseBodyIndexPolicyCodec, ScheduleUnitCodec, @@ -79,6 +80,7 @@ export const CommonFieldsCodec = t.intersection([ [ConfigKey.LOCATIONS]: MonitorServiceLocationsCodec, }), t.partial({ + [ConfigKey.FORM_MONITOR_TYPE]: FormMonitorTypeCodec, [ConfigKey.TIMEOUT]: t.union([t.string, t.null]), [ConfigKey.REVISION]: t.number, [ConfigKey.MONITOR_SOURCE_TYPE]: SourceTypeCodec, @@ -220,6 +222,7 @@ export const EncryptedBrowserSimpleFieldsCodec = t.intersection([ [ConfigKey.PROJECT_ID]: t.string, [ConfigKey.ORIGINAL_SPACE]: t.string, [ConfigKey.CUSTOM_HEARTBEAT_ID]: t.string, + [ConfigKey.TEXT_ASSERTION]: t.string, }), ]), ZipUrlTLSFieldsCodec, diff --git a/x-pack/plugins/synthetics/e2e/journeys/index.ts b/x-pack/plugins/synthetics/e2e/journeys/index.ts index a73ec34ef1d290..a33a5185fcac2a 100644 --- a/x-pack/plugins/synthetics/e2e/journeys/index.ts +++ b/x-pack/plugins/synthetics/e2e/journeys/index.ts @@ -4,8 +4,9 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -export * from './alerts'; + export * from './synthetics'; +export * from './alerts'; export * from './data_view_permissions'; export * from './uptime.journey'; export * from './step_duration.journey'; diff --git a/x-pack/plugins/synthetics/e2e/journeys/synthetics/add_monitor.journey.ts b/x-pack/plugins/synthetics/e2e/journeys/synthetics/add_monitor.journey.ts new file mode 100644 index 00000000000000..881e562d56dd8e --- /dev/null +++ b/x-pack/plugins/synthetics/e2e/journeys/synthetics/add_monitor.journey.ts @@ -0,0 +1,211 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import uuid from 'uuid'; +import { journey, step, expect, Page } from '@elastic/synthetics'; +import { FormMonitorType } from '../../../common/runtime_types/monitor_management'; +import { syntheticsAppPageProvider } from '../../page_objects/synthetics_app'; + +const customLocation = process.env.SYNTHETICS_TEST_LOCATION; + +const basicMonitorDetails = { + location: customLocation || 'US Central', + schedule: '3', +}; +const httpName = `http monitor ${uuid.v4()}`; +const icmpName = `icmp monitor ${uuid.v4()}`; +const tcpName = `tcp monitor ${uuid.v4()}`; +const browserName = `browser monitor ${uuid.v4()}`; +const browserRecorderName = `browser monitor recorder ${uuid.v4()}`; +const apmServiceName = 'apmServiceName'; + +const configuration = { + [FormMonitorType.HTTP]: { + monitorType: FormMonitorType.HTTP, + monitorConfig: { + ...basicMonitorDetails, + name: httpName, + url: 'https://elastic.co', + locations: [basicMonitorDetails.location], + apmServiceName, + }, + monitorListDetails: { + ...basicMonitorDetails, + name: httpName, + }, + monitorEditDetails: [ + ['[data-test-subj=syntheticsMonitorConfigSchedule]', '3'], + ['[data-test-subj=syntheticsMonitorConfigName]', httpName], + ['[data-test-subj=syntheticsMonitorConfigURL]', 'https://elastic.co'], + ['[data-test-subj=syntheticsMonitorConfigAPMServiceName]', apmServiceName], + ], + }, + [FormMonitorType.TCP]: { + monitorType: FormMonitorType.TCP, + monitorConfig: { + ...basicMonitorDetails, + name: tcpName, + host: 'smtp.gmail.com:587', + locations: [basicMonitorDetails.location], + apmServiceName, + }, + monitorListDetails: { + ...basicMonitorDetails, + name: tcpName, + }, + monitorEditDetails: [ + ['[data-test-subj=syntheticsMonitorConfigSchedule]', '3'], + ['[data-test-subj=syntheticsMonitorConfigName]', tcpName], + ['[data-test-subj=syntheticsMonitorConfigHost]', 'smtp.gmail.com:587'], + ['[data-test-subj=syntheticsMonitorConfigAPMServiceName]', apmServiceName], + ], + }, + [FormMonitorType.ICMP]: { + monitorType: FormMonitorType.ICMP, + monitorConfig: { + ...basicMonitorDetails, + name: icmpName, + host: '1.1.1.1', + locations: [basicMonitorDetails.location], + apmServiceName, + }, + monitorListDetails: { + ...basicMonitorDetails, + name: icmpName, + }, + monitorEditDetails: [ + ['[data-test-subj=syntheticsMonitorConfigSchedule]', '3'], + ['[data-test-subj=syntheticsMonitorConfigName]', icmpName], + ['[data-test-subj=syntheticsMonitorConfigHost]', '1.1.1.1'], + ['[data-test-subj=syntheticsMonitorConfigAPMServiceName]', apmServiceName], + // name: httpName, + ], + }, + [FormMonitorType.MULTISTEP]: { + monitorType: FormMonitorType.MULTISTEP, + monitorConfig: { + ...basicMonitorDetails, + schedule: '10', + name: browserName, + inlineScript: 'step("test step", () => {})', + locations: [basicMonitorDetails.location], + apmServiceName, + }, + monitorListDetails: { + ...basicMonitorDetails, + schedule: '10', + name: browserName, + }, + monitorEditDetails: [ + ['[data-test-subj=syntheticsMonitorConfigSchedule]', '10'], + ['[data-test-subj=syntheticsMonitorConfigName]', browserName], + ['[data-test-subj=codeEditorContainer] textarea', 'step("test step", () => {})'], + ['[data-test-subj=syntheticsMonitorConfigAPMServiceName]', apmServiceName], + ], + }, + [`${FormMonitorType.MULTISTEP}__recorder`]: { + monitorType: FormMonitorType.MULTISTEP, + monitorConfig: { + ...basicMonitorDetails, + schedule: '10', + name: browserRecorderName, + recorderScript: 'step("test step", () => {})', + locations: [basicMonitorDetails.location], + apmServiceName: 'Sample APM Service', + }, + monitorListDetails: { + ...basicMonitorDetails, + schedule: '10', + name: browserRecorderName, + }, + monitorEditDetails: [ + ['[data-test-subj=syntheticsMonitorConfigSchedule]', '10'], + ['[data-test-subj=syntheticsMonitorConfigName]', browserRecorderName], + ['[data-test-subj=codeEditorContainer] textarea', 'step("test step", () => {})'], + // name: httpName, + ], + }, +}; + +const createMonitorJourney = ({ + monitorName, + monitorType, + monitorConfig, + monitorListDetails, + monitorEditDetails, +}: { + monitorName: string; + monitorType: FormMonitorType; + monitorConfig: Record; + monitorListDetails: Record; + monitorEditDetails: Array<[string, string]>; +}) => { + journey( + `Synthetics - add monitor - ${monitorName}`, + async ({ page, params }: { page: Page; params: any }) => { + const syntheticsApp = syntheticsAppPageProvider({ page, kibanaUrl: params.kibanaUrl }); + + step('Go to monitor management', async () => { + await syntheticsApp.navigateToMonitorManagement(); + }); + + step('login to Kibana', async () => { + await syntheticsApp.loginToKibana(); + const invalid = await page.locator( + `text=Username or password is incorrect. Please try again.` + ); + expect(await invalid.isVisible()).toBeFalsy(); + }); + + step('Ensure all montiors are deleted', async () => { + await syntheticsApp.navigateToMonitorManagement(); + await syntheticsApp.waitForLoadingToFinish(); + const isSuccessful = await syntheticsApp.deleteMonitors(); + expect(isSuccessful).toBeTruthy(); + }); + + step(`create ${monitorName}`, async () => { + await syntheticsApp.navigateToAddMonitor(); + await syntheticsApp.createMonitor({ monitorConfig, monitorType }); + const isSuccessful = await syntheticsApp.confirmAndSave(); + expect(isSuccessful).toBeTruthy(); + }); + + step(`view ${monitorName} details in Monitor Management UI`, async () => { + await syntheticsApp.navigateToMonitorManagement(); + const hasFailure = await syntheticsApp.findMonitorConfiguration(monitorListDetails); + expect(hasFailure).toBeFalsy(); + }); + + step(`edit ${monitorName}`, async () => { + await syntheticsApp.navigateToEditMonitor(); + await syntheticsApp.findByText(monitorListDetails.location); + const hasFailure = await syntheticsApp.findEditMonitorConfiguration( + monitorEditDetails, + monitorType + ); + expect(hasFailure).toBeFalsy(); + }); + + step('delete monitor', async () => { + await syntheticsApp.navigateToMonitorManagement(); + await syntheticsApp.findByText('Monitor name'); + const isSuccessful = await syntheticsApp.deleteMonitors(); + expect(isSuccessful).toBeTruthy(); + }); + } + ); +}; + +Object.values(configuration).forEach((config) => { + createMonitorJourney({ + monitorType: config.monitorType, + monitorName: `${config.monitorConfig.name} monitor`, + monitorConfig: config.monitorConfig, + monitorListDetails: config.monitorListDetails, + monitorEditDetails: config.monitorEditDetails as Array<[string, string]>, + }); +}); diff --git a/x-pack/plugins/synthetics/e2e/journeys/synthetics/index.ts b/x-pack/plugins/synthetics/e2e/journeys/synthetics/index.ts index 1783ced950ca17..3c8869fab85a8e 100644 --- a/x-pack/plugins/synthetics/e2e/journeys/synthetics/index.ts +++ b/x-pack/plugins/synthetics/e2e/journeys/synthetics/index.ts @@ -6,3 +6,4 @@ */ export * from './getting_started.journey'; +export * from './add_monitor.journey'; diff --git a/x-pack/plugins/synthetics/e2e/page_objects/monitor_management.tsx b/x-pack/plugins/synthetics/e2e/page_objects/monitor_management.tsx index ba5d245a45588f..0046326bad612c 100644 --- a/x-pack/plugins/synthetics/e2e/page_objects/monitor_management.tsx +++ b/x-pack/plugins/synthetics/e2e/page_objects/monitor_management.tsx @@ -4,7 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { Page } from '@elastic/synthetics'; +import { expect, Page } from '@elastic/synthetics'; import { getQuerystring } from '@kbn/observability-plugin/e2e/utils'; import { DataStream } from '../../common/runtime_types/monitor_management'; import { loginPageProvider } from './login'; @@ -107,6 +107,8 @@ export function monitorManagementPageProvider({ }, async clickAddMonitor() { + const isEnabled = await this.checkIsEnabled(); + expect(isEnabled).toBe(true); await page.click('text=Add monitor'); }, diff --git a/x-pack/plugins/synthetics/e2e/page_objects/synthetics_app.tsx b/x-pack/plugins/synthetics/e2e/page_objects/synthetics_app.tsx index 13ef33a7261630..fc365abd823b92 100644 --- a/x-pack/plugins/synthetics/e2e/page_objects/synthetics_app.tsx +++ b/x-pack/plugins/synthetics/e2e/page_objects/synthetics_app.tsx @@ -4,7 +4,8 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { Page } from '@elastic/synthetics'; +import { expect, Page } from '@elastic/synthetics'; +import { FormMonitorType } from '../../common/runtime_types/monitor_management'; import { loginPageProvider } from './login'; import { utilsPageProvider } from './utils'; @@ -19,8 +20,7 @@ export function syntheticsAppPageProvider({ page, kibanaUrl }: { page: Page; kib const isRemote = Boolean(process.env.SYNTHETICS_REMOTE_ENABLED); const basePath = isRemote ? remoteKibanaUrl : kibanaUrl; const monitorManagement = `${basePath}/app/synthetics/monitors`; - const addMonitor = `${basePath}/app/uptime/add-monitor`; - + const addMonitor = `${basePath}/app/synthetics/add-monitor`; return { ...loginPageProvider({ page, @@ -49,25 +49,43 @@ export function syntheticsAppPageProvider({ page, kibanaUrl }: { page: Page; kib }, async navigateToAddMonitor() { - await page.goto(addMonitor, { - waitUntil: 'networkidle', - }); + await page.goto(addMonitor); }, async ensureIsOnMonitorConfigPage() { await page.isVisible('[data-test-subj=monitorSettingsSection]'); }, - async confirmAndSave(isEditPage?: boolean) { + async confirmAndSave() { await this.ensureIsOnMonitorConfigPage(); - if (isEditPage) { - await page.click('text=Update monitor'); - } else { - await page.click('text=Create monitor'); - } + await this.clickByTestSubj('syntheticsMonitorConfigSubmitButton'); return await this.findByText('Monitor added successfully.'); }, + async deleteMonitors() { + let isSuccessful: boolean = false; + while (true) { + if ((await page.$(this.byTestId('syntheticsMonitorListActions'))) === null) { + isSuccessful = true; + break; + } + await page.click(this.byTestId('syntheticsMonitorListActions'), { delay: 800 }); + await page.click('text=delete', { delay: 800 }); + await page.waitForSelector('[data-test-subj="confirmModalTitleText"]'); + await this.clickByTestSubj('confirmModalConfirmButton'); + isSuccessful = Boolean(await this.findByTestSubj('uptimeDeleteMonitorSuccess')); + await this.navigateToMonitorManagement(); + await page.waitForTimeout(5 * 1000); + } + return isSuccessful; + }, + + async navigateToEditMonitor() { + await this.clickByTestSubj('syntheticsMonitorListActions'); + await page.click('text=Edit'); + await this.findByText('Edit monitor'); + }, + async selectLocations({ locations }: { locations: string[] }) { for (let i = 0; i < locations.length; i++) { await page.click( @@ -77,6 +95,13 @@ export function syntheticsAppPageProvider({ page, kibanaUrl }: { page: Page; kib } }, + async selectLocationsAddEdit({ locations }: { locations: string[] }) { + for (let i = 0; i < locations.length; i++) { + await page.click(this.byTestId('syntheticsMonitorConfigLocations')); + await page.click(`text=${locations[i]}`); + } + }, + async fillFirstMonitorDetails({ url, locations }: { url: string; locations: string[] }) { await this.fillByTestSubj('urls-input', url); await page.click(this.byTestId('comboBoxInput')); @@ -84,6 +109,162 @@ export function syntheticsAppPageProvider({ page, kibanaUrl }: { page: Page; kib await page.click(this.byTestId('urls-input')); }, + async selectMonitorType(monitorType: string) { + await this.clickByTestSubj(monitorType); + }, + + async findMonitorConfiguration(monitorConfig: Record) { + const values = Object.values(monitorConfig); + + for (let i = 0; i < values.length; i++) { + await this.findByText(values[i]); + } + }, + + async findEditMonitorConfiguration( + monitorConfig: Array<[string, string]>, + monitorType: FormMonitorType + ) { + await page.click('text="Advanced options"'); + + for (let i = 0; i < monitorConfig.length; i++) { + const [selector, expected] = monitorConfig[i]; + const actual = await page.inputValue(selector); + expect(actual).toEqual(expected); + } + }, + + async fillCodeEditor(value: string) { + await page.fill('[data-test-subj=codeEditorContainer] textarea', value); + }, + + async createBasicHTTPMonitorDetails({ + name, + url, + apmServiceName, + locations, + }: { + name: string; + url: string; + apmServiceName: string; + locations: string[]; + }) { + await this.selectMonitorType('syntheticsMonitorTypeHTTP'); + await this.createBasicMonitorDetails({ name, apmServiceName, locations }); + await this.fillByTestSubj('syntheticsMonitorConfigURL', url); + }, + + async createBasicTCPMonitorDetails({ + name, + host, + apmServiceName, + locations, + }: { + name: string; + host: string; + apmServiceName: string; + locations: string[]; + }) { + await this.selectMonitorType('syntheticsMonitorTypeTCP'); + await this.createBasicMonitorDetails({ name, apmServiceName, locations }); + await this.fillByTestSubj('syntheticsMonitorConfigHost', host); + }, + + async createBasicICMPMonitorDetails({ + name, + host, + apmServiceName, + locations, + }: { + name: string; + host: string; + apmServiceName: string; + locations: string[]; + }) { + await this.selectMonitorType('syntheticsMonitorTypeICMP'); + await this.createBasicMonitorDetails({ name, apmServiceName, locations }); + await this.fillByTestSubj('syntheticsMonitorConfigHost', host); + }, + + async createBasicBrowserMonitorDetails({ + name, + inlineScript, + recorderScript, + params, + username, + password, + apmServiceName, + locations, + }: { + name: string; + inlineScript?: string; + recorderScript?: string; + params?: string; + username?: string; + password?: string; + apmServiceName: string; + locations: string[]; + }) { + await this.createBasicMonitorDetails({ name, apmServiceName, locations }); + if (inlineScript) { + await this.clickByTestSubj('syntheticsSourceTab__inline'); + await this.fillCodeEditor(inlineScript); + return; + } + if (recorderScript) { + // Upload buffer from memory + await page.setInputFiles('input[data-test-subj=syntheticsFleetScriptRecorderUploader]', { + name: 'file.js', + mimeType: 'text/javascript', + buffer: Buffer.from(recorderScript), + }); + } + }, + + async createBasicMonitorDetails({ + name, + apmServiceName, + locations, + }: { + name: string; + apmServiceName: string; + locations: string[]; + }) { + await page.click('text="Advanced options"'); + await this.fillByTestSubj('syntheticsMonitorConfigName', name); + await this.fillByTestSubj('syntheticsMonitorConfigAPMServiceName', apmServiceName); + await this.selectLocationsAddEdit({ locations }); + }, + + async createMonitor({ + monitorConfig, + monitorType, + }: { + monitorConfig: Record; + monitorType: FormMonitorType; + }) { + switch (monitorType) { + case FormMonitorType.HTTP: + // @ts-ignore + await this.createBasicHTTPMonitorDetails(monitorConfig); + break; + case FormMonitorType.TCP: + // @ts-ignore + await this.createBasicTCPMonitorDetails(monitorConfig); + break; + case FormMonitorType.ICMP: + // @ts-ignore + await this.createBasicICMPMonitorDetails(monitorConfig); + break; + case FormMonitorType.MULTISTEP: + // @ts-ignore + await this.createBasicBrowserMonitorDetails(monitorConfig); + break; + default: + break; + } + }, + async enableMonitorManagement(shouldEnable: boolean = true) { const isEnabled = await this.checkIsEnabled(); if (isEnabled === shouldEnable) { diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/getting_started/getting_started_page.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/getting_started/getting_started_page.tsx index 704b5d350b9e04..a334d6ec1a514f 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/getting_started/getting_started_page.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/getting_started/getting_started_page.tsx @@ -8,13 +8,17 @@ import React, { useEffect } from 'react'; import { EuiEmptyPrompt, EuiLink, EuiSpacer, EuiText } from '@elastic/eui'; import { useDispatch } from 'react-redux'; +import { useHistory } from 'react-router-dom'; import { i18n } from '@kbn/i18n'; import styled from 'styled-components'; import { useBreadcrumbs } from '../../hooks'; import { getServiceLocations } from '../../state'; +import { MONITOR_ADD_ROUTE } from '../../../../../common/constants/ui'; import { SimpleMonitorForm } from './simple_monitor_form'; + export const GettingStartedPage = () => { const dispatch = useDispatch(); + const history = useHistory(); useEffect(() => { dispatch(getServiceLocations()); @@ -32,7 +36,13 @@ export const GettingStartedPage = () => { <> {OR_LABEL}{' '} - {SELECT_DIFFERENT_MONITOR} + + {SELECT_DIFFERENT_MONITOR} + {i18n.translate('xpack.synthetics.gettingStarted.createSingle.description', { defaultMessage: ' to get started with Elastic Synthetics Monitoring', })} diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/getting_started/simple_monitor_form.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/getting_started/simple_monitor_form.tsx index 14ceff545e240b..ce849f586a93c0 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/getting_started/simple_monitor_form.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/getting_started/simple_monitor_form.tsx @@ -77,7 +77,13 @@ export const SimpleMonitorForm = () => { - + {CREATE_MONITOR_LABEL} diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/advanced/index.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/advanced/index.tsx new file mode 100644 index 00000000000000..d5accba8d73999 --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/advanced/index.tsx @@ -0,0 +1,55 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { i18n } from '@kbn/i18n'; +import { EuiAccordion, EuiDescribedFormGroup, EuiPanel, EuiSpacer } from '@elastic/eui'; +import { useFormContext, FieldError } from 'react-hook-form'; +import { FORM_CONFIG } from '../form/form_config'; +import { Field } from '../form/field'; +import { ConfigKey, FormMonitorType } from '../types'; + +export const AdvancedConfig = () => { + const { + watch, + formState: { errors }, + } = useFormContext(); + const [type]: [FormMonitorType] = watch([ConfigKey.FORM_MONITOR_TYPE]); + + return FORM_CONFIG[type]?.advanced ? ( + + + + {FORM_CONFIG[type].advanced?.map((configGroup) => { + return ( + {configGroup.title}} + fullWidth + key={configGroup.title} + > + {configGroup.components.map((field) => { + return ( + + ); + })} + + ); + })} + + + ) : null; +}; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/constants.ts b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/constants.ts new file mode 100644 index 00000000000000..a5f56f375aba17 --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/constants.ts @@ -0,0 +1,9 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export * from '../../../../../common/constants/monitor_management'; +export * from '../../../../../common/constants/monitor_defaults'; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/fields/code_editor.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/fields/code_editor.tsx new file mode 100644 index 00000000000000..6d7fa2cbc441f5 --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/fields/code_editor.tsx @@ -0,0 +1,60 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import React from 'react'; + +import styled from 'styled-components'; + +import { EuiPanel } from '@elastic/eui'; +import { euiStyled } from '@kbn/kibana-react-plugin/common'; +import { CodeEditor as MonacoCodeEditor } from '@kbn/kibana-react-plugin/public'; + +import { MonacoEditorLangId } from '../types'; + +const CodeEditorContainer = styled(EuiPanel)` + padding: 0; +`; + +interface Props { + ariaLabel: string; + id: string; + languageId: MonacoEditorLangId; + onChange: (value: string) => void; + value: string; + placeholder?: string; +} + +export const CodeEditor = ({ ariaLabel, id, languageId, onChange, value, placeholder }: Props) => { + return ( + + + + + + ); +}; + +const MonacoCodeContainer = euiStyled.div` + & > .kibanaCodeEditor { + z-index: 0; + } +`; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/fields/combo_box.test.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/fields/combo_box.test.tsx new file mode 100644 index 00000000000000..3788b3ca7f2c3b --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/fields/combo_box.test.tsx @@ -0,0 +1,37 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { fireEvent } from '@testing-library/react'; +import React from 'react'; +import { render } from '../../../utils/testing/rtl_helpers'; +import { ComboBox } from './combo_box'; + +describe('', () => { + const onChange = jest.fn(); + const selectedOptions: string[] = []; + + it('renders ComboBox', () => { + const { getByTestId } = render( + + ); + + expect(getByTestId('syntheticsFleetComboBox')).toBeInTheDocument(); + }); + + it('calls onBlur', () => { + const onBlur = jest.fn(); + const { getByTestId } = render( + + ); + + const combobox = getByTestId('syntheticsFleetComboBox'); + fireEvent.focus(combobox); + fireEvent.blur(combobox); + + expect(onBlur).toHaveBeenCalledTimes(1); + }); +}); diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/fields/combo_box.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/fields/combo_box.tsx new file mode 100644 index 00000000000000..16a31e8e5d623d --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/fields/combo_box.tsx @@ -0,0 +1,79 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { useState, useCallback } from 'react'; +import { EuiComboBox, EuiComboBoxOptionOption } from '@elastic/eui'; + +export interface Props { + onChange: (value: string[]) => void; + onBlur?: () => void; + selectedOptions: string[]; +} + +export const ComboBox = ({ onChange, onBlur, selectedOptions, ...props }: Props) => { + const [formattedSelectedOptions, setSelectedOptions] = useState< + Array> + >(selectedOptions.map((option) => ({ label: option, key: option }))); + const [isInvalid, setInvalid] = useState(false); + + const onOptionsChange = useCallback( + (options: Array>) => { + setSelectedOptions(options); + const formattedTags = options.map((option) => option.label); + onChange(formattedTags); + setInvalid(false); + }, + [onChange, setSelectedOptions, setInvalid] + ); + + const onCreateOption = useCallback( + (tag: string) => { + const formattedTag = tag.trim(); + const newOption = { + label: formattedTag, + }; + + onChange([...selectedOptions, formattedTag]); + + // Select the option. + setSelectedOptions([...formattedSelectedOptions, newOption]); + }, + [onChange, formattedSelectedOptions, selectedOptions, setSelectedOptions] + ); + + const onSearchChange = useCallback( + (searchValue: string) => { + if (!searchValue) { + setInvalid(false); + + return; + } + + setInvalid(!isValid(searchValue)); + }, + [setInvalid] + ); + + return ( + + data-test-subj="syntheticsFleetComboBox" + noSuggestions + selectedOptions={formattedSelectedOptions} + onCreateOption={onCreateOption} + onChange={onOptionsChange} + onBlur={() => onBlur?.()} + onSearchChange={onSearchChange} + isInvalid={isInvalid} + {...props} + /> + ); +}; + +const isValid = (value: string) => { + // Ensure that the tag is more than whitespace + return value.match(/\S+/) !== null; +}; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/fields/header_field.test.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/fields/header_field.test.tsx new file mode 100644 index 00000000000000..6f920bf10d84a9 --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/fields/header_field.test.tsx @@ -0,0 +1,109 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { fireEvent, waitFor } from '@testing-library/react'; +import { render } from '../../../utils/testing/rtl_helpers'; +import { HeaderField, contentTypes } from './header_field'; +import { Mode } from '../types'; + +describe('', () => { + const onChange = jest.fn(); + const onBlur = jest.fn(); + const defaultValue = {}; + + afterEach(() => { + jest.resetAllMocks(); + }); + + it('renders HeaderField', () => { + const { getByText, getByTestId } = render( + + ); + + expect(getByText('Key')).toBeInTheDocument(); + expect(getByText('Value')).toBeInTheDocument(); + const key = getByTestId('keyValuePairsKey0') as HTMLInputElement; + const value = getByTestId('keyValuePairsValue0') as HTMLInputElement; + expect(key.value).toEqual('sample'); + expect(value.value).toEqual('header'); + }); + + it('calls onBlur', () => { + const { getByTestId } = render( + + ); + + const key = getByTestId('keyValuePairsKey0') as HTMLInputElement; + const value = getByTestId('keyValuePairsValue0') as HTMLInputElement; + + fireEvent.blur(key); + fireEvent.blur(value); + + expect(onBlur).toHaveBeenCalledTimes(2); + }); + + it('formats headers and handles onChange', async () => { + const { getByTestId, getByText } = render( + + ); + const addHeader = getByText('Add header'); + fireEvent.click(addHeader); + const key = getByTestId('keyValuePairsKey0') as HTMLInputElement; + const value = getByTestId('keyValuePairsValue0') as HTMLInputElement; + const newKey = 'sampleKey'; + const newValue = 'sampleValue'; + fireEvent.change(key, { target: { value: newKey } }); + fireEvent.change(value, { target: { value: newValue } }); + + await waitFor(() => { + expect(onChange).toBeCalledWith({ + [newKey]: newValue, + }); + }); + }); + + it('handles deleting headers', async () => { + const { getByTestId, getByText, getByLabelText } = render( + + ); + const addHeader = getByText('Add header'); + + fireEvent.click(addHeader); + + const key = getByTestId('keyValuePairsKey0') as HTMLInputElement; + const value = getByTestId('keyValuePairsValue0') as HTMLInputElement; + const newKey = 'sampleKey'; + const newValue = 'sampleValue'; + fireEvent.change(key, { target: { value: newKey } }); + fireEvent.change(value, { target: { value: newValue } }); + + await waitFor(() => { + expect(onChange).toBeCalledWith({ + [newKey]: newValue, + }); + }); + + const deleteBtn = getByLabelText('Delete item number 2, sampleKey:sampleValue'); + + // uncheck + fireEvent.click(deleteBtn); + }); + + it('handles content mode', async () => { + const contentMode: Mode = Mode.PLAINTEXT; + render( + + ); + + await waitFor(() => { + expect(onChange).toBeCalledWith({ + 'Content-Type': contentTypes[Mode.PLAINTEXT], + }); + }); + }); +}); diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/fields/header_field.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/fields/header_field.tsx new file mode 100644 index 00000000000000..d2a3c4968191aa --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/fields/header_field.tsx @@ -0,0 +1,77 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { useEffect, useState } from 'react'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { ContentType, Mode } from '../types'; + +import { KeyValuePairsField, Pair } from './key_value_field'; + +interface Props { + contentMode?: Mode; + defaultValue: Record; + onChange: (value: Record) => void; + onBlur?: () => void; + 'data-test-subj'?: string; +} + +export const HeaderField = ({ + contentMode, + defaultValue, + onChange, + onBlur, + 'data-test-subj': dataTestSubj, +}: Props) => { + const defaultValueKeys = Object.keys(defaultValue).filter((key) => key !== 'Content-Type'); // Content-Type is a secret header we hide from the user + const formattedDefaultValues: Pair[] = [ + ...defaultValueKeys.map((key) => { + return [key || '', defaultValue[key] || '']; // key, value + }), + ]; + const [headers, setHeaders] = useState(formattedDefaultValues); + + useEffect(() => { + const formattedHeaders = headers.reduce((acc: Record, header) => { + const [key, value] = header; + if (key) { + return { + ...acc, + [key]: value, + }; + } + return acc; + }, {}); + + if (contentMode) { + onChange({ 'Content-Type': contentTypes[contentMode], ...formattedHeaders }); + } else { + onChange(formattedHeaders); + } + }, [contentMode, headers, onChange]); + + return ( + + } + defaultPairs={headers} + onChange={setHeaders} + onBlur={() => onBlur?.()} + data-test-subj={dataTestSubj} + /> + ); +}; + +export const contentTypes: Record = { + [Mode.JSON]: ContentType.JSON, + [Mode.PLAINTEXT]: ContentType.TEXT, + [Mode.XML]: ContentType.XML, + [Mode.FORM]: ContentType.FORM, +}; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/fields/index_response_body_field.test.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/fields/index_response_body_field.test.tsx new file mode 100644 index 00000000000000..da2e1ef1f93e75 --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/fields/index_response_body_field.test.tsx @@ -0,0 +1,115 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { fireEvent, waitFor } from '@testing-library/react'; +import { render } from '../../../utils/testing/rtl_helpers'; +import { ResponseBodyIndexField } from './index_response_body_field'; +import { ResponseBodyIndexPolicy } from '../types'; + +describe('', () => { + const defaultDefaultValue = ResponseBodyIndexPolicy.ON_ERROR; + const onChange = jest.fn(); + const onBlur = jest.fn(); + const WrappedComponent = ({ defaultValue = defaultDefaultValue }) => { + return ( + + ); + }; + + afterEach(() => { + jest.resetAllMocks(); + }); + + it('renders ResponseBodyIndexField', () => { + const { getByText, getByTestId } = render(); + const select = getByTestId('indexResponseBodyFieldSelect') as HTMLInputElement; + expect(select.value).toEqual(defaultDefaultValue); + expect(getByText('On error')).toBeInTheDocument(); + expect(getByText('Index response body')).toBeInTheDocument(); + }); + + it('handles select change', async () => { + const { getByText, getByTestId } = render(); + const select = getByTestId('indexResponseBodyFieldSelect') as HTMLInputElement; + const newPolicy = ResponseBodyIndexPolicy.ALWAYS; + expect(select.value).toEqual(defaultDefaultValue); + + fireEvent.change(select, { target: { value: newPolicy } }); + + await waitFor(() => { + expect(select.value).toBe(newPolicy); + expect(getByText('Always')).toBeInTheDocument(); + expect(onChange).toBeCalledWith(newPolicy); + }); + }); + + it('calls onBlur', async () => { + const { getByTestId } = render(); + const select = getByTestId('indexResponseBodyFieldSelect') as HTMLInputElement; + const newPolicy = ResponseBodyIndexPolicy.ALWAYS; + + fireEvent.change(select, { target: { value: newPolicy } }); + fireEvent.blur(select); + + expect(onBlur).toHaveBeenCalledTimes(1); + }); + + it('handles checkbox change', async () => { + const { getByTestId, getByLabelText } = render(); + const checkbox = getByLabelText('Index response body') as HTMLInputElement; + const select = getByTestId('indexResponseBodyFieldSelect') as HTMLInputElement; + const newPolicy = ResponseBodyIndexPolicy.NEVER; + expect(checkbox.checked).toBe(true); + + fireEvent.click(checkbox); + + await waitFor(() => { + expect(checkbox.checked).toBe(false); + expect(select).not.toBeInTheDocument(); + expect(onChange).toBeCalledWith(newPolicy); + }); + + fireEvent.click(checkbox); + + await waitFor(() => { + expect(checkbox.checked).toBe(true); + expect(select).not.toBeInTheDocument(); + expect(onChange).toBeCalledWith(defaultDefaultValue); + }); + }); + + it('handles ResponseBodyIndexPolicy.NEVER as a default value', async () => { + const { queryByTestId, getByTestId, getByLabelText } = render( + + ); + const checkbox = getByLabelText('Index response body') as HTMLInputElement; + expect(checkbox.checked).toBe(false); + expect( + queryByTestId('indexResponseBodyFieldSelect') as HTMLInputElement + ).not.toBeInTheDocument(); + + fireEvent.click(checkbox); + const select = getByTestId('indexResponseBodyFieldSelect') as HTMLInputElement; + + await waitFor(() => { + expect(checkbox.checked).toBe(true); + expect(select).toBeInTheDocument(); + expect(select.value).toEqual(ResponseBodyIndexPolicy.ON_ERROR); + // switches back to on error policy when checkbox is checked + expect(onChange).toBeCalledWith(ResponseBodyIndexPolicy.ON_ERROR); + }); + + const newPolicy = ResponseBodyIndexPolicy.ALWAYS; + fireEvent.change(select, { target: { value: newPolicy } }); + + await waitFor(() => { + expect(select.value).toEqual(newPolicy); + expect(onChange).toBeCalledWith(newPolicy); + }); + }); +}); diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/fields/index_response_body_field.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/fields/index_response_body_field.tsx new file mode 100644 index 00000000000000..d7de7adcf1aa97 --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/fields/index_response_body_field.tsx @@ -0,0 +1,101 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { useEffect, useState } from 'react'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n-react'; + +import { EuiCheckbox, EuiFlexGroup, EuiFlexItem, EuiSelect } from '@elastic/eui'; +import { ResponseBodyIndexPolicy } from '../types'; + +interface Props { + defaultValue: ResponseBodyIndexPolicy; + onChange: (responseBodyIndexPolicy: ResponseBodyIndexPolicy) => void; + onBlur?: () => void; +} + +export const ResponseBodyIndexField = ({ defaultValue, onChange, onBlur }: Props) => { + const [policy, setPolicy] = useState( + defaultValue !== ResponseBodyIndexPolicy.NEVER ? defaultValue : ResponseBodyIndexPolicy.ON_ERROR + ); + const [checked, setChecked] = useState(defaultValue !== ResponseBodyIndexPolicy.NEVER); + + useEffect(() => { + if (checked) { + setPolicy(policy); + onChange(policy); + } else { + onChange(ResponseBodyIndexPolicy.NEVER); + } + }, [checked, policy, setPolicy, onChange]); + + useEffect(() => { + onChange(policy); + }, [onChange, policy]); + + return ( + + + + } + onChange={(event) => { + const checkedEvent = event.target.checked; + setChecked(checkedEvent); + }} + onBlur={() => onBlur?.()} + /> + + {checked && ( + + { + setPolicy(event.target.value as ResponseBodyIndexPolicy); + }} + onBlur={() => onBlur?.()} + /> + + )} + + ); +}; + +const responseBodyIndexPolicyOptions = [ + { + value: ResponseBodyIndexPolicy.ALWAYS, + text: i18n.translate( + 'xpack.synthetics.createPackagePolicy.stepConfigure.responseBodyIndex.always', + { + defaultMessage: 'Always', + } + ), + }, + { + value: ResponseBodyIndexPolicy.ON_ERROR, + text: i18n.translate( + 'xpack.synthetics.createPackagePolicy.stepConfigure.responseBodyIndex.onError', + { + defaultMessage: 'On error', + } + ), + }, +]; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/fields/key_value_field.test.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/fields/key_value_field.test.tsx new file mode 100644 index 00000000000000..670c414e37bbb4 --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/fields/key_value_field.test.tsx @@ -0,0 +1,89 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import userEvent from '@testing-library/user-event'; +import React from 'react'; +import { fireEvent, waitFor } from '@testing-library/react'; +import { render } from '../../../utils/testing/rtl_helpers'; +import { KeyValuePairsField, Pair } from './key_value_field'; + +describe('', () => { + const onChange = jest.fn(); + const onBlur = jest.fn(); + const defaultDefaultValue = [['', '']] as Pair[]; + const WrappedComponent = ({ + defaultValue = defaultDefaultValue, + addPairControlLabel = 'Add pair', + }) => { + return ( + + ); + }; + + afterEach(() => { + jest.resetAllMocks(); + }); + + it('renders KeyValuePairsField', () => { + const { getByText } = render(); + expect(getByText('Key')).toBeInTheDocument(); + expect(getByText('Value')).toBeInTheDocument(); + + expect(getByText('Add pair')).toBeInTheDocument(); + }); + + it('calls onBlur', () => { + const { getByText, getByTestId } = render(); + const addPair = getByText('Add pair'); + fireEvent.click(addPair); + + const keyInput = getByTestId('keyValuePairsKey0') as HTMLInputElement; + const valueInput = getByTestId('keyValuePairsValue0') as HTMLInputElement; + + userEvent.type(keyInput, 'some-key'); + userEvent.type(valueInput, 'some-value'); + fireEvent.blur(valueInput); + + expect(onBlur).toHaveBeenCalledTimes(2); + }); + + it('handles adding and editing a new row', async () => { + const { getByTestId, queryByTestId, getByText } = render( + + ); + + expect(queryByTestId('keyValuePairsKey0')).not.toBeInTheDocument(); + expect(queryByTestId('keyValuePairsValue0')).not.toBeInTheDocument(); // check that only one row exists + + const addPair = getByText('Add pair'); + + fireEvent.click(addPair); + + const newRowKey = getByTestId('keyValuePairsKey0') as HTMLInputElement; + const newRowValue = getByTestId('keyValuePairsValue0') as HTMLInputElement; + + await waitFor(() => { + expect(newRowKey.value).toEqual(''); + expect(newRowValue.value).toEqual(''); + expect(onChange).toBeCalledWith([[newRowKey.value, newRowValue.value]]); + }); + + fireEvent.change(newRowKey, { target: { value: 'newKey' } }); + fireEvent.change(newRowValue, { target: { value: 'newValue' } }); + + await waitFor(() => { + expect(newRowKey.value).toEqual('newKey'); + expect(newRowValue.value).toEqual('newValue'); + expect(onChange).toBeCalledWith([[newRowKey.value, newRowValue.value]]); + }); + }); +}); diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/fields/key_value_field.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/fields/key_value_field.tsx new file mode 100644 index 00000000000000..153d537ebec0ea --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/fields/key_value_field.tsx @@ -0,0 +1,201 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { Fragment, useCallback, useEffect, useState } from 'react'; +import styled from 'styled-components'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { + EuiButton, + EuiButtonIcon, + EuiFieldText, + EuiFlexGroup, + EuiFlexItem, + EuiFormControlLayoutDelimited, + EuiFormLabel, + EuiFormFieldset, + EuiSpacer, +} from '@elastic/eui'; + +const StyledFieldset = styled(EuiFormFieldset)` + &&& { + legend { + width: calc(100% - 52px); // right margin + flex item padding + margin-right: 40px; + } + .euiFlexGroup { + margin-left: 0; + } + .euiFlexItem { + margin-left: 0; + padding-left: 12px; + } + } +`; + +const StyledField = styled(EuiFieldText)` + text-align: left; +`; + +export type Pair = [ + string, // key + string // value +]; + +interface Props { + addPairControlLabel: string | React.ReactElement; + defaultPairs: Pair[]; + onChange: (pairs: Pair[]) => void; + onBlur?: () => void; + 'data-test-subj'?: string; +} + +export const KeyValuePairsField = ({ + addPairControlLabel, + defaultPairs, + onChange, + onBlur, + 'data-test-subj': dataTestSubj, +}: Props) => { + const [pairs, setPairs] = useState(defaultPairs); + + const handleOnChange = useCallback( + (event: React.ChangeEvent, index: number, isKey: boolean) => { + const targetValue = event.target.value; + + setPairs((prevPairs) => { + const newPairs = [...prevPairs]; + const [prevKey, prevValue] = prevPairs[index]; + newPairs[index] = isKey ? [targetValue, prevValue] : [prevKey, targetValue]; + return newPairs; + }); + }, + [setPairs] + ); + + const handleAddPair = useCallback(() => { + setPairs((prevPairs) => [['', ''], ...prevPairs]); + }, [setPairs]); + + const handleDeletePair = useCallback( + (index: number) => { + setPairs((prevPairs) => { + const newPairs = [...prevPairs]; + newPairs.splice(index, 1); + return [...newPairs]; + }); + }, + [setPairs] + ); + + useEffect(() => { + onChange(pairs); + }, [onChange, pairs]); + + return ( +
+ + + + + {addPairControlLabel} + + + + + + + { + + } + + + { + + } + + + ), + } + : undefined + } + > + {pairs.map((pair, index) => { + const [key, value] = pair; + return ( + + + + handleDeletePair(index)} + /> + + } + startControl={ + handleOnChange(event, index, true)} + onBlur={() => onBlur?.()} + /> + } + endControl={ + handleOnChange(event, index, false)} + onBlur={() => onBlur?.()} + /> + } + delimiter=":" + /> + + + ); + })} + +
+ ); +}; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/fields/monitor_type_radio_group.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/fields/monitor_type_radio_group.tsx new file mode 100644 index 00000000000000..a803f01770d4e8 --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/fields/monitor_type_radio_group.tsx @@ -0,0 +1,109 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { i18n } from '@kbn/i18n'; +import { + EuiPanel, + EuiText, + EuiLink, + EuiSpacer, + EuiKeyPadMenu, + EuiKeyPadMenuItem, + EuiIcon, + EuiKeyPadMenuItemProps, +} from '@elastic/eui'; + +export type MonitorTypeRadioOption = EuiKeyPadMenuItemProps & { + icon: string; + description: string; + descriptionTitle: string; + link: string; + value: string; + label: React.ReactNode; + onChange: (id: string, value: string) => void; + name: string; + 'data-test-subj': string; +}; + +export const MonitorType = ({ + id, + value, + label, + icon, + onChange, + name, + isSelected, + 'data-test-subj': dataTestSubj, +}: MonitorTypeRadioOption) => { + return ( + + + + ); +}; + +export const MonitorTypeRadioGroup = ({ + options, + value, + name, + onChange, + ariaLegend, + ...props +}: EuiKeyPadMenuItemProps & { + options: MonitorTypeRadioOption[]; + onChange: React.ChangeEvent; + name: string; + value: string; + ariaLegend: string; +}) => { + const selectedOption = options.find((radio) => radio.value === value); + return ( + <> + + {options.map((radio) => { + return ( + + ); + })} + + + {selectedOption && ( + + +

{selectedOption.descriptionTitle}

+
+ + {`${selectedOption.description} `} + + {i18n.translate('xpack.synthetics.monitorConfig.monitorType.learnMoreLink', { + defaultMessage: 'Learn more', + })} + + + +
+ )} + + ); +}; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/fields/optional_label.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/fields/optional_label.tsx new file mode 100644 index 00000000000000..a9db178a84bb3a --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/fields/optional_label.tsx @@ -0,0 +1,20 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import React from 'react'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { EuiText } from '@elastic/eui'; + +export const OptionalLabel = () => { + return ( + + + + ); +}; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/fields/request_body_field.test.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/fields/request_body_field.test.tsx new file mode 100644 index 00000000000000..7f3442027da872 --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/fields/request_body_field.test.tsx @@ -0,0 +1,88 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import 'jest-canvas-mock'; + +import React, { useState, useCallback } from 'react'; +import { fireEvent, waitFor } from '@testing-library/react'; +import { render } from '../../../utils/testing/rtl_helpers'; +import { RequestBodyField } from './request_body_field'; +import { Mode } from '../types'; + +jest.mock('@elastic/eui/lib/services/accessibility/html_id_generator', () => ({ + htmlIdGenerator: () => () => `id-${Math.random()}`, +})); + +jest.mock('@kbn/kibana-react-plugin/public', () => { + const original = jest.requireActual('@kbn/kibana-react-plugin/public'); + return { + ...original, + // Mocking CodeEditor, which uses React Monaco under the hood + CodeEditor: (props: any) => ( + { + props.onChange(e.jsonContent); + }} + /> + ), + }; +}); + +describe('', () => { + const defaultMode = Mode.PLAINTEXT; + const defaultValue = 'sample value'; + const WrappedComponent = () => { + const [config, setConfig] = useState({ + type: defaultMode, + value: defaultValue, + }); + + return ( + setConfig({ type: code.type as Mode, value: code.value }), + [setConfig] + )} + /> + ); + }; + + it('renders RequestBodyField', () => { + const { getByText, getByLabelText } = render(); + + expect(getByText('Form')).toBeInTheDocument(); + expect(getByText('Text')).toBeInTheDocument(); + expect(getByText('XML')).toBeInTheDocument(); + expect(getByText('JSON')).toBeInTheDocument(); + expect(getByLabelText('Text code editor')).toBeInTheDocument(); + }); + + it('handles changing code editor mode', async () => { + const { getByText, getByLabelText, queryByText, queryByLabelText } = render( + + ); + + // currently text code editor is displayed + expect(getByLabelText('Text code editor')).toBeInTheDocument(); + expect(queryByText('Key')).not.toBeInTheDocument(); + + const formButton = getByText('Form').closest('button'); + if (formButton) { + fireEvent.click(formButton); + } + await waitFor(() => { + expect(getByText('Add form field')).toBeInTheDocument(); + expect(queryByLabelText('Text code editor')).not.toBeInTheDocument(); + }); + }); +}); diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/fields/request_body_field.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/fields/request_body_field.tsx new file mode 100644 index 00000000000000..2d38c65e9a2fe0 --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/fields/request_body_field.tsx @@ -0,0 +1,208 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import React, { useCallback, useEffect, useMemo, useState } from 'react'; +import { stringify, parse } from 'query-string'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { i18n } from '@kbn/i18n'; +import { EuiTabbedContent } from '@elastic/eui'; +import { Mode, MonacoEditorLangId } from '../types'; +import { KeyValuePairsField, Pair } from './key_value_field'; +import { CodeEditor } from './code_editor'; + +interface Props { + onChange: (requestBody: { type: Mode; value: string }) => void; + onBlur?: () => void; + value: { + type: Mode; + value: string; + }; +} + +enum ResponseBodyType { + CODE = 'code', + FORM = 'form', +} + +// TO DO: Look into whether or not code editor reports errors, in order to prevent form submission on an error +export const RequestBodyField = ({ onChange, onBlur, value: { type, value } }: Props) => { + const [values, setValues] = useState>({ + [ResponseBodyType.FORM]: type === Mode.FORM ? value : '', + [ResponseBodyType.CODE]: type !== Mode.FORM ? value : '', + }); + useEffect(() => { + onChange({ + type, + value: type === Mode.FORM ? values[ResponseBodyType.FORM] : values[ResponseBodyType.CODE], + }); + }, [onChange, type, values]); + + const handleSetMode = useCallback( + (currentMode: Mode) => { + onChange({ + type: currentMode, + value: + currentMode === Mode.FORM ? values[ResponseBodyType.FORM] : values[ResponseBodyType.CODE], + }); + }, + [onChange, values] + ); + + const onChangeFormFields = useCallback( + (pairs: Pair[]) => { + const formattedPairs = pairs.reduce((acc: Record, header) => { + const [key, pairValue] = header; + if (key) { + return { + ...acc, + [key]: pairValue, + }; + } + return acc; + }, {}); + return setValues((prevValues) => ({ + ...prevValues, + [Mode.FORM]: stringify(formattedPairs), + })); + }, + [setValues] + ); + + const defaultFormPairs: Pair[] = useMemo(() => { + const pairs = parse(values[Mode.FORM]); + const keys = Object.keys(pairs); + const formattedPairs: Pair[] = keys.map((key: string) => { + // key, value, checked; + return [key, `${pairs[key]}`]; + }); + return formattedPairs; + }, [values]); + + const tabs = [ + { + id: Mode.PLAINTEXT, + name: modeLabels[Mode.PLAINTEXT], + 'data-test-subj': `syntheticsRequestBodyTab__${Mode.PLAINTEXT}`, + content: ( + { + setValues((prevValues) => ({ ...prevValues, [ResponseBodyType.CODE]: code })); + onBlur?.(); + }} + value={values[ResponseBodyType.CODE]} + /> + ), + }, + { + id: Mode.JSON, + name: modeLabels[Mode.JSON], + 'data-test-subj': `syntheticsRequestBodyTab__${Mode.JSON}`, + content: ( + { + setValues((prevValues) => ({ ...prevValues, [ResponseBodyType.CODE]: code })); + onBlur?.(); + }} + value={values[ResponseBodyType.CODE]} + /> + ), + }, + { + id: Mode.XML, + name: modeLabels[Mode.XML], + 'data-test-subj': `syntheticsRequestBodyTab__${Mode.XML}`, + content: ( + { + setValues((prevValues) => ({ ...prevValues, [ResponseBodyType.CODE]: code })); + onBlur?.(); + }} + value={values[ResponseBodyType.CODE]} + /> + ), + }, + { + id: Mode.FORM, + name: modeLabels[Mode.FORM], + 'data-test-subj': `syntheticsRequestBodyTab__${Mode.FORM}`, + content: ( + + } + defaultPairs={defaultFormPairs} + onChange={onChangeFormFields} + onBlur={() => onBlur?.()} + /> + ), + }, + ]; + + return ( + tab.id === type)} + autoFocus="selected" + onTabClick={(tab) => { + handleSetMode(tab.id as Mode); + }} + /> + ); +}; + +const modeLabels = { + [Mode.FORM]: i18n.translate( + 'xpack.synthetics.createPackagePolicy.stepConfigure.requestBodyType.form', + { + defaultMessage: 'Form', + } + ), + [Mode.PLAINTEXT]: i18n.translate( + 'xpack.synthetics.createPackagePolicy.stepConfigure.requestBodyType.text', + { + defaultMessage: 'Text', + } + ), + [Mode.JSON]: i18n.translate( + 'xpack.synthetics.createPackagePolicy.stepConfigure.requestBodyType.JSON', + { + defaultMessage: 'JSON', + } + ), + [Mode.XML]: i18n.translate( + 'xpack.synthetics.createPackagePolicy.stepConfigure.requestBodyType.XML', + { + defaultMessage: 'XML', + } + ), +}; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/fields/script_recorder_fields.test.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/fields/script_recorder_fields.test.tsx new file mode 100644 index 00000000000000..f9fa393bab5dcf --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/fields/script_recorder_fields.test.tsx @@ -0,0 +1,122 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { fireEvent, waitFor } from '@testing-library/react'; +import { render } from '../../../utils/testing/rtl_helpers'; +import { ScriptRecorderFields } from './script_recorder_fields'; + +jest.mock('@elastic/eui/lib/services/accessibility/html_id_generator', () => ({ + ...jest.requireActual('@elastic/eui/lib/services/accessibility/html_id_generator'), + htmlIdGenerator: () => () => `id-${Math.random()}`, +})); + +const onChange = jest.fn(); + +describe('', () => { + let file: File; + const testScript = 'step(() => {})'; + const WrappedComponent = ({ + isEditable = true, + script = '', + fileName = '', + }: { + isEditable?: boolean; + script?: string; + fileName?: string; + }) => { + return ( + + ); + }; + + beforeEach(() => { + jest.clearAllMocks(); + file = new File([testScript], 'samplescript.js', { type: 'text/javascript' }); + }); + + it('renders ScriptRecorderFields', () => { + const { queryByText } = render(); + + expect(queryByText('Show script')).not.toBeInTheDocument(); + expect(queryByText('Remove script')).not.toBeInTheDocument(); + }); + + it('handles uploading files', async () => { + const { getByTestId } = render(); + + const uploader = getByTestId('syntheticsFleetScriptRecorderUploader'); + + fireEvent.change(uploader, { + target: { files: [file] }, + }); + + await waitFor(() => { + expect(onChange).toBeCalledWith({ scriptText: testScript, fileName: 'samplescript.js' }); + }); + }); + + it('shows user errors for invalid file types', async () => { + const { getByTestId, getByText } = render(); + file = new File(['journey(() => {})'], 'samplescript.js', { type: 'text/javascript' }); + + let uploader = getByTestId('syntheticsFleetScriptRecorderUploader') as HTMLInputElement; + + fireEvent.change(uploader, { + target: { files: [file] }, + }); + + uploader = getByTestId('syntheticsFleetScriptRecorderUploader') as HTMLInputElement; + + await waitFor(() => { + expect(onChange).not.toBeCalled(); + expect( + getByText( + 'Error uploading file. Please upload a .js file generated by the Elastic Synthetics Recorder in inline script format.' + ) + ).toBeInTheDocument(); + }); + }); + + it('shows show script button when script is available', () => { + const { getByText, queryByText } = render(); + + const showScriptBtn = getByText('Show script'); + + expect(queryByText(testScript)).not.toBeInTheDocument(); + + fireEvent.click(showScriptBtn); + + expect(getByText(testScript)).toBeInTheDocument(); + }); + + it('shows show remove script button when script is available and isEditable is true', async () => { + const { getByText, getByTestId } = render( + + ); + + const showScriptBtn = getByText('Show script'); + fireEvent.click(showScriptBtn); + + expect(getByText(testScript)).toBeInTheDocument(); + + fireEvent.click(getByTestId('euiFlyoutCloseButton')); + + const removeScriptBtn = getByText('Remove script'); + + fireEvent.click(removeScriptBtn); + + await waitFor(() => { + expect(onChange).toBeCalledWith({ scriptText: '', fileName: '' }); + }); + }); +}); diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/fields/script_recorder_fields.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/fields/script_recorder_fields.tsx new file mode 100644 index 00000000000000..3704fd4f4ec110 --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/fields/script_recorder_fields.tsx @@ -0,0 +1,125 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { useState, useCallback } from 'react'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { + EuiFlexGroup, + EuiFlexItem, + EuiFlyout, + EuiFlyoutHeader, + EuiFormRow, + EuiCodeBlock, + EuiTitle, + EuiButton, + EuiSpacer, + EuiText, +} from '@elastic/eui'; +import { Uploader } from './uploader'; + +interface Props { + onChange: ({ scriptText, fileName }: { scriptText: string; fileName: string }) => void; + script: string; + fileName?: string; + isEditable?: boolean; +} + +export function ScriptRecorderFields({ onChange, script, fileName, isEditable }: Props) { + const [showScript, setShowScript] = useState(false); + + const handleUpload = useCallback( + ({ scriptText, fileName: fileNameT }: { scriptText: string; fileName: string }) => { + onChange({ scriptText, fileName: fileNameT }); + }, + [onChange] + ); + + return ( + <> + + {isEditable && script ? ( + + + {fileName} + + + ) : ( + + )} + {script && ( + <> + + + + setShowScript(true)} + iconType="editorCodeBlock" + iconSide="right" + > + + + + + {isEditable && ( + onChange({ scriptText: '', fileName: '' })} + iconType="trash" + iconSide="right" + color="danger" + > + + + )} + + + + )} + {showScript && ( + setShowScript(false)} + aria-labelledby="syntheticsBrowserScriptBlockHeader" + closeButtonAriaLabel={CLOSE_BUTTON_LABEL} + > + + + + {fileName || PLACEHOLDER_FILE_NAME} + + + +
+ + {script} + +
+
+ )} + + ); +} + +const PLACEHOLDER_FILE_NAME = i18n.translate( + 'xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.scriptRecorder.mockFileName', + { + defaultMessage: 'test_script.js', + } +); + +const CLOSE_BUTTON_LABEL = i18n.translate( + 'xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.scriptRecorder.closeButtonLabel', + { + defaultMessage: 'Close script flyout', + } +); diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/fields/source_field.test.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/fields/source_field.test.tsx new file mode 100644 index 00000000000000..b52cfe346a80d6 --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/fields/source_field.test.tsx @@ -0,0 +1,99 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import userEvent from '@testing-library/user-event'; +import { render } from '../../../utils/testing/rtl_helpers'; +import { SourceField } from './source_field'; + +jest.mock('@elastic/eui/lib/services/accessibility/html_id_generator', () => ({ + ...jest.requireActual('@elastic/eui/lib/services/accessibility/html_id_generator'), + htmlIdGenerator: () => () => `id-${Math.random()}`, +})); + +jest.mock('@kbn/kibana-react-plugin/public', () => { + const original = jest.requireActual('@kbn/kibana-react-plugin/public'); + return { + ...original, + // Mocking CodeEditor, which uses React Monaco under the hood + CodeEditor: (props: any) => ( + { + props.onChange(e.jsonContent); + }} + /> + ), + }; +}); + +const onChange = jest.fn(); +const onBlur = jest.fn(); + +describe('', () => { + const WrappedComponent = ({ + script = '', + fileName = '', + type = 'recorder', + isEdit = false, + }: { + isEditable?: boolean; + script?: string; + fileName?: string; + type?: 'recorder' | 'inline'; + isEdit?: boolean; + }) => { + return ( + + ); + }; + + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('renders ScriptRecorderFields as the default tab', () => { + const { getByText } = render(); + + expect(getByText('Select or drag and drop a .js file')).toBeInTheDocument(); + }); + + it('changes to code editor when selected', async () => { + const script = 'test script'; + const { getByTestId } = render(); + expect(getByTestId('codeEditorContainer')).toBeInTheDocument(); + }); + + it('displays code editor by default in edit flow', async () => { + const fileName = 'fileName'; + const script = 'test script'; + const { getByTestId } = render( + + ); + expect(getByTestId('codeEditorContainer')).toBeInTheDocument(); + }); + + it('displays filename of existing script in edit flow', async () => { + const fileName = 'fileName'; + const script = 'test script'; + const { getByText } = render( + + ); + userEvent.click(getByText(/Upload new script/)); + expect(getByText(fileName)).toBeInTheDocument(); + }); +}); diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/fields/source_field.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/fields/source_field.tsx new file mode 100644 index 00000000000000..6ddb0b27a8f6b7 --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/fields/source_field.tsx @@ -0,0 +1,179 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import React, { useEffect, useState } from 'react'; +import styled from 'styled-components'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { i18n } from '@kbn/i18n'; +import { + EuiTabbedContent, + EuiFormRow, + EuiBetaBadge, + EuiFlexGroup, + EuiFlexItem, +} from '@elastic/eui'; +import { CodeEditor } from './code_editor'; +import { ScriptRecorderFields } from './script_recorder_fields'; +import { ConfigKey, MonacoEditorLangId } from '../types'; + +enum SourceType { + INLINE = 'syntheticsBrowserInlineConfig', + SCRIPT_RECORDER = 'syntheticsBrowserScriptRecorderConfig', + ZIP = 'syntheticsBrowserZipURLConfig', +} + +interface SourceConfig { + script: string; + type: 'recorder' | 'inline'; + fileName?: string; +} + +interface Props { + onChange: (sourceConfig: SourceConfig) => void; + onBlur: (field: ConfigKey) => void; + value: SourceConfig; + isEditFlow?: boolean; +} + +export const SourceField = ({ onChange, onBlur, value, isEditFlow = false }: Props) => { + const [sourceType, setSourceType] = useState( + value.type === 'inline' ? SourceType.INLINE : SourceType.SCRIPT_RECORDER + ); + const [config, setConfig] = useState(value); + + useEffect(() => { + onChange(config); + }, [config, onChange]); + + const allTabs = [ + { + id: 'syntheticsBrowserScriptRecorderConfig', + name: ( + + + {isEditFlow ? ( + + ) : ( + + )} + + + + + + ), + 'data-test-subj': 'syntheticsSourceTab__scriptRecorder', + content: ( + { + setConfig((prevConfig) => ({ + ...prevConfig, + script: scriptText, + type: 'recorder', + fileName, + })); + }} + script={config.script} + isEditable={isEditFlow} + fileName={config.fileName} + /> + ), + }, + { + id: 'syntheticsBrowserInlineConfig', + name: ( + + ), + 'data-test-subj': `syntheticsSourceTab__inline`, + content: ( + + } + fullWidth + > + { + setConfig((prevConfig) => ({ ...prevConfig, script: code })); + onBlur(ConfigKey.SOURCE_INLINE); + }} + value={config.script} + placeholder={i18n.translate( + 'xpack.synthetics.addEditMonitor.scriptEditor.placeholder', + { + defaultMessage: '// Paste your Playwright script here...', + } + )} + /> + + ), + }, + ]; + + if (isEditFlow) { + allTabs.reverse(); + } + + return ( + tab.id === SourceType.INLINE) + : allTabs.find((tab) => tab.id === sourceType) + } + autoFocus="selected" + onTabClick={(tab) => { + if (tab.id !== sourceType) { + setConfig({ + script: '', + type: tab.id === SourceType.INLINE ? 'inline' : 'recorder', + fileName: '', + }); + } + setSourceType(tab.id as SourceType); + }} + /> + ); +}; + +const StyledBetaBadgeWrapper = styled(EuiFlexItem)` + .euiToolTipAnchor { + display: flex; + } +`; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/fields/uploader.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/fields/uploader.tsx new file mode 100644 index 00000000000000..e028e24504f031 --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/fields/uploader.tsx @@ -0,0 +1,96 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { useState, useRef } from 'react'; + +import { i18n } from '@kbn/i18n'; + +import { EuiFormRow, EuiFilePicker } from '@elastic/eui'; + +interface Props { + onUpload: ({ scriptText, fileName }: { scriptText: string; fileName: string }) => void; +} + +export function Uploader({ onUpload }: Props) { + const fileReader = useRef(null); + const [error, setError] = useState(null); + const filePickerRef = useRef(null); + + const handleFileRead = (fileName: string) => { + const content = fileReader?.current?.result as string; + + if (content?.trim().slice(0, 4) !== 'step') { + setError(PARSING_ERROR); + filePickerRef.current?.removeFiles(); + return; + } + + onUpload({ scriptText: content, fileName }); + setError(null); + }; + + const handleFileChosen = (files: FileList | null) => { + if (!files || !files.length) { + onUpload({ scriptText: '', fileName: '' }); + return; + } + if (files.length && !files[0].type.includes('javascript')) { + setError(INVALID_FILE_ERROR); + filePickerRef.current?.removeFiles(); + return; + } + fileReader.current = new FileReader(); + fileReader.current.onloadend = () => handleFileRead(files[0].name); + fileReader.current.readAsText(files[0]); + }; + + return ( + + + + ); +} + +const TESTING_SCRIPT_LABEL = i18n.translate( + 'xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.uploader.fieldLabel', + { + defaultMessage: 'Testing script', + } +); + +const PROMPT_TEXT = i18n.translate('xpack.synthetics.monitorConfig.uploader.label', { + defaultMessage: 'Select or drag and drop a .js file', +}); + +const INVALID_FILE_ERROR = i18n.translate( + 'xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.uploader.invalidFileError', + { + defaultMessage: + 'Invalid file type. Please upload a .js file generated by the Elastic Synthetics Recorder.', + } +); + +const PARSING_ERROR = i18n.translate( + 'xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.uploader.parsingError', + { + defaultMessage: + 'Error uploading file. Please upload a .js file generated by the Elastic Synthetics Recorder in inline script format.', + } +); diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/controlled_field.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/controlled_field.tsx new file mode 100644 index 00000000000000..8248500d351c50 --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/controlled_field.tsx @@ -0,0 +1,92 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import React from 'react'; +import { EuiFormRow, EuiFormRowProps } from '@elastic/eui'; +import { useSelector } from 'react-redux'; +import { + UseFormReturn, + ControllerRenderProps, + ControllerFieldState, + useFormContext, +} from 'react-hook-form'; +import { useKibanaSpace, useIsEditFlow } from '../hooks'; +import { selectServiceLocationsState } from '../../../state'; +import { FieldMeta } from '../types'; + +type Props = FieldMeta & { + component: React.ComponentType; + field: ControllerRenderProps; + fieldState: ControllerFieldState; + formRowProps: Partial; + error: React.ReactNode; + dependenciesValues: unknown[]; + dependenciesFieldMeta: Record; +}; + +const setFieldValue = (key: string, setValue: UseFormReturn['setValue']) => (value: any) => { + setValue(key, value); +}; + +export const ControlledField = ({ + component: FieldComponent, + props, + fieldKey, + shouldUseSetValue, + field, + formRowProps, + fieldState, + customHook, + error, + dependenciesValues, + dependenciesFieldMeta, +}: Props) => { + const { setValue, reset, formState } = useFormContext(); + const noop = () => {}; + let hook: Function = noop; + let hookProps; + const { locations } = useSelector(selectServiceLocationsState); + const { space } = useKibanaSpace(); + const isEdit = useIsEditFlow(); + if (customHook) { + hookProps = customHook(field.value); + hook = hookProps.func; + } + const { [hookProps?.fieldKey as string]: hookResult } = hook(hookProps?.params) || {}; + const onChange = shouldUseSetValue ? setFieldValue(fieldKey, setValue) : field.onChange; + const generatedProps = props + ? props({ + field, + setValue, + reset, + locations, + dependencies: dependenciesValues, + dependenciesFieldMeta, + space: space?.id, + isEdit, + formState, + }) + : {}; + const isInvalid = hookResult || Boolean(fieldState.error); + const hookError = hookResult ? hookProps?.error : undefined; + return ( + + + + ); +}; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/defaults.test.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/defaults.test.tsx new file mode 100644 index 00000000000000..192c76e414b07a --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/defaults.test.tsx @@ -0,0 +1,185 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { ConfigKey, DataStream, FormMonitorType, SyntheticsMonitor } from '../types'; +import { DEFAULT_FIELDS } from '../constants'; +import { formatDefaultFormValues } from './defaults'; + +describe('defaults', () => { + const testScript = 'testScript'; + const monitorValues = { + __ui: { + script_source: { + file_name: '', + is_generated_script: false, + }, + }, + enabled: true, + 'filter_journeys.match': '', + 'filter_journeys.tags': [], + form_monitor_type: 'multistep', + ignore_https_errors: false, + journey_id: '', + locations: [ + { + id: 'us_central', + isServiceManaged: true, + }, + ], + name: 'Browser monitor', + namespace: 'default', + origin: 'ui', + params: '', + playwright_options: '', + playwright_text_assertion: '', + project_id: '', + schedule: { + number: '10', + unit: 'm', + }, + screenshots: 'on', + 'service.name': '', + 'source.inline.script': testScript, + 'source.project.content': '', + 'source.zip_url.folder': '', + 'source.zip_url.password': '', + 'source.zip_url.proxy_url': '', + 'source.zip_url.ssl.certificate': undefined, + 'source.zip_url.ssl.certificate_authorities': undefined, + 'source.zip_url.ssl.key': undefined, + 'source.zip_url.ssl.key_passphrase': undefined, + 'source.zip_url.ssl.supported_protocols': undefined, + 'source.zip_url.ssl.verification_mode': undefined, + 'source.zip_url.url': '', + 'source.zip_url.username': '', + 'ssl.certificate': '', + 'ssl.certificate_authorities': '', + 'ssl.key': '', + 'ssl.key_passphrase': '', + 'ssl.supported_protocols': ['TLSv1.1', 'TLSv1.2', 'TLSv1.3'], + 'ssl.verification_mode': 'full', + synthetics_args: [], + tags: [], + 'throttling.config': '5d/3u/20l', + 'throttling.download_speed': '5', + 'throttling.is_enabled': true, + 'throttling.latency': '20', + 'throttling.upload_speed': '3', + timeout: '16', + type: 'browser', + 'url.port': null, + urls: '', + } as SyntheticsMonitor; + + it('correctly formats monitor type to form type', () => { + expect(formatDefaultFormValues(monitorValues)).toEqual({ + __ui: { + script_source: { + file_name: '', + is_generated_script: false, + }, + }, + enabled: true, + 'filter_journeys.match': '', + 'filter_journeys.tags': [], + form_monitor_type: 'multistep', + ignore_https_errors: false, + journey_id: '', + locations: [ + { + id: 'us_central', + isServiceManaged: true, + }, + ], + name: 'Browser monitor', + namespace: 'default', + origin: 'ui', + params: '', + playwright_options: '', + playwright_text_assertion: '', + project_id: '', + schedule: { + number: '10', + unit: 'm', + }, + screenshots: 'on', + 'service.name': '', + 'source.inline': { + fileName: '', + script: 'testScript', + type: 'inline', + }, + 'source.inline.script': 'testScript', + 'source.project.content': '', + 'source.zip_url.folder': '', + 'source.zip_url.password': '', + 'source.zip_url.proxy_url': '', + 'source.zip_url.ssl.certificate': undefined, + 'source.zip_url.ssl.certificate_authorities': undefined, + 'source.zip_url.ssl.key': undefined, + 'source.zip_url.ssl.key_passphrase': undefined, + 'source.zip_url.ssl.supported_protocols': undefined, + 'source.zip_url.ssl.verification_mode': undefined, + 'source.zip_url.url': '', + 'source.zip_url.username': '', + 'ssl.certificate': '', + 'ssl.certificate_authorities': '', + 'ssl.key': '', + 'ssl.key_passphrase': '', + 'ssl.supported_protocols': ['TLSv1.1', 'TLSv1.2', 'TLSv1.3'], + 'ssl.verification_mode': 'full', + synthetics_args: [], + tags: [], + 'throttling.config': '5d/3u/20l', + 'throttling.download_speed': '5', + 'throttling.is_enabled': true, + 'throttling.latency': '20', + 'throttling.upload_speed': '3', + timeout: '16', + type: 'browser', + 'url.port': null, + urls: '', + }); + }); + + it.each([ + [DataStream.HTTP, 'testCA'], + [DataStream.HTTP, ''], + [DataStream.TCP, 'testCA'], + [DataStream.TCP, ''], + ])('correctly formats isTLSEnabled', (formType, testCA) => { + const monitor = { + ...DEFAULT_FIELDS[formType as DataStream], + [ConfigKey.FORM_MONITOR_TYPE]: formType as unknown as FormMonitorType, + [ConfigKey.TLS_CERTIFICATE_AUTHORITIES]: testCA, + }; + expect(formatDefaultFormValues(monitor)).toEqual({ + ...monitor, + isTLSEnabled: Boolean(testCA), + [ConfigKey.TLS_CERTIFICATE_AUTHORITIES]: testCA, + }); + }); + + it.each([ + [DataStream.HTTP, FormMonitorType.HTTP], + [DataStream.TCP, FormMonitorType.TCP], + [DataStream.ICMP, FormMonitorType.ICMP], + [DataStream.BROWSER, FormMonitorType.MULTISTEP], + ])( + 'correctly formats legacy uptime monitors to include ConfigKey.FORM_MONITOR_TYPE', + (dataStream, formType) => { + const monitor = { + ...DEFAULT_FIELDS[dataStream], + [ConfigKey.FORM_MONITOR_TYPE]: undefined, + }; + expect(formatDefaultFormValues(monitor as unknown as SyntheticsMonitor)).toEqual( + expect.objectContaining({ + [ConfigKey.FORM_MONITOR_TYPE]: formType, + }) + ); + } + ); +}); diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/defaults.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/defaults.tsx new file mode 100644 index 00000000000000..c8412a866dbb7e --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/defaults.tsx @@ -0,0 +1,109 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { isEqual } from 'lodash'; +import { DEFAULT_FIELDS, DEFAULT_TLS_FIELDS } from '../constants'; +import { + ConfigKey, + DataStream, + FormMonitorType, + SyntheticsMonitor, + BrowserFields, + TLSFields, +} from '../types'; + +export const getDefaultFormFields = ( + spaceId: string = 'default' +): Record> => { + return { + [FormMonitorType.MULTISTEP]: { + ...DEFAULT_FIELDS[DataStream.BROWSER], + 'source.inline': { + type: 'recorder', + script: '', + fileName: '', + }, + [ConfigKey.FORM_MONITOR_TYPE]: FormMonitorType.MULTISTEP, + [ConfigKey.NAMESPACE]: spaceId, + }, + [FormMonitorType.SINGLE]: { + ...DEFAULT_FIELDS[DataStream.BROWSER], + [ConfigKey.FORM_MONITOR_TYPE]: FormMonitorType.SINGLE, + [ConfigKey.NAMESPACE]: spaceId, + }, + [FormMonitorType.HTTP]: { + ...DEFAULT_FIELDS[DataStream.HTTP], + isTLSEnabled: false, + [ConfigKey.FORM_MONITOR_TYPE]: FormMonitorType.HTTP, + [ConfigKey.NAMESPACE]: spaceId, + }, + [FormMonitorType.TCP]: { + ...DEFAULT_FIELDS[DataStream.TCP], + isTLSEnabled: false, + [ConfigKey.FORM_MONITOR_TYPE]: FormMonitorType.TCP, + [ConfigKey.NAMESPACE]: spaceId, + }, + [FormMonitorType.ICMP]: { + ...DEFAULT_FIELDS[DataStream.ICMP], + [ConfigKey.FORM_MONITOR_TYPE]: FormMonitorType.ICMP, + [ConfigKey.NAMESPACE]: spaceId, + }, + }; +}; + +export const formatDefaultFormValues = (monitor?: SyntheticsMonitor) => { + if (!monitor) return undefined; + + let formMonitorType = monitor[ConfigKey.FORM_MONITOR_TYPE]; + const monitorType = monitor[ConfigKey.MONITOR_TYPE]; + const monitorWithFormMonitorType = { + ...monitor, + }; + + // handle default monitor types from Uptime, which don't contain `ConfigKey.FORM_MONITOR_TYPE` + if (!formMonitorType) { + formMonitorType = + monitorType === DataStream.BROWSER + ? FormMonitorType.MULTISTEP + : (monitorType as Omit as FormMonitorType); + monitorWithFormMonitorType[ConfigKey.FORM_MONITOR_TYPE] = formMonitorType; + } + + switch (formMonitorType) { + case FormMonitorType.MULTISTEP: + const browserMonitor = monitor as BrowserFields; + return { + ...monitorWithFormMonitorType, + 'source.inline': { + type: browserMonitor[ConfigKey.METADATA]?.script_source?.is_generated_script + ? 'recorder' + : 'inline', + script: browserMonitor[ConfigKey.SOURCE_INLINE], + fileName: browserMonitor[ConfigKey.METADATA]?.script_source?.file_name, + }, + }; + case FormMonitorType.SINGLE: + case FormMonitorType.ICMP: + return { + ...monitorWithFormMonitorType, + }; + case FormMonitorType.HTTP: + case FormMonitorType.TCP: + return { + ...monitorWithFormMonitorType, + isTLSEnabled: isCustomTLSEnabled(monitor), + }; + } +}; + +const isCustomTLSEnabled = (monitor: SyntheticsMonitor) => { + const sslKeys = Object.keys(monitor).filter((key) => key.includes('ssl')) as unknown as Array< + keyof TLSFields + >; + const sslValues: Record = {}; + sslKeys.map((key) => (sslValues[key] = (monitor as TLSFields)[key])); + return !isEqual(sslValues, DEFAULT_TLS_FIELDS); +}; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/disclaimer.test.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/disclaimer.test.tsx new file mode 100644 index 00000000000000..2265b035876f73 --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/disclaimer.test.tsx @@ -0,0 +1,45 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { render } from '../../../utils/testing/rtl_helpers'; +import * as formContext from 'react-hook-form'; +import { Disclaimer } from './disclaimer'; +import { ServiceLocations } from '../types'; + +export const mockLocation = { + label: 'US Central', + id: 'us_central', + geo: { + lat: 1, + lon: 1, + }, + url: 'url', + isServiceManaged: true, +}; +describe('', () => { + beforeEach(() => { + jest.spyOn(formContext, 'useFormContext').mockReturnValue({ + watch: () => [[mockLocation] as ServiceLocations], + } as unknown as formContext.UseFormReturn); + }); + + it('shows disclaimer when ', () => { + const { getByText } = render(); + + expect(getByText(/You consent/)).toBeInTheDocument(); + }); + + it('does not show disclaimer when locations are not service managed', () => { + jest.spyOn(formContext, 'useFormContext').mockReturnValue({ + watch: () => [[{ ...mockLocation, isServiceManaged: false }] as ServiceLocations], + } as unknown as formContext.UseFormReturn); + const { queryByText } = render(); + + expect(queryByText(/You consent/)).not.toBeInTheDocument(); + }); +}); diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/disclaimer.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/disclaimer.tsx new file mode 100644 index 00000000000000..58e182be0b0537 --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/disclaimer.tsx @@ -0,0 +1,33 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { i18n } from '@kbn/i18n'; +import { EuiText, EuiSpacer } from '@elastic/eui'; +import { useFormContext } from 'react-hook-form'; +import { ConfigKey, MonitorServiceLocation } from '../types'; + +export const Disclaimer: React.FC = () => { + const { watch } = useFormContext(); + const [locations]: [locations: MonitorServiceLocation[]] = watch([ConfigKey.LOCATIONS]); + + const includesServiceLocation = locations.find((location) => location.isServiceManaged === true); + + return includesServiceLocation ? ( + <> + + +

+ {i18n.translate('xpack.synthetics.monitorConfig.locations.disclaimer', { + defaultMessage: + 'You consent to the transfer of testing instructions and the output of such instructions (including any data shown therein) to your selected testing location, on infrastructure provided by a cloud service provider chosen by Elastic.', + })} +

+
+ + ) : null; +}; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/field.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/field.tsx new file mode 100644 index 00000000000000..fbb0943b5f7732 --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/field.tsx @@ -0,0 +1,134 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import React, { memo, useEffect, useState } from 'react'; +import { useSelector } from 'react-redux'; +import { Controller, useFormContext, FieldError, ControllerFieldState } from 'react-hook-form'; +import { EuiFormRow } from '@elastic/eui'; +import { selectServiceLocationsState } from '../../../state'; +import { useKibanaSpace, useIsEditFlow } from '../hooks'; +import { ControlledField } from './controlled_field'; +import { FieldMeta } from '../types'; + +type Props = FieldMeta & { fieldError?: FieldError }; + +export const Field = memo( + ({ + component: Component, + helpText, + label, + ariaLabel, + props, + fieldKey, + controlled, + showWhen, + shouldUseSetValue, + required, + validation, + error, + fieldError, + dependencies, + customHook, + }: Props) => { + const { register, watch, control, setValue, reset, getFieldState, formState } = + useFormContext(); + const { locations } = useSelector(selectServiceLocationsState); + const { space } = useKibanaSpace(); + const isEdit = useIsEditFlow(); + const [dependenciesFieldMeta, setDependenciesFieldMeta] = useState< + Record + >({}); + let show = true; + let dependenciesValues: unknown[] = []; + if (showWhen) { + const [showKey, expectedValue] = showWhen; + const [actualValue] = watch([showKey]); + show = actualValue === expectedValue; + } + if (dependencies) { + dependenciesValues = watch(dependencies); + } + useEffect(() => { + if (dependencies) { + dependencies.forEach((dependency) => { + setDependenciesFieldMeta((prevState) => ({ + ...prevState, + [dependency]: getFieldState(dependency), + })); + }); + } + // run effect when dependencies values change, to get the most up to date meta state + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [JSON.stringify(dependenciesValues || []), dependencies, getFieldState]); + + if (!show) { + return null; + } + + const formRowProps = { + label, + 'aria-label': ariaLabel, + helpText, + fullWidth: true, + }; + + return controlled ? ( + { + return ( + + ); + }} + /> + ) : ( + + + + ); + } +); diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/field_config.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/field_config.tsx new file mode 100644 index 00000000000000..b3d7f10c2b7b53 --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/field_config.tsx @@ -0,0 +1,980 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { UseFormReturn, ControllerRenderProps, FormState } from 'react-hook-form'; +import { + EuiButtonGroup, + EuiCheckbox, + EuiCode, + EuiComboBox, + EuiComboBoxOptionOption, + EuiComboBoxProps, + EuiFlexGroup, + EuiFlexItem, + EuiFieldText, + EuiFieldNumber, + EuiFieldPassword, + EuiSelect, + EuiSuperSelect, + EuiSwitch, + EuiText, + EuiLink, + EuiTextArea, +} from '@elastic/eui'; +import { useMonitorName } from '../hooks/use_monitor_name'; +import { MonitorTypeRadioGroup } from '../fields/monitor_type_radio_group'; +import { + ConfigKey, + DataStream, + FormMonitorType, + HTTPMethod, + MonitorFields, + MonitorServiceLocations, + ScreenshotOption, + ServiceLocations, + SyntheticsMonitor, + TLSVersion, + VerificationMode, + FieldMeta, +} from '../types'; +import { DEFAULT_BROWSER_ADVANCED_FIELDS } from '../constants'; +import { HeaderField } from '../fields/header_field'; +import { RequestBodyField } from '../fields/request_body_field'; +import { ResponseBodyIndexField } from '../fields/index_response_body_field'; +import { ComboBox } from '../fields/combo_box'; +import { SourceField } from '../fields/source_field'; +import { getDefaultFormFields } from './defaults'; +import { validate, validateHeaders, WHOLE_NUMBERS_ONLY, FLOATS_ONLY } from './validation'; + +const getScheduleContent = (value: number) => { + if (value > 60) { + return i18n.translate('xpack.synthetics.monitorConfig.schedule.label', { + defaultMessage: 'Every {value, number} {value, plural, one {hour} other {hours}}', + values: { + value: value / 60, + }, + }); + } else { + return i18n.translate('xpack.synthetics.monitorConfig.schedule.minutes.label', { + defaultMessage: 'Every {value, number} {value, plural, one {minute} other {minutes}}', + values: { + value, + }, + }); + } +}; + +const getScheduleConfig = (schedules: number[]) => { + return schedules.map((value) => ({ + value: `${value}`, + text: getScheduleContent(value), + })); +}; + +const BROWSER_SCHEDULES = getScheduleConfig([3, 5, 10, 15, 30, 60, 120, 240]); + +const LIGHTWEIGHT_SCHEDULES = getScheduleConfig([1, 3, 5, 10, 15, 30, 60]); + +export const MONITOR_TYPE_CONFIG = { + [FormMonitorType.MULTISTEP]: { + id: 'syntheticsMonitorTypeMultistep', + 'data-test-subj': 'syntheticsMonitorTypeMultistep', + label: i18n.translate('xpack.synthetics.monitorConfig.monitorType.multiStep.label', { + defaultMessage: 'Multistep', + }), + value: FormMonitorType.MULTISTEP, + descriptionTitle: i18n.translate('xpack.synthetics.monitorConfig.monitorType.multiStep.title', { + defaultMessage: 'Multistep Browser Journey', + }), + description: i18n.translate( + 'xpack.synthetics.monitorConfig.monitorType.multiStep.description', + { + defaultMessage: + 'Navigate through multiple steps or pages to test key user flows from a real browser.', + } + ), + link: '#', + icon: 'videoPlayer', + beta: true, + }, + [FormMonitorType.SINGLE]: { + id: 'syntheticsMonitorTypeSingle', + 'data-test-subj': 'syntheticsMonitorTypeSingle', + label: i18n.translate('xpack.synthetics.monitorConfig.monitorType.singlePage.label', { + defaultMessage: 'Single Page', + }), + value: FormMonitorType.SINGLE, + descriptionTitle: i18n.translate( + 'xpack.synthetics.monitorConfig.monitorType.singlePage.title', + { + defaultMessage: 'Single Page Browser Test', + } + ), + description: i18n.translate( + 'xpack.synthetics.monitorConfig.monitorType.singlePage.description', + { + defaultMessage: + 'Test a single page load including all objects on the page from a real web browser.', + } + ), + link: '#', + icon: 'videoPlayer', + beta: true, + }, + [FormMonitorType.HTTP]: { + id: 'syntheticsMonitorTypeHTTP', + 'data-test-subj': 'syntheticsMonitorTypeHTTP', + label: i18n.translate('xpack.synthetics.monitorConfig.monitorType.http.label', { + defaultMessage: 'HTTP Ping', + }), + value: FormMonitorType.HTTP, + descriptionTitle: i18n.translate('xpack.synthetics.monitorConfig.monitorType.http.title', { + defaultMessage: 'HTTP Ping', + }), + description: i18n.translate('xpack.synthetics.monitorConfig.monitorType.http.description', { + defaultMessage: + 'A lightweight API check to validate the availability of a web service or endpoint.', + }), + link: '#', + icon: 'online', + beta: false, + }, + [FormMonitorType.TCP]: { + id: 'syntheticsMonitorTypeTCP', + 'data-test-subj': 'syntheticsMonitorTypeTCP', + label: i18n.translate('xpack.synthetics.monitorConfig.monitorType.tcp.label', { + defaultMessage: 'TCP Ping', + }), + value: FormMonitorType.TCP, + descriptionTitle: i18n.translate('xpack.synthetics.monitorConfig.monitorType.tcp.title', { + defaultMessage: 'TCP Ping', + }), + description: i18n.translate('xpack.synthetics.monitorConfig.monitorType.tcp.description', { + defaultMessage: + 'A lightweight API check to validate the availability of a web service or endpoint.', + }), + link: '#', + icon: 'online', + beta: false, + }, + [FormMonitorType.ICMP]: { + id: 'syntheticsMonitorTypeICMP', + 'data-test-subj': 'syntheticsMonitorTypeICMP', + label: i18n.translate('xpack.synthetics.monitorConfig.monitorType.icmp.label', { + defaultMessage: 'ICMP Ping', + }), + value: FormMonitorType.ICMP, + descriptionTitle: i18n.translate('xpack.synthetics.monitorConfig.monitorType.icmp.title', { + defaultMessage: 'ICMP Ping', + }), + description: i18n.translate('xpack.synthetics.monitorConfig.monitorType.icmp.description', { + defaultMessage: + 'A lightweight API check to validate the availability of a web service or endpoint.', + }), + link: '#', + icon: 'online', + beta: false, + }, +}; + +export const FIELD: Record = { + [ConfigKey.FORM_MONITOR_TYPE]: { + fieldKey: ConfigKey.FORM_MONITOR_TYPE, + required: true, + component: MonitorTypeRadioGroup, + ariaLabel: i18n.translate('xpack.synthetics.monitorConfig.monitorType.label', { + defaultMessage: 'Monitor type', + }), + controlled: true, + props: ({ field, reset, space }) => ({ + onChange: (_: string, monitorType: FormMonitorType) => { + const defaultFields = getDefaultFormFields(space)[monitorType]; + reset(defaultFields); + }, + selectedOption: field?.value, + options: Object.values(MONITOR_TYPE_CONFIG), + }), + validation: () => ({ + required: true, + }), + }, + [`${ConfigKey.URLS}__single`]: { + fieldKey: ConfigKey.URLS, + required: true, + component: EuiFieldText, + label: i18n.translate('xpack.synthetics.monitorConfig.urlsSingle.label', { + defaultMessage: 'Website URL', + }), + helpText: i18n.translate('xpack.synthetics.monitorConfig.urlsSingle.helpText', { + defaultMessage: 'For example, https://www.elastic.co.', + }), + controlled: true, + dependencies: [ConfigKey.NAME], + props: ({ setValue, dependenciesFieldMeta, isEdit, formState }) => { + return { + 'data-test-subj': 'syntheticsMonitorConfigURL', + onChange: (event: React.ChangeEvent) => { + setValue(ConfigKey.URLS, event.target.value, { + shouldValidate: Boolean(formState.submitCount > 0), + }); + if (!dependenciesFieldMeta[ConfigKey.NAME].isDirty && !isEdit) { + setValue(ConfigKey.NAME, event.target.value, { + shouldValidate: Boolean(formState.submitCount > 0), + }); + } + }, + }; + }, + }, + [`${ConfigKey.URLS}__http`]: { + fieldKey: ConfigKey.URLS, + required: true, + component: EuiFieldText, + label: i18n.translate('xpack.synthetics.monitorConfig.urls.label', { + defaultMessage: 'URL', + }), + helpText: i18n.translate('xpack.synthetics.monitorConfig.urls.helpText', { + defaultMessage: 'For example, your service endpoint.', + }), + controlled: true, + dependencies: [ConfigKey.NAME], + props: ({ setValue, dependenciesFieldMeta, isEdit, formState }) => { + return { + onChange: (event: React.ChangeEvent) => { + setValue(ConfigKey.URLS, event.target.value, { + shouldValidate: Boolean(formState.submitCount > 0), + }); + if (!dependenciesFieldMeta[ConfigKey.NAME].isDirty && !isEdit) { + setValue(ConfigKey.NAME, event.target.value, { + shouldValidate: Boolean(formState.submitCount > 0), + }); + } + }, + 'data-test-subj': 'syntheticsMonitorConfigURL', + }; + }, + }, + [`${ConfigKey.HOSTS}__tcp`]: { + fieldKey: ConfigKey.HOSTS, + required: true, + component: EuiFieldText, + label: i18n.translate('xpack.synthetics.monitorConfig.hostsTCP.label', { + defaultMessage: 'Host:Port', + }), + controlled: true, + dependencies: [ConfigKey.NAME], + props: ({ setValue, dependenciesFieldMeta, isEdit, formState }) => { + return { + onChange: (event: React.ChangeEvent) => { + setValue(ConfigKey.HOSTS, event.target.value, { + shouldValidate: Boolean(formState.submitCount > 0), + }); + if (!dependenciesFieldMeta[ConfigKey.NAME].isDirty && !isEdit) { + setValue(ConfigKey.NAME, event.target.value, { + shouldValidate: Boolean(formState.submitCount > 0), + }); + } + }, + 'data-test-subj': 'syntheticsMonitorConfigHost', + }; + }, + }, + [`${ConfigKey.HOSTS}__icmp`]: { + fieldKey: ConfigKey.HOSTS, + required: true, + component: EuiFieldText, + label: i18n.translate('xpack.synthetics.monitorConfig.hostsICMP.label', { + defaultMessage: 'Host', + }), + controlled: true, + dependencies: [ConfigKey.NAME], + props: ({ setValue, dependenciesFieldMeta, isEdit, formState }) => { + return { + onChange: (event: React.ChangeEvent) => { + setValue(ConfigKey.HOSTS, event.target.value, { + shouldValidate: Boolean(formState.submitCount > 0), + }); + if (!dependenciesFieldMeta[ConfigKey.NAME].isDirty && !isEdit) { + setValue(ConfigKey.NAME, event.target.value, { + shouldValidate: Boolean(formState.submitCount > 0), + }); + } + }, + 'data-test-subj': 'syntheticsMonitorConfigHost', + }; + }, + }, + [ConfigKey.NAME]: { + fieldKey: ConfigKey.NAME, + required: true, + component: EuiFieldText, + controlled: true, + label: i18n.translate('xpack.synthetics.monitorConfig.name.label', { + defaultMessage: 'Monitor name', + }), + helpText: i18n.translate('xpack.synthetics.monitorConfig.name.helpText', { + defaultMessage: 'Choose a name to help identify this monitor in the future.', + }), + dependencies: [ConfigKey.URLS, ConfigKey.HOSTS], + customHook: (value: unknown) => ({ + fieldKey: 'nameAlreadyExists', + func: useMonitorName, + params: { search: value as string }, + error: i18n.translate('xpack.synthetics.monitorConfig.name.existsError', { + defaultMessage: 'Monitor name already exists', + }), + }), + validation: () => ({ + validate: { + notEmpty: (value) => Boolean(value.trim()), + }, + }), + error: i18n.translate('xpack.synthetics.monitorConfig.name.error', { + defaultMessage: 'Monitor name is required', + }), + props: () => ({ + 'data-test-subj': 'syntheticsMonitorConfigName', + }), + }, + [ConfigKey.SCHEDULE]: { + fieldKey: `${ConfigKey.SCHEDULE}.number`, + required: true, + component: EuiSelect, + label: i18n.translate('xpack.synthetics.monitorConfig.frequency.label', { + defaultMessage: 'Frequency', + }), + helpText: i18n.translate('xpack.synthetics.monitorConfig.frequency.helpText', { + defaultMessage: + 'How often do you want to run this test? Higher frequencies will increase your total cost.', + }), + dependencies: [ConfigKey.MONITOR_TYPE], + props: ({ dependencies }) => { + const [monitorType] = dependencies; + return { + 'data-test-subj': 'syntheticsMonitorConfigSchedule', + options: monitorType === DataStream.BROWSER ? BROWSER_SCHEDULES : LIGHTWEIGHT_SCHEDULES, + }; + }, + }, + [ConfigKey.LOCATIONS]: { + fieldKey: ConfigKey.LOCATIONS, + required: true, + controlled: true, + component: EuiComboBox as React.ComponentType>, + label: i18n.translate('xpack.synthetics.monitorConfig.locations.label', { + defaultMessage: 'Locations', + }), + helpText: i18n.translate('xpack.synthetics.monitorConfig.locations.helpText', { + defaultMessage: + 'Where do you want to run this test from? Additional locations will increase your total cost.', + }), + props: ({ + field, + setValue, + locations, + formState, + }: { + field?: ControllerRenderProps; + setValue: UseFormReturn['setValue']; + locations: ServiceLocations; + formState: FormState; + }) => { + return { + options: Object.values(locations).map((location) => ({ + label: locations?.find((loc) => location.id === loc.id)?.label, + id: location.id, + isServiceManaged: location.isServiceManaged, + })), + selectedOptions: Object.values(field?.value as ServiceLocations).map((location) => ({ + label: locations?.find((loc) => location.id === loc.id)?.label, + id: location.id, + isServiceManaged: location.isServiceManaged, + })), + 'data-test-subj': 'syntheticsMonitorConfigLocations', + onChange: (updatedValues: ServiceLocations) => { + setValue( + ConfigKey.LOCATIONS, + updatedValues.map((location) => ({ + id: location.id, + isServiceManaged: location.isServiceManaged, + })) as MonitorServiceLocations, + { shouldValidate: Boolean(formState.submitCount > 0) } + ); + }, + }; + }, + }, + [ConfigKey.TAGS]: { + fieldKey: ConfigKey.TAGS, + component: ComboBox, + label: i18n.translate('xpack.synthetics.monitorConfig.tags.label', { + defaultMessage: 'Tags', + }), + helpText: i18n.translate('xpack.synthetics.monitorConfig.tags.helpText', { + defaultMessage: + 'A list of tags that will be sent with each monitor event. Useful for searching and segmenting data.', + }), + controlled: true, + props: ({ field }) => ({ + selectedOptions: field?.value, + }), + }, + [ConfigKey.TIMEOUT]: { + fieldKey: ConfigKey.TIMEOUT, + component: EuiFieldNumber, + label: i18n.translate('xpack.synthetics.monitorConfig.timeout.label', { + defaultMessage: 'Timeout in seconds', + }), + helpText: i18n.translate('xpack.synthetics.monitorConfig.timeout.helpText', { + defaultMessage: 'The total time allowed for testing the connection and exchanging data.', + }), + props: () => ({ + min: 1, + step: 'any', + }), + dependencies: [ConfigKey.SCHEDULE], + validation: ([schedule]) => { + return { + validate: (value) => { + switch (true) { + case value < 0: + return i18n.translate('xpack.synthetics.monitorConfig.timeout.greaterThan0Error', { + defaultMessage: 'Timeout must be greater than or equal to 0.', + }); + case value > parseFloat((schedule as MonitorFields[ConfigKey.SCHEDULE]).number) * 60: + return i18n.translate('xpack.synthetics.monitorConfig.timeout.scheduleError', { + defaultMessage: 'Timemout must be less than the monitor frequency.', + }); + case !Boolean(`${value}`.match(FLOATS_ONLY)): + return i18n.translate('xpack.synthetics.monitorConfig.timeout.formatError', { + defaultMessage: 'Timeout is invalid.', + }); + default: + return true; + } + }, + }; + }, + }, + [ConfigKey.APM_SERVICE_NAME]: { + fieldKey: ConfigKey.APM_SERVICE_NAME, + component: EuiFieldText, + label: i18n.translate('xpack.synthetics.monitorConfig.apmServiceName.label', { + defaultMessage: 'APM service name', + }), + helpText: i18n.translate('xpack.synthetics.monitorConfig.apmServiceName.helpText', { + defaultMessage: + 'Corrseponds to the service.name ECS field from APM. Set this to enable integrations between APM and Synthetics data.', + }), + controlled: true, + props: ({ field }) => ({ + selectedOptions: field?.value, + 'data-test-subj': 'syntheticsMonitorConfigAPMServiceName', + }), + }, + [ConfigKey.NAMESPACE]: { + fieldKey: ConfigKey.NAMESPACE, + component: EuiFieldText, + label: i18n.translate('xpack.synthetics.monitorConfig.namespace.label', { + defaultMessage: 'Data stream namespace', + }), + helpText: ( + + {i18n.translate('xpack.synthetics.monitorConfig.namespace.helpText', { + defaultMessage: + "Change the default namespace. This setting changes the name of the monitor's data stream. ", + })} + + {i18n.translate('xpack.synthetics.monitorConfig.namespace.learnMore', { + defaultMessage: 'Learn more', + })} + + + ), + controlled: true, + props: ({ field }) => ({ + selectedOptions: field, + }), + }, + [ConfigKey.MAX_REDIRECTS]: { + fieldKey: ConfigKey.MAX_REDIRECTS, + component: EuiFieldNumber, + label: i18n.translate('xpack.synthetics.monitorConfig.maxRedirects.label', { + defaultMessage: 'Max redirects', + }), + helpText: i18n.translate('xpack.synthetics.monitorConfig.maxRedirects.helpText', { + defaultMessage: 'The total number of redirects to follow.', + }), + props: () => ({ + min: 0, + max: 10, + step: 1, + }), + validation: () => ({ + min: 0, + pattern: WHOLE_NUMBERS_ONLY, + }), + error: i18n.translate('xpack.synthetics.monitorConfig.maxRedirects.error', { + defaultMessage: 'Max redirects is invalid.', + }), + }, + [ConfigKey.WAIT]: { + fieldKey: ConfigKey.WAIT, + component: EuiFieldNumber, + label: i18n.translate('xpack.synthetics.monitorConfig.wait.label', { + defaultMessage: 'Wait', + }), + helpText: i18n.translate('xpack.synthetics.monitorConfig.wait.helpText', { + defaultMessage: + 'The duration to wait before emitting another ICMP Echo Request if no response is received.', + }), + props: () => ({ + min: 1, + step: 1, + }), + validation: () => ({ + min: 1, + pattern: WHOLE_NUMBERS_ONLY, + }), + error: i18n.translate('xpack.synthetics.monitorConfig.wait.error', { + defaultMessage: 'Wait duration is invalid.', + }), + }, + [ConfigKey.USERNAME]: { + fieldKey: ConfigKey.USERNAME, + component: EuiFieldText, + label: i18n.translate('xpack.synthetics.monitorConfig.username.label', { + defaultMessage: 'Username', + }), + helpText: i18n.translate('xpack.synthetics.monitorConfig.username.helpText', { + defaultMessage: 'Username for authenticating with the server.', + }), + }, + [ConfigKey.PASSWORD]: { + fieldKey: ConfigKey.PASSWORD, + component: EuiFieldPassword, + label: i18n.translate('xpack.synthetics.monitorConfig.password.label', { + defaultMessage: 'Password', + }), + helpText: i18n.translate('xpack.synthetics.monitorConfig.password.helpText', { + defaultMessage: 'Password for authenticating with the server.', + }), + }, + [ConfigKey.PROXY_URL]: { + fieldKey: ConfigKey.PROXY_URL, + component: EuiFieldText, + label: i18n.translate('xpack.synthetics.monitorConfig.proxyUrl.label', { + defaultMessage: 'Proxy URL', + }), + helpText: i18n.translate('xpack.synthetics.monitorConfig.proxyUrl.helpText', { + defaultMessage: 'HTTP proxy URL', + }), + }, + [ConfigKey.REQUEST_METHOD_CHECK]: { + fieldKey: ConfigKey.REQUEST_METHOD_CHECK, + component: EuiSelect, + label: i18n.translate('xpack.synthetics.monitorConfig.requestMethod.label', { + defaultMessage: 'Request method', + }), + helpText: i18n.translate('xpack.synthetics.monitorConfig.requestMethod.helpText', { + defaultMessage: 'The HTTP method to use.', + }), + props: () => ({ + options: Object.keys(HTTPMethod).map((method) => ({ + value: method, + text: method, + })), + }), + }, + [ConfigKey.REQUEST_HEADERS_CHECK]: { + fieldKey: ConfigKey.REQUEST_HEADERS_CHECK, + component: HeaderField, + label: i18n.translate('xpack.synthetics.monitorConfig.requestHeaders.label', { + defaultMessage: 'Request headers', + }), + helpText: i18n.translate('xpack.synthetics.monitorConfig.requestHeaders.helpText', { + defaultMessage: + 'A dictionary of additional HTTP headers to send. By default the client will set the User-Agent header to identify itself.', + }), + controlled: true, + validation: () => ({ + validate: (headers) => !validateHeaders(headers), + }), + error: i18n.translate('xpack.synthetics.monitorConfig.requestHeaders.error', { + defaultMessage: 'Header key must be a valid HTTP token.', + }), + }, + [ConfigKey.REQUEST_BODY_CHECK]: { + fieldKey: ConfigKey.REQUEST_BODY_CHECK, + component: RequestBodyField, + label: i18n.translate('xpack.synthetics.monitorConfig.requestBody.label', { + defaultMessage: 'Request body', + }), + helpText: i18n.translate('xpack.synthetics.monitorConfig.requestBody.helpText', { + defaultMessage: 'Request body content.', + }), + controlled: true, + }, + [ConfigKey.RESPONSE_HEADERS_INDEX]: { + fieldKey: ConfigKey.RESPONSE_HEADERS_INDEX, + component: EuiCheckbox, + helpText: ( + <> + + http.response.body.headers + + ), + props: () => ({ + label: i18n.translate('xpack.synthetics.monitorConfig.indexResponseHeaders.label', { + defaultMessage: 'Index response headers', + }), + id: 'syntheticsMonitorConfigResponseHeadersIndex', // checkbox needs an id or it won't work + }), + controlled: true, + }, + [ConfigKey.RESPONSE_BODY_INDEX]: { + fieldKey: ConfigKey.RESPONSE_BODY_INDEX, + component: ResponseBodyIndexField, + helpText: ( + <> + + http.response.body.contents + + ), + props: () => ({ + label: i18n.translate('xpack.synthetics.monitorConfig.indexResponseBody.label', { + defaultMessage: 'Index response body', + }), + }), + controlled: true, + }, + [ConfigKey.RESPONSE_STATUS_CHECK]: { + fieldKey: ConfigKey.RESPONSE_STATUS_CHECK, + component: ComboBox, + label: i18n.translate('xpack.synthetics.monitorConfig.responseStatusCheck.label', { + defaultMessage: 'Check response status equals', + }), + helpText: i18n.translate('xpack.synthetics.monitorConfig.responseStatusCheck.helpText', { + defaultMessage: + 'A list of expected status codes. Press enter to add a new code. 4xx and 5xx codes are considered down by default. Other codes are considered up.', + }), + controlled: true, + props: ({ field }) => ({ + selectedOptions: field?.value, + }), + validation: () => ({ + validate: (value) => { + const validateFn = validate[DataStream.HTTP][ConfigKey.RESPONSE_STATUS_CHECK]; + if (validateFn) { + return !validateFn({ + [ConfigKey.RESPONSE_STATUS_CHECK]: value, + }); + } + }, + }), + error: i18n.translate('xpack.synthetics.monitorConfig.responseStatusCheck.error', { + defaultMessage: 'Status code must contain digits only.', + }), + }, + [ConfigKey.RESPONSE_HEADERS_CHECK]: { + fieldKey: ConfigKey.RESPONSE_HEADERS_CHECK, + component: HeaderField, + label: i18n.translate('xpack.synthetics.monitorConfig.responseHeadersCheck.label', { + defaultMessage: 'Check response headers contain', + }), + helpText: i18n.translate('xpack.synthetics.monitorConfig.responseHeadersCheck.helpText', { + defaultMessage: 'A list of expected response headers.', + }), + controlled: true, + validation: () => ({ + validate: (headers) => !validateHeaders(headers), + }), + error: i18n.translate('xpack.synthetics.monitorConfig.responseHeadersCheck.error', { + defaultMessage: 'Header key must be a valid HTTP token.', + }), + }, + [ConfigKey.RESPONSE_BODY_CHECK_POSITIVE]: { + fieldKey: ConfigKey.RESPONSE_BODY_CHECK_POSITIVE, + component: ComboBox, + label: i18n.translate('xpack.synthetics.monitorConfig.responseBodyCheck.label', { + defaultMessage: 'Check response body contains', + }), + helpText: i18n.translate('xpack.synthetics.monitorConfig.responseBodyCheck.helpText', { + defaultMessage: + 'A list of regular expressions to match the body output. Press enter to add a new expression. Only a single expression needs to match.', + }), + controlled: true, + props: ({ field }) => ({ + selectedOptions: field?.value, + }), + }, + [ConfigKey.RESPONSE_BODY_CHECK_NEGATIVE]: { + fieldKey: ConfigKey.RESPONSE_BODY_CHECK_NEGATIVE, + component: ComboBox, + label: i18n.translate('xpack.synthetics.monitorConfig.responseBodyCheckNegative.label', { + defaultMessage: 'Check response body does not contain', + }), + helpText: i18n.translate('xpack.synthetics.monitorConfig.responseBodyCheckNegative.helpText', { + defaultMessage: + 'A list of regular expressions to match the the body output negatively. Press enter to add a new expression. Return match failed if single expression matches.', + }), + controlled: true, + props: ({ field }) => ({ + selectedOptions: field?.value, + }), + }, + [ConfigKey.RESPONSE_RECEIVE_CHECK]: { + fieldKey: ConfigKey.RESPONSE_RECEIVE_CHECK, + component: EuiFieldText, + label: i18n.translate('xpack.synthetics.monitorConfig.responseReceiveCheck.label', { + defaultMessage: 'Check response contains', + }), + helpText: i18n.translate('xpack.synthetics.monitorConfig.responseReceiveCheck.helpText', { + defaultMessage: 'The expected remote host response.', + }), + }, + [`${ConfigKey.PROXY_URL}__tcp`]: { + fieldKey: ConfigKey.PROXY_URL, + component: EuiFieldText, + label: i18n.translate('xpack.synthetics.monitorConfig.proxyURLTCP.label', { + defaultMessage: 'Proxy URL', + }), + helpText: i18n.translate('xpack.synthetics.monitorConfig.proxyURLTCP.helpText', { + defaultMessage: + 'The URL of the SOCKS5 proxy to use when connecting to the server. The value must be a URL with a scheme of socks5://.', + }), + }, + [ConfigKey.REQUEST_SEND_CHECK]: { + fieldKey: ConfigKey.REQUEST_SEND_CHECK, + component: EuiFieldText, + label: i18n.translate('xpack.synthetics.monitorConfig.requestSendCheck.label', { + defaultMessage: 'Request payload', + }), + helpText: i18n.translate('xpack.synthetics.monitorConfig.requestSendCheck.helpText', { + defaultMessage: 'A payload string to send to the remote host.', + }), + }, + [ConfigKey.SOURCE_INLINE]: { + fieldKey: 'source.inline', + required: true, + component: SourceField, + ariaLabel: i18n.translate('xpack.synthetics.monitorConfig.monitorScript.label', { + defaultMessage: 'Monitor script', + }), + controlled: true, + props: ({ isEdit }) => ({ + isEditFlow: isEdit, + }), + validation: () => ({ + validate: (value) => Boolean(value.script), + }), + error: i18n.translate('xpack.synthetics.monitorConfig.monitorScript.error', { + defaultMessage: 'Monitor script is required', + }), + }, + isTLSEnabled: { + fieldKey: 'isTLSEnabled', + component: EuiSwitch, + controlled: true, + props: ({ setValue }) => { + return { + id: 'syntheticsMontiorConfigIsTLSEnabledSwitch', + label: i18n.translate('xpack.synthetics.monitorConfig.customTLS.label', { + defaultMessage: 'Use custom TLS configuration', + }), + onChange: (event: React.ChangeEvent) => { + setValue('isTLSEnabled', event.target.checked); + }, + }; + }, + }, + [ConfigKey.TLS_VERIFICATION_MODE]: { + fieldKey: ConfigKey.TLS_VERIFICATION_MODE, + component: EuiSelect, + label: i18n.translate('xpack.synthetics.monitorConfig.verificationMode.label', { + defaultMessage: 'Verification mode', + }), + helpText: i18n.translate('xpack.synthetics.monitorConfig.verificationMode.helpText', { + defaultMessage: + 'Verifies that the provided certificate is signed by a trusted authority (CA) and also verifies that the server’s hostname (or IP address) matches the names identified within the certificate. If the Subject Alternative Name is empty, it returns an error.', + }), + showWhen: ['isTLSEnabled', true], + props: () => ({ + options: Object.values(VerificationMode).map((method) => ({ + value: method, + text: method.toUpperCase(), + })), + }), + }, + [ConfigKey.TLS_VERSION]: { + fieldKey: ConfigKey.TLS_VERSION, + component: EuiComboBox as React.ComponentType>, + label: i18n.translate('xpack.synthetics.monitorConfig.tlsVersion.label', { + defaultMessage: 'Supported TLS protocols', + }), + controlled: true, + showWhen: ['isTLSEnabled', true], + props: ({ + field, + setValue, + }: { + field?: ControllerRenderProps; + setValue: UseFormReturn['setValue']; + }) => { + return { + options: Object.values(TLSVersion).map((version) => ({ + label: version, + })), + selectedOptions: Object.values(field?.value).map((version) => ({ + label: version, + })), + onChange: (updatedValues: Array>) => { + setValue( + ConfigKey.TLS_VERSION, + updatedValues.map((option) => option.label as TLSVersion) + ); + }, + }; + }, + }, + [ConfigKey.TLS_CERTIFICATE_AUTHORITIES]: { + fieldKey: ConfigKey.TLS_CERTIFICATE_AUTHORITIES, + component: EuiTextArea, + label: i18n.translate('xpack.synthetics.monitorConfig.certificateAuthorities.label', { + defaultMessage: 'Certificate authorities', + }), + helpText: i18n.translate('xpack.synthetics.monitorConfig.certificateAuthorities.helpText', { + defaultMessage: 'PEM-formatted custom certificate authorities.', + }), + showWhen: ['isTLSEnabled', true], + }, + [ConfigKey.TLS_CERTIFICATE]: { + fieldKey: ConfigKey.TLS_CERTIFICATE, + component: EuiTextArea, + label: i18n.translate('xpack.synthetics.monitorConfig.clientCertificate.label', { + defaultMessage: 'Client certificate', + }), + helpText: i18n.translate('xpack.synthetics.monitorConfig.clientCertificate.helpText', { + defaultMessage: 'PEM-formatted certificate for TLS client authentication.', + }), + showWhen: ['isTLSEnabled', true], + }, + [ConfigKey.TLS_KEY]: { + fieldKey: ConfigKey.TLS_KEY, + component: EuiTextArea, + label: i18n.translate('xpack.synthetics.monitorConfig.clientKey.label', { + defaultMessage: 'Client key', + }), + helpText: i18n.translate('xpack.synthetics.monitorConfig.clientKey.helpText', { + defaultMessage: 'PEM-formatted certificate key for TLS client authentication.', + }), + showWhen: ['isTLSEnabled', true], + }, + [ConfigKey.TLS_KEY_PASSPHRASE]: { + fieldKey: ConfigKey.TLS_KEY_PASSPHRASE, + component: EuiFieldPassword, + label: i18n.translate('xpack.synthetics.monitorConfig.clientKeyPassphrase.label', { + defaultMessage: 'Client key passphrase', + }), + helpText: i18n.translate('xpack.synthetics.monitorConfig.clientKeyPassphrase.helpText', { + defaultMessage: 'Certificate key passphrase for TLS client authentication.', + }), + showWhen: ['isTLSEnabled', true], + }, + [ConfigKey.SCREENSHOTS]: { + fieldKey: ConfigKey.SCREENSHOTS, + component: EuiButtonGroup, + label: i18n.translate('xpack.synthetics.monitorConfig.screenshotOptions.label', { + defaultMessage: 'Screenshot options', + }), + helpText: i18n.translate('xpack.synthetics.monitorConfig.screenshotOptions.helpText', { + defaultMessage: 'Set this option to manage the screenshots captured by the synthetics agent.', + }), + controlled: true, + props: ({ + field, + setValue, + }: { + field?: ControllerRenderProps; + setValue: UseFormReturn['setValue']; + }) => ({ + type: 'single', + idSelected: field?.value, + onChange: (option: ScreenshotOption) => setValue(ConfigKey.SCREENSHOTS, option), + options: Object.values(ScreenshotOption).map((option) => ({ + id: option, + label: option.replace(/-/g, ' '), + })), + css: { + 'text-transform': 'capitalize', + }, + }), + }, + [ConfigKey.TEXT_ASSERTION]: { + fieldKey: ConfigKey.TEXT_ASSERTION, + component: EuiFieldText, + label: i18n.translate('xpack.synthetics.monitorConfig.textAssertion.label', { + defaultMessage: 'Text assertion', + }), + required: true, + helpText: i18n.translate('xpack.synthetics.monitorConfig.textAssertion.helpText', { + defaultMessage: 'Consider the page loaded when the specified text is rendered.', + }), + validation: () => ({ + required: true, + }), + }, + [ConfigKey.THROTTLING_CONFIG]: { + fieldKey: ConfigKey.THROTTLING_CONFIG, + component: EuiSuperSelect, + label: i18n.translate('xpack.synthetics.monitorConfig.throttling.label', { + defaultMessage: 'Connection profile', + }), + required: true, + controlled: true, + helpText: i18n.translate('xpack.synthetics.monitorConfig.throttling.helpText', { + defaultMessage: + 'Simulate network throttling (download, upload, latency). More options will be added in a future version.', + }), + props: () => ({ + options: [ + { + value: DEFAULT_BROWSER_ADVANCED_FIELDS[ConfigKey.THROTTLING_CONFIG], + inputDisplay: ( + + + + {i18n.translate('xpack.synthetics.monitorConfig.throttling.options.default', { + defaultMessage: 'Default', + })} + + + + + {'(5 Mbps, 3 Mbps, 20 ms)'} + + + + ), + }, + ], + disabled: true, // currently disabled through 1.0 until we define connection profiles + }), + validation: () => ({ + required: true, + }), + }, +}; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/form_config.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/form_config.tsx new file mode 100644 index 00000000000000..1c49665af081eb --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/form_config.tsx @@ -0,0 +1,233 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { i18n } from '@kbn/i18n'; +import { ConfigKey, FormMonitorType, FieldMeta } from '../types'; + +import { FIELD } from './field_config'; + +const DEFAULT_DATA_OPTIONS = { + title: i18n.translate('xpack.synthetics.monitorConfig.section.dataOptions.title', { + defaultMessage: 'Data options', + }), + description: i18n.translate('xpack.synthetics.monitorConfig.section.dataOptions.description', { + defaultMessage: 'Configure data options to add context to the data coming from your monitors.', + }), + components: [ + FIELD[ConfigKey.TAGS], + FIELD[ConfigKey.APM_SERVICE_NAME], + FIELD[ConfigKey.NAMESPACE], + ], +}; + +const HTTP_ADVANCED = { + requestConfig: { + title: i18n.translate('xpack.synthetics.monitorConfig.section.requestConfiguration.title', { + defaultMessage: 'Request configuration', + }), + description: i18n.translate( + 'xpack.synthetics.monitorConfig.section.requestConfiguration.description', + { + defaultMessage: + 'Configure an optional request to send to the remote host including method, body, and headers.', + } + ), + components: [ + FIELD[ConfigKey.USERNAME], + FIELD[ConfigKey.PASSWORD], + FIELD[ConfigKey.PROXY_URL], + FIELD[ConfigKey.REQUEST_METHOD_CHECK], + FIELD[ConfigKey.REQUEST_HEADERS_CHECK], + FIELD[ConfigKey.REQUEST_BODY_CHECK], + ], + }, + responseConfig: { + title: i18n.translate('xpack.synthetics.monitorConfig.section.responseConfiguration.title', { + defaultMessage: 'Response configuration', + }), + description: i18n.translate( + 'xpack.synthetics.monitorConfig.section.responseConfiguration.description', + { + defaultMessage: 'Control the indexing of the HTTP response contents.', + } + ), + components: [FIELD[ConfigKey.RESPONSE_HEADERS_INDEX], FIELD[ConfigKey.RESPONSE_BODY_INDEX]], + }, + responseChecks: { + title: i18n.translate('xpack.synthetics.monitorConfig.section.responseChecks.title', { + defaultMessage: 'Response checks', + }), + description: i18n.translate( + 'xpack.synthetics.monitorConfig.section.responseChecks.description', + { + defaultMessage: 'Configure the expected HTTP response.', + } + ), + components: [ + FIELD[ConfigKey.RESPONSE_STATUS_CHECK], + FIELD[ConfigKey.RESPONSE_HEADERS_CHECK], + FIELD[ConfigKey.RESPONSE_BODY_CHECK_POSITIVE], + FIELD[ConfigKey.RESPONSE_BODY_CHECK_NEGATIVE], + ], + }, +}; + +export const TCP_ADVANCED = { + requestConfig: { + title: i18n.translate('xpack.synthetics.monitorConfig.section.requestConfigTCP.title', { + defaultMessage: 'Request configuration', + }), + description: i18n.translate( + 'xpack.synthetics.monitorConfig.section.requestConfigTCP.description', + { + defaultMessage: 'Configure the payload sent to the remote host.', + } + ), + components: [FIELD[`${ConfigKey.PROXY_URL}__tcp`], FIELD[ConfigKey.REQUEST_SEND_CHECK]], + }, + responseChecks: { + title: i18n.translate('xpack.synthetics.monitorConfig.section.responseChecksTCP.title', { + defaultMessage: 'Response checks', + }), + description: i18n.translate( + 'xpack.synthetics.monitorConfig.section.responseChecksTCP.description', + { + defaultMessage: 'Configure the expected response from the remote host.', + } + ), + components: [FIELD[ConfigKey.RESPONSE_RECEIVE_CHECK]], + }, +}; + +interface AdvancedFieldGroup { + title: string; + description: string; + components: FieldMeta[]; +} + +type FieldConfig = Record< + FormMonitorType, + { + step1: FieldMeta[]; + step2: FieldMeta[]; + step3?: FieldMeta[]; + scriptEdit?: FieldMeta[]; + advanced?: AdvancedFieldGroup[]; + } +>; + +const TLS_OPTIONS = { + title: i18n.translate('xpack.synthetics.monitorConfig.section.tlsOptions.title', { + defaultMessage: 'TLS options', + }), + description: i18n.translate('xpack.synthetics.monitorConfig.section.tlsOptions.description', { + defaultMessage: + 'Configure TLS options, including verification mode, certificate authorities, and client certificates.', + }), + components: [ + FIELD.isTLSEnabled, + FIELD[ConfigKey.TLS_VERIFICATION_MODE], + FIELD[ConfigKey.TLS_VERSION], + FIELD[ConfigKey.TLS_CERTIFICATE_AUTHORITIES], + FIELD[ConfigKey.TLS_CERTIFICATE], + FIELD[ConfigKey.TLS_KEY], + FIELD[ConfigKey.TLS_KEY_PASSPHRASE], + ], +}; + +export const FORM_CONFIG: FieldConfig = { + [FormMonitorType.HTTP]: { + step1: [FIELD[ConfigKey.FORM_MONITOR_TYPE]], + step2: [ + FIELD[`${ConfigKey.URLS}__http`], + FIELD[ConfigKey.NAME], + FIELD[ConfigKey.LOCATIONS], + FIELD[ConfigKey.SCHEDULE], + FIELD[ConfigKey.MAX_REDIRECTS], + FIELD[ConfigKey.TIMEOUT], + ], + advanced: [ + DEFAULT_DATA_OPTIONS, + HTTP_ADVANCED.requestConfig, + HTTP_ADVANCED.responseConfig, + HTTP_ADVANCED.responseChecks, + TLS_OPTIONS, + ], + }, + [FormMonitorType.TCP]: { + step1: [FIELD[ConfigKey.FORM_MONITOR_TYPE]], + step2: [ + FIELD[`${ConfigKey.HOSTS}__tcp`], + FIELD[ConfigKey.NAME], + FIELD[ConfigKey.LOCATIONS], + FIELD[ConfigKey.SCHEDULE], + FIELD[ConfigKey.TIMEOUT], + ], + advanced: [ + DEFAULT_DATA_OPTIONS, + TCP_ADVANCED.requestConfig, + TCP_ADVANCED.responseChecks, + TLS_OPTIONS, + ], + }, + [FormMonitorType.MULTISTEP]: { + step1: [FIELD[ConfigKey.FORM_MONITOR_TYPE]], + step2: [ + FIELD[ConfigKey.NAME], + FIELD[ConfigKey.LOCATIONS], + FIELD[ConfigKey.SCHEDULE], + FIELD[ConfigKey.THROTTLING_CONFIG], + ], + step3: [FIELD[ConfigKey.SOURCE_INLINE]], + scriptEdit: [FIELD[ConfigKey.SOURCE_INLINE]], + advanced: [ + { + ...DEFAULT_DATA_OPTIONS, + components: [ + FIELD[ConfigKey.TAGS], + FIELD[ConfigKey.APM_SERVICE_NAME], + FIELD[ConfigKey.SCREENSHOTS], + FIELD[ConfigKey.NAMESPACE], + ], + }, + ], + }, + [FormMonitorType.SINGLE]: { + step1: [FIELD[ConfigKey.FORM_MONITOR_TYPE]], + step2: [ + FIELD[`${ConfigKey.URLS}__single`], + FIELD[ConfigKey.NAME], + FIELD[ConfigKey.TEXT_ASSERTION], + FIELD[ConfigKey.LOCATIONS], + FIELD[ConfigKey.SCHEDULE], + FIELD[ConfigKey.THROTTLING_CONFIG], + ], + advanced: [ + { + ...DEFAULT_DATA_OPTIONS, + components: [ + FIELD[ConfigKey.TAGS], + FIELD[ConfigKey.APM_SERVICE_NAME], + FIELD[ConfigKey.SCREENSHOTS], + FIELD[ConfigKey.NAMESPACE], + ], + }, + ], + }, + [FormMonitorType.ICMP]: { + step1: [FIELD[ConfigKey.FORM_MONITOR_TYPE]], + step2: [ + FIELD[`${ConfigKey.HOSTS}__icmp`], + FIELD[ConfigKey.NAME], + FIELD[ConfigKey.LOCATIONS], + FIELD[ConfigKey.SCHEDULE], + FIELD[ConfigKey.WAIT], + FIELD[ConfigKey.TIMEOUT], + ], + advanced: [DEFAULT_DATA_OPTIONS], + }, +}; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/formatter.test.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/formatter.test.tsx new file mode 100644 index 00000000000000..80b34b47fdc9f1 --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/formatter.test.tsx @@ -0,0 +1,347 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { format } from './formatter'; + +describe('format', () => { + const formValues = { + type: 'http', + form_monitor_type: 'http', + enabled: true, + schedule: { + number: '3', + unit: 'm', + }, + 'service.name': '', + tags: [], + timeout: '16', + name: 'Sample name', + locations: [ + { + id: 'us_central', + isServiceManaged: true, + }, + ], + namespace: 'default', + origin: 'ui', + __ui: { + is_tls_enabled: false, + }, + urls: 'sample url', + max_redirects: '0', + password: '', + proxy_url: '', + 'check.response.body.negative': [], + 'check.response.body.positive': [], + 'response.include_body': 'on_error', + 'check.response.headers': {}, + 'response.include_headers': true, + 'check.response.status': [], + 'check.request.body': { + value: '', + type: 'text', + }, + 'check.request.headers': {}, + 'check.request.method': 'GET', + username: '', + 'ssl.certificate_authorities': '', + 'ssl.certificate': '', + 'ssl.key': '', + 'ssl.key_passphrase': '', + 'ssl.verification_mode': 'full', + 'ssl.supported_protocols': ['TLSv1.1', 'TLSv1.2', 'TLSv1.3'], + isTLSEnabled: false, + service: { + name: '', + }, + check: { + request: { + method: 'GET', + headers: {}, + body: { + type: 'text', + value: '', + }, + }, + response: { + status: [], + headers: {}, + body: { + positive: [], + negative: [], + }, + }, + }, + response: { + include_headers: true, + include_body: 'on_error', + }, + }; + + it('correctly formats form fields to monitor type', () => { + expect(format(formValues)).toEqual({ + __ui: { + is_tls_enabled: false, + }, + config_id: '', + 'check.request.body': { + type: 'text', + value: '', + }, + 'check.request.headers': {}, + 'check.request.method': 'GET', + 'check.response.body.negative': [], + 'check.response.body.positive': [], + 'check.response.headers': {}, + 'check.response.status': [], + enabled: true, + form_monitor_type: 'http', + locations: [ + { + id: 'us_central', + isServiceManaged: true, + }, + ], + max_redirects: '0', + name: 'Sample name', + namespace: 'default', + origin: 'ui', + password: '', + proxy_url: '', + 'response.include_body': 'on_error', + 'response.include_headers': true, + schedule: { + number: '3', + unit: 'm', + }, + 'service.name': '', + 'ssl.certificate': '', + 'ssl.certificate_authorities': '', + 'ssl.key': '', + 'ssl.key_passphrase': '', + 'ssl.supported_protocols': ['TLSv1.1', 'TLSv1.2', 'TLSv1.3'], + 'ssl.verification_mode': 'full', + tags: [], + timeout: '16', + type: 'http', + urls: 'sample url', + username: '', + }); + }); + + it.each([ + ['recorder', true, 'testScriptRecorder', 'fileName'], + ['inline', false, 'testScript', ''], + ])( + 'correctly formats form fields to monitor type', + (scriptType, isGeneratedScript, script, fileName) => { + const browserFormFields = { + type: 'browser', + form_monitor_type: 'multistep', + config_id: '', + enabled: true, + schedule: { + unit: 'm', + number: '10', + }, + 'service.name': '', + tags: [], + timeout: '16', + name: 'Browser monitor', + locations: [ + { + id: 'us_central', + isServiceManaged: true, + }, + ], + namespace: 'default', + origin: 'ui', + journey_id: '', + project_id: '', + playwright_options: '', + __ui: { + script_source: { + is_generated_script: false, + file_name: '', + }, + is_zip_url_tls_enabled: false, + }, + params: '', + 'source.inline.script': '', + 'source.project.content': '', + 'source.zip_url.url': '', + 'source.zip_url.username': '', + 'source.zip_url.password': '', + 'source.zip_url.folder': '', + 'source.zip_url.proxy_url': '', + playwright_text_assertion: '', + urls: '', + screenshots: 'on', + synthetics_args: [], + 'filter_journeys.match': '', + 'filter_journeys.tags': [], + ignore_https_errors: false, + 'throttling.is_enabled': true, + 'throttling.download_speed': '5', + 'throttling.upload_speed': '3', + 'throttling.latency': '20', + 'throttling.config': '5d/3u/20l', + 'ssl.certificate_authorities': '', + 'ssl.certificate': '', + 'ssl.key': '', + 'ssl.key_passphrase': '', + 'ssl.verification_mode': 'full', + 'ssl.supported_protocols': ['TLSv1.1', 'TLSv1.2', 'TLSv1.3'], + 'source.inline': { + type: 'recorder', + script: '', + fileName: '', + }, + throttling: { + config: '5d/3u/20l', + }, + source: { + inline: { + type: scriptType, + script, + fileName, + }, + }, + service: { + name: '', + }, + }; + expect(format(browserFormFields)).toEqual({ + __ui: { + script_source: { + file_name: fileName, + is_generated_script: isGeneratedScript, + }, + }, + config_id: '', + enabled: true, + 'filter_journeys.match': '', + 'filter_journeys.tags': [], + form_monitor_type: 'multistep', + ignore_https_errors: false, + journey_id: '', + locations: [ + { + id: 'us_central', + isServiceManaged: true, + }, + ], + name: 'Browser monitor', + namespace: 'default', + origin: 'ui', + params: '', + playwright_options: '', + playwright_text_assertion: '', + project_id: '', + schedule: { + number: '10', + unit: 'm', + }, + screenshots: 'on', + 'service.name': '', + 'source.inline.script': script, + 'source.project.content': '', + 'source.zip_url.folder': '', + 'source.zip_url.password': '', + 'source.zip_url.proxy_url': '', + 'source.zip_url.ssl.certificate': undefined, + 'source.zip_url.ssl.certificate_authorities': undefined, + 'source.zip_url.ssl.key': undefined, + 'source.zip_url.ssl.key_passphrase': undefined, + 'source.zip_url.ssl.supported_protocols': undefined, + 'source.zip_url.ssl.verification_mode': undefined, + 'source.zip_url.url': '', + 'source.zip_url.username': '', + 'ssl.certificate': '', + 'ssl.certificate_authorities': '', + 'ssl.key': '', + 'ssl.key_passphrase': '', + 'ssl.supported_protocols': ['TLSv1.1', 'TLSv1.2', 'TLSv1.3'], + 'ssl.verification_mode': 'full', + synthetics_args: [], + tags: [], + 'throttling.config': '5d/3u/20l', + 'throttling.download_speed': '5', + 'throttling.is_enabled': true, + 'throttling.latency': '20', + 'throttling.upload_speed': '3', + timeout: '16', + type: 'browser', + 'url.port': null, + urls: '', + }); + } + ); + + it.each([ + ['testCA', true], + ['', false], + ])('correctly formats form fields to monitor type', (certificateAuthorities, isTLSEnabled) => { + expect( + format({ + ...formValues, + ssl: { + // @ts-ignore next + ...formValues.ssl, + certificate_authorities: certificateAuthorities, + }, + }) + ).toEqual({ + __ui: { + is_tls_enabled: isTLSEnabled, + }, + config_id: '', + 'check.request.body': { + type: 'text', + value: '', + }, + 'check.request.headers': {}, + 'check.request.method': 'GET', + 'check.response.body.negative': [], + 'check.response.body.positive': [], + 'check.response.headers': {}, + 'check.response.status': [], + enabled: true, + form_monitor_type: 'http', + locations: [ + { + id: 'us_central', + isServiceManaged: true, + }, + ], + max_redirects: '0', + name: 'Sample name', + namespace: 'default', + origin: 'ui', + password: '', + proxy_url: '', + 'response.include_body': 'on_error', + 'response.include_headers': true, + schedule: { + number: '3', + unit: 'm', + }, + 'service.name': '', + 'ssl.certificate': '', + 'ssl.certificate_authorities': certificateAuthorities, + 'ssl.key': '', + 'ssl.key_passphrase': '', + 'ssl.supported_protocols': ['TLSv1.1', 'TLSv1.2', 'TLSv1.3'], + 'ssl.verification_mode': 'full', + tags: [], + timeout: '16', + type: 'http', + urls: 'sample url', + username: '', + }); + }); +}); diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/formatter.ts b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/formatter.ts new file mode 100644 index 00000000000000..8da53f6cbb2806 --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/formatter.ts @@ -0,0 +1,74 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { get, isEqual } from 'lodash'; +import { ConfigKey, DataStream, FormMonitorType, MonitorFields } from '../types'; +import { DEFAULT_FIELDS, DEFAULT_TLS_FIELDS } from '../constants'; + +export const formatter = (fields: Record) => { + const monitorType = fields[ConfigKey.MONITOR_TYPE] as DataStream; + const monitorFields: Record = {}; + const defaults = DEFAULT_FIELDS[monitorType] as MonitorFields; + Object.keys(defaults).map((key) => { + /* split key names on dot to handle dot notation fields, + * which are changed to nested fields by react-hook-form */ + monitorFields[key] = get(fields, key.split('.')) || defaults[key as ConfigKey]; + }); + return monitorFields as MonitorFields; +}; + +export const format = (fields: Record) => { + const formattedFields = formatter(fields) as MonitorFields; + const formattedMap = { + [FormMonitorType.SINGLE]: { + ...formattedFields, + [ConfigKey.SOURCE_INLINE]: `step('Go to ${formattedFields[ConfigKey.URLS]}', async () => { + await page.goto('${formattedFields[ConfigKey.URLS]}'); + expect(await page.isVisible('text=${ + formattedFields[ConfigKey.TEXT_ASSERTION] + }')).toBeTruthy(); + });`, + [ConfigKey.FORM_MONITOR_TYPE]: FormMonitorType.SINGLE, + }, + [FormMonitorType.MULTISTEP]: { + ...formattedFields, + [ConfigKey.METADATA]: { + script_source: { + is_generated_script: get(fields, 'source.inline.type') === 'recorder' ? true : false, + file_name: get(fields, 'source.inline.fileName'), + }, + }, + [ConfigKey.FORM_MONITOR_TYPE]: FormMonitorType.MULTISTEP, + }, + [FormMonitorType.HTTP]: { + ...formattedFields, + [ConfigKey.METADATA]: { + is_tls_enabled: isCustomTLSEnabled(formattedFields), + }, + [ConfigKey.FORM_MONITOR_TYPE]: FormMonitorType.HTTP, + }, + [FormMonitorType.TCP]: { + ...formattedFields, + [ConfigKey.METADATA]: { + is_tls_enabled: isCustomTLSEnabled(formattedFields), + }, + [ConfigKey.FORM_MONITOR_TYPE]: FormMonitorType.TCP, + }, + [FormMonitorType.ICMP]: { + ...formattedFields, + [ConfigKey.FORM_MONITOR_TYPE]: FormMonitorType.ICMP, + }, + }; + return formattedMap[fields[ConfigKey.FORM_MONITOR_TYPE] as FormMonitorType]; +}; + +const isCustomTLSEnabled = (fields: MonitorFields) => { + const tlsFields: Record = {}; + Object.keys(DEFAULT_TLS_FIELDS).map((key) => { + tlsFields[key] = fields[key as keyof MonitorFields]; + }); + return !isEqual(tlsFields, DEFAULT_TLS_FIELDS); +}; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/index.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/index.tsx new file mode 100644 index 00000000000000..18e1b78a3c59bb --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/index.tsx @@ -0,0 +1,51 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { EuiForm, EuiSpacer } from '@elastic/eui'; +import { FormProvider } from 'react-hook-form'; +import { useFormWrapped } from '../hooks/use_form_wrapped'; +import { FormMonitorType, SyntheticsMonitor } from '../types'; +import { getDefaultFormFields, formatDefaultFormValues } from './defaults'; +import { ActionBar } from './submit'; +import { Disclaimer } from './disclaimer'; + +export const MonitorForm: React.FC<{ defaultValues?: SyntheticsMonitor; space?: string }> = ({ + children, + defaultValues, + space, +}) => { + const methods = useFormWrapped({ + mode: 'onSubmit', + reValidateMode: 'onChange', + defaultValues: + formatDefaultFormValues(defaultValues as SyntheticsMonitor) || + getDefaultFormFields(space)[FormMonitorType.MULTISTEP], + shouldFocusError: true, + }); + + /* React hook form doesn't seem to register a field + * as dirty until validation unless dirtyFields is subscribed to */ + const { + formState: { isSubmitted, errors, dirtyFields: _ }, + } = methods; + + return ( + + + {children} + + + + + + ); +}; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/submit.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/submit.tsx new file mode 100644 index 00000000000000..46dba61339a7bd --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/submit.tsx @@ -0,0 +1,128 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { useEffect, useState } from 'react'; +import { Redirect, useParams, useHistory, useRouteMatch } from 'react-router-dom'; +import { EuiButton, EuiLink, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { useFormContext } from 'react-hook-form'; +import { useFetcher, FETCH_STATUS } from '@kbn/observability-plugin/public'; +import { SyntheticsMonitor } from '../types'; +import { format } from './formatter'; +import { createMonitorAPI, updateMonitorAPI } from '../../../state/monitor_management/api'; +import { kibanaService } from '../../../../../utils/kibana_service'; + +import { MONITORS_ROUTE, MONITOR_EDIT_ROUTE } from '../../../../../../common/constants'; + +export const ActionBar = () => { + const { monitorId } = useParams<{ monitorId: string }>(); + const history = useHistory(); + const editRouteMatch = useRouteMatch({ path: MONITOR_EDIT_ROUTE }); + const isEdit = editRouteMatch?.isExact; + const { handleSubmit } = useFormContext(); + + const [monitorData, setMonitorData] = useState(undefined); + + const { data, status } = useFetcher(() => { + if (!monitorData) { + return null; + } + if (isEdit) { + return updateMonitorAPI({ + id: monitorId, + monitor: monitorData, + }); + } else { + return createMonitorAPI({ + monitor: monitorData, + }); + } + }, [monitorData]); + + const loading = status === FETCH_STATUS.LOADING; + + useEffect(() => { + if (status === FETCH_STATUS.FAILURE) { + kibanaService.toasts.addDanger({ + title: MONITOR_FAILURE_LABEL, + toastLifeTimeMs: 3000, + }); + } else if (status === FETCH_STATUS.SUCCESS && !loading) { + kibanaService.toasts.addSuccess({ + title: monitorId ? MONITOR_UPDATED_SUCCESS_LABEL : MONITOR_SUCCESS_LABEL, + toastLifeTimeMs: 3000, + }); + } + }, [data, status, monitorId, loading]); + + const formSubmitter = (formData: Record) => { + setMonitorData(format(formData) as SyntheticsMonitor); + }; + + return status === FETCH_STATUS.SUCCESS ? ( + + ) : ( + + + {CANCEL_LABEL} + + + + + + {isEdit ? UPDATE_MONITOR_LABEL : CREATE_MONITOR_LABEL} + + + + + + ); +}; + +const CANCEL_LABEL = i18n.translate('xpack.synthetics.monitorManagement.discardLabel', { + defaultMessage: 'Cancel', +}); + +const CREATE_MONITOR_LABEL = i18n.translate( + 'xpack.synthetics.monitorManagement.addEdit.createMonitorLabel', + { + defaultMessage: 'Create monitor', + } +); + +const UPDATE_MONITOR_LABEL = i18n.translate( + 'xpack.synthetics.monitorManagement.updateMonitorLabel', + { + defaultMessage: 'Update monitor', + } +); + +const MONITOR_SUCCESS_LABEL = i18n.translate( + 'xpack.synthetics.monitorManagement.monitorAddedSuccessMessage', + { + defaultMessage: 'Monitor added successfully.', + } +); + +const MONITOR_UPDATED_SUCCESS_LABEL = i18n.translate( + 'xpack.synthetics.monitorManagement.monitorEditedSuccessMessage', + { + defaultMessage: 'Monitor updated successfully.', + } +); + +const MONITOR_FAILURE_LABEL = i18n.translate( + 'xpack.synthetics.monitorManagement.monitorFailureMessage', + { + defaultMessage: 'Monitor was unable to be saved. Please try again later.', + } +); diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/validation.test.ts b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/validation.test.ts new file mode 100644 index 00000000000000..fa91bd457671dc --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/validation.test.ts @@ -0,0 +1,76 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { + ConfigKey, + DataStream, + HTTPFields, + BrowserFields, + MonitorFields, + ScheduleUnit, +} from '../types'; +import { validate } from './validation'; + +describe('[Monitor Management] validation', () => { + const commonPropsValid: Partial = { + [ConfigKey.SCHEDULE]: { number: '5', unit: ScheduleUnit.MINUTES }, + [ConfigKey.TIMEOUT]: '3m', + }; + + describe('HTTP', () => { + const httpPropsValid: Partial = { + ...commonPropsValid, + [ConfigKey.RESPONSE_STATUS_CHECK]: ['200', '204'], + [ConfigKey.RESPONSE_HEADERS_CHECK]: { 'Content-Type': 'application/json' }, + [ConfigKey.REQUEST_HEADERS_CHECK]: { 'Accept-Language': 'en-GB,en-US;q=0.9,en;q=0.8' }, + [ConfigKey.MAX_REDIRECTS]: '3', + [ConfigKey.URLS]: 'https:// example-url.com', + }; + + it('should return false for all valid props', () => { + const validators = validate[DataStream.HTTP]; + const keysToValidate = [ + ConfigKey.SCHEDULE, + ConfigKey.TIMEOUT, + ConfigKey.RESPONSE_STATUS_CHECK, + ConfigKey.RESPONSE_HEADERS_CHECK, + ConfigKey.REQUEST_HEADERS_CHECK, + ConfigKey.MAX_REDIRECTS, + ConfigKey.URLS, + ]; + const validatorFns = keysToValidate.map((key) => validators[key]); + const result = validatorFns.map((fn) => fn?.(httpPropsValid) ?? true); + + expect(result).not.toEqual(expect.arrayContaining([true])); + }); + }); + + describe.each([ + [ConfigKey.SOURCE_INLINE, 'step(() => {});'], + [ConfigKey.SOURCE_ZIP_URL, 'https://test.zip'], + ])('Browser', (configKey, value) => { + const browserProps: Partial = { + ...commonPropsValid, + [ConfigKey.MONITOR_TYPE]: DataStream.BROWSER, + [ConfigKey.TIMEOUT]: null, + [ConfigKey.URLS]: null, + [ConfigKey.PORT]: null, + [configKey]: value, + }; + + it('should return false for all valid props', () => { + const validators = validate[DataStream.BROWSER]; + const keysToValidate = [ConfigKey.SCHEDULE, ConfigKey.TIMEOUT, configKey]; + const validatorFns = keysToValidate.map((key) => validators[key]); + const result = validatorFns.map((fn) => fn?.(browserProps as Partial) ?? true); + + expect(result).not.toEqual(expect.arrayContaining([true])); + }); + }); + + // TODO: Add test for other monitor types if needed +}); diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/validation.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/validation.tsx new file mode 100644 index 00000000000000..de3ce4bc327fdb --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/validation.tsx @@ -0,0 +1,157 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { + ConfigKey, + DataStream, + ScheduleUnit, + MonitorFields, + Validator, + Validation, +} from '../types'; + +export const DIGITS_ONLY = /^[0-9]*$/g; +export const INCLUDES_VALID_PORT = /[^\:]+:[0-9]{1,5}$/g; +export const WHOLE_NUMBERS_ONLY = /^[0-9]+(.?[0]+)?$/; +export const FLOATS_ONLY = /^[0-9]+(.?[0-9]+)?$/; + +type ValidationLibrary = Record; + +// returns true if invalid +export function validateHeaders(headers: T): boolean { + return Object.keys(headers).some((key) => { + if (key) { + const whiteSpaceRegEx = /[\s]/g; + return whiteSpaceRegEx.test(key); + } else { + return false; + } + }); +} + +// returns true if invalid +export const validateTimeout = ({ + scheduleNumber, + scheduleUnit, + timeout, +}: { + scheduleNumber: string; + scheduleUnit: ScheduleUnit; + timeout: string; +}): boolean => { + let schedule: number; + switch (scheduleUnit) { + case ScheduleUnit.SECONDS: + schedule = parseFloat(scheduleNumber); + break; + case ScheduleUnit.MINUTES: + schedule = parseFloat(scheduleNumber) * 60; + break; + default: + schedule = parseFloat(scheduleNumber); + } + + return parseFloat(timeout) > schedule; +}; + +// validation functions return true when invalid +const validateCommon: ValidationLibrary = { + [ConfigKey.SCHEDULE]: ({ [ConfigKey.SCHEDULE]: value }) => { + const { number, unit } = value as MonitorFields[ConfigKey.SCHEDULE]; + const parsedFloat = parseFloat(number); + return !parsedFloat || !unit || parsedFloat < 1; + }, + [ConfigKey.TIMEOUT]: ({ + [ConfigKey.MONITOR_TYPE]: monitorType, + [ConfigKey.TIMEOUT]: timeout, + [ConfigKey.SCHEDULE]: schedule, + }) => { + const { number, unit } = schedule as MonitorFields[ConfigKey.SCHEDULE]; + + // Timeout is not currently supported by browser monitors + if (monitorType === DataStream.BROWSER) { + return false; + } + + return ( + !timeout || + parseFloat(timeout) < 0 || + validateTimeout({ + timeout, + scheduleNumber: number, + scheduleUnit: unit, + }) + ); + }, +}; + +const validateHTTP: ValidationLibrary = { + [ConfigKey.RESPONSE_STATUS_CHECK]: ({ [ConfigKey.RESPONSE_STATUS_CHECK]: value }) => { + const statusCodes = value as MonitorFields[ConfigKey.RESPONSE_STATUS_CHECK]; + return statusCodes.length ? statusCodes.some((code) => !`${code}`.match(DIGITS_ONLY)) : false; + }, + [ConfigKey.RESPONSE_HEADERS_CHECK]: ({ [ConfigKey.RESPONSE_HEADERS_CHECK]: value }) => { + const headers = value as MonitorFields[ConfigKey.RESPONSE_HEADERS_CHECK]; + return validateHeaders(headers); + }, + [ConfigKey.REQUEST_HEADERS_CHECK]: ({ [ConfigKey.REQUEST_HEADERS_CHECK]: value }) => { + const headers = value as MonitorFields[ConfigKey.REQUEST_HEADERS_CHECK]; + return validateHeaders(headers); + }, + [ConfigKey.MAX_REDIRECTS]: ({ [ConfigKey.MAX_REDIRECTS]: value }) => + (!!value && !`${value}`.match(DIGITS_ONLY)) || + parseFloat(value as MonitorFields[ConfigKey.MAX_REDIRECTS]) < 0, + [ConfigKey.URLS]: ({ [ConfigKey.URLS]: value }) => !value, + ...validateCommon, +}; + +const validateTCP: Record = { + [ConfigKey.HOSTS]: ({ [ConfigKey.HOSTS]: value }) => { + return !value || !`${value}`.match(INCLUDES_VALID_PORT); + }, + ...validateCommon, +}; + +const validateICMP: ValidationLibrary = { + [ConfigKey.HOSTS]: ({ [ConfigKey.HOSTS]: value }) => !value, + [ConfigKey.WAIT]: ({ [ConfigKey.WAIT]: value }) => + !!value && + !DIGITS_ONLY.test(`${value}`) && + parseFloat(value as MonitorFields[ConfigKey.WAIT]) < 0, + ...validateCommon, +}; + +const validateThrottleValue = (speed: string | undefined, allowZero?: boolean) => { + if (speed === undefined || speed === '') return false; + const throttleValue = parseFloat(speed); + return isNaN(throttleValue) || (allowZero ? throttleValue < 0 : throttleValue <= 0); +}; + +const validateBrowser: ValidationLibrary = { + ...validateCommon, + [ConfigKey.SOURCE_ZIP_URL]: ({ + [ConfigKey.SOURCE_ZIP_URL]: zipUrl, + [ConfigKey.SOURCE_INLINE]: inlineScript, + }) => !zipUrl && !inlineScript, + [ConfigKey.SOURCE_INLINE]: ({ + [ConfigKey.SOURCE_ZIP_URL]: zipUrl, + [ConfigKey.SOURCE_INLINE]: inlineScript, + }) => !zipUrl && !inlineScript, + [ConfigKey.DOWNLOAD_SPEED]: ({ [ConfigKey.DOWNLOAD_SPEED]: downloadSpeed }) => + validateThrottleValue(downloadSpeed), + [ConfigKey.UPLOAD_SPEED]: ({ [ConfigKey.UPLOAD_SPEED]: uploadSpeed }) => + validateThrottleValue(uploadSpeed), + [ConfigKey.LATENCY]: ({ [ConfigKey.LATENCY]: latency }) => validateThrottleValue(latency, true), +}; + +export type ValidateDictionary = Record; + +export const validate: ValidateDictionary = { + [DataStream.HTTP]: validateHTTP, + [DataStream.TCP]: validateTCP, + [DataStream.ICMP]: validateICMP, + [DataStream.BROWSER]: validateBrowser, +}; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/hooks/index.ts b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/hooks/index.ts new file mode 100644 index 00000000000000..c69bb9421ab7ca --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/hooks/index.ts @@ -0,0 +1,9 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export * from './use_is_edit_flow'; +export * from './use_kibana_space'; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/hooks/use_form_wrapped.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/hooks/use_form_wrapped.tsx new file mode 100644 index 00000000000000..0f2c75ac559802 --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/hooks/use_form_wrapped.tsx @@ -0,0 +1,33 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { useCallback } from 'react'; +import { FieldValues, useForm, UseFormProps } from 'react-hook-form'; + +export function useFormWrapped( + props?: UseFormProps +) { + const { register, ...restOfForm } = useForm(props); + + const euiRegister = useCallback( + (name, ...registerArgs) => { + const { ref, ...restOfRegister } = register(name, ...registerArgs); + + return { + inputRef: ref, + ref, + ...restOfRegister, + }; + }, + [register] + ); + + return { + register: euiRegister, + ...restOfForm, + }; +} diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/hooks/use_is_edit_flow.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/hooks/use_is_edit_flow.tsx new file mode 100644 index 00000000000000..5f0ef77be6a94c --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/hooks/use_is_edit_flow.tsx @@ -0,0 +1,13 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { useRouteMatch } from 'react-router-dom'; +import { MONITOR_EDIT_ROUTE } from '../../../../../../common/constants'; + +export const useIsEditFlow = () => { + const editRouteMatch = useRouteMatch({ path: MONITOR_EDIT_ROUTE }); + return editRouteMatch?.isExact || false; +}; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/hooks/use_kibana_space.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/hooks/use_kibana_space.tsx new file mode 100644 index 00000000000000..e7e7a6f1375f5e --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/hooks/use_kibana_space.tsx @@ -0,0 +1,28 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { useKibana } from '@kbn/kibana-react-plugin/public'; +import { useFetcher } from '@kbn/observability-plugin/public'; +import { ClientPluginsStart } from '../../../../../plugin'; + +export const useKibanaSpace = () => { + const { services } = useKibana(); + + const { + data: space, + loading, + error, + } = useFetcher(() => { + return services.spaces?.getActiveSpace(); + }, [services.spaces]); + + return { + space, + loading, + error, + }; +}; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/hooks/use_monitor_name.test.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/hooks/use_monitor_name.test.tsx new file mode 100644 index 00000000000000..709d61bc7dc2ff --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/hooks/use_monitor_name.test.tsx @@ -0,0 +1,80 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { defaultCore, WrappedHelper } from '../../../utils/testing/rtl_helpers'; +import { renderHook } from '@testing-library/react-hooks'; +import { useMonitorName } from './use_monitor_name'; + +import * as reactRouter from 'react-router-dom'; + +const mockRouter = { + ...reactRouter, +}; + +jest.mock('react-router-dom', () => ({ + ...jest.requireActual('react-router-dom'), + useParams: jest.fn().mockReturnValue({}), +})); + +describe('useMonitorName', () => { + it('returns expected results', () => { + const { result } = renderHook(() => useMonitorName({}), { wrapper: WrappedHelper }); + + expect(result.current).toStrictEqual({ nameAlreadyExists: false, validName: '' }); + expect(defaultCore.savedObjects.client.find).toHaveBeenCalledWith({ + aggs: { + monitorNames: { + terms: { field: 'synthetics-monitor.attributes.name.keyword', size: 10000 }, + }, + }, + perPage: 0, + type: 'synthetics-monitor', + }); + }); + + it('returns expected results after data', async () => { + defaultCore.savedObjects.client.find = jest.fn().mockReturnValue({ + aggregations: { + monitorNames: { + buckets: [{ key: 'Test' }, { key: 'Test 1' }], + }, + }, + }); + + const { result, waitForNextUpdate } = renderHook(() => useMonitorName({ search: 'Test' }), { + wrapper: WrappedHelper, + }); + + expect(result.current).toStrictEqual({ nameAlreadyExists: false, validName: 'Test' }); + + await waitForNextUpdate(); + + expect(result.current).toStrictEqual({ nameAlreadyExists: true, validName: '' }); + }); + + it('returns expected results after data while editing monitor', async () => { + defaultCore.savedObjects.client.find = jest.fn().mockReturnValue({ + aggregations: { + monitorNames: { + buckets: [{ key: 'Test' }, { key: 'Test 1' }], + }, + }, + }); + + jest.spyOn(mockRouter, 'useParams').mockReturnValue({ monitorId: 'test-id' }); + + const { result, waitForNextUpdate } = renderHook(() => useMonitorName({ search: 'Test' }), { + wrapper: WrappedHelper, + }); + + expect(result.current).toStrictEqual({ nameAlreadyExists: false, validName: 'Test' }); + + await waitForNextUpdate(); + + expect(result.current).toStrictEqual({ nameAlreadyExists: false, validName: 'Test' }); + }); +}); diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/hooks/use_monitor_name.ts b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/hooks/use_monitor_name.ts new file mode 100644 index 00000000000000..a173aae5c700d4 --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/hooks/use_monitor_name.ts @@ -0,0 +1,64 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { useEffect, useState } from 'react'; +import { useFetcher } from '@kbn/observability-plugin/public'; +import { useKibana } from '@kbn/kibana-react-plugin/public'; +import { useParams } from 'react-router-dom'; +import { syntheticsMonitorType } from '../../../../../../common/types/saved_objects'; + +interface AggsResponse { + monitorNames: { + buckets: Array<{ + key: string; + }>; + }; +} + +export const useMonitorName = ({ search = '' }: { search?: string }) => { + const [values, setValues] = useState([]); + + const { monitorId } = useParams<{ monitorId: string }>(); + + const { savedObjects } = useKibana().services; + + const { data } = useFetcher(() => { + const aggs = { + monitorNames: { + terms: { + field: `${syntheticsMonitorType}.attributes.name.keyword`, + size: 10000, + }, + }, + }; + return savedObjects?.client.find({ + type: syntheticsMonitorType, + perPage: 0, + aggs, + }); + }, []); + + useEffect(() => { + if (data?.aggregations) { + const newValues = (data.aggregations as AggsResponse)?.monitorNames.buckets.map(({ key }) => + key.toLowerCase() + ); + if (monitorId && newValues.includes(search.toLowerCase())) { + setValues(newValues.filter((val) => val !== search.toLowerCase())); + } else { + setValues(newValues); + } + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [data, monitorId]); + + const hasMonitor = Boolean( + search && values && values.length > 0 && values?.includes(search.trim().toLowerCase()) + ); + + return { nameAlreadyExists: hasMonitor, validName: hasMonitor ? '' : search }; +}; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/monitor_add_edit_page.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/monitor_add_edit_page.tsx deleted file mode 100644 index d0a0c04150f8d8..00000000000000 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/monitor_add_edit_page.tsx +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React from 'react'; -import { useTrackPageview } from '@kbn/observability-plugin/public'; -import { useMonitorAddEditBreadcrumbs } from './use_breadcrumbs'; - -export const MonitorAddEditPage: React.FC = () => { - useTrackPageview({ app: 'synthetics', path: 'add-monitor' }); - useTrackPageview({ app: 'synthetics', path: 'add-monitor', delay: 15000 }); - useMonitorAddEditBreadcrumbs(); - - return ( - <> -

Monitor Add or Edit page

- - ); -}; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/monitor_add_page.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/monitor_add_page.tsx new file mode 100644 index 00000000000000..327e7cf574528e --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/monitor_add_page.tsx @@ -0,0 +1,37 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { useEffect } from 'react'; +import { EuiLoadingSpinner } from '@elastic/eui'; +import { useDispatch } from 'react-redux'; +import { useTrackPageview } from '@kbn/observability-plugin/public'; +import { useKibanaSpace } from './hooks/use_kibana_space'; +import { getServiceLocations } from '../../state'; +import { MonitorSteps } from './steps'; +import { MonitorForm } from './form'; +import { ADD_MONITOR_STEPS } from './steps/step_config'; +import { useMonitorAddEditBreadcrumbs } from './use_breadcrumbs'; + +export const MonitorAddPage = () => { + useTrackPageview({ app: 'synthetics', path: 'add-monitor' }); + const { space, loading, error } = useKibanaSpace(); + useTrackPageview({ app: 'synthetics', path: 'add-monitor', delay: 15000 }); + useMonitorAddEditBreadcrumbs(); + const dispatch = useDispatch(); + + useEffect(() => { + dispatch(getServiceLocations()); + }, [dispatch]); + + return !loading && !error ? ( + + + + ) : ( + + ); +}; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/monitor_details_portal.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/monitor_details_portal.tsx new file mode 100644 index 00000000000000..950d439173004c --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/monitor_details_portal.tsx @@ -0,0 +1,32 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { useHistory } from 'react-router-dom'; +import { EuiButtonEmpty } from '@elastic/eui'; +import { InPortal } from 'react-reverse-portal'; +import { MonitorDetailsLinkPortalNode } from './portals'; + +export const MonitorDetailsLinkPortal = ({ name, id }: { name: string; id: string }) => { + return ( + + + + ); +}; + +export const MonitorDetailsLink = ({ name, id }: { name: string; id: string }) => { + const history = useHistory(); + const href = history.createHref({ + pathname: `monitor/${id}`, + }); + return ( + + {name} + + ); +}; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/monitor_edit_page.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/monitor_edit_page.tsx new file mode 100644 index 00000000000000..a1aba64f43f4c7 --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/monitor_edit_page.tsx @@ -0,0 +1,44 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { useEffect } from 'react'; +import { EuiLoadingSpinner } from '@elastic/eui'; +import { useParams } from 'react-router-dom'; +import { useDispatch } from 'react-redux'; +import { useTrackPageview, useFetcher } from '@kbn/observability-plugin/public'; +import { getServiceLocations } from '../../state'; +import { MonitorSteps } from './steps'; +import { MonitorForm } from './form'; +import { MonitorDetailsLinkPortal } from './monitor_details_portal'; +import { useMonitorAddEditBreadcrumbs } from './use_breadcrumbs'; +import { getMonitorAPI } from '../../state/monitor_management/api'; +import { EDIT_MONITOR_STEPS } from './steps/step_config'; + +export const MonitorEditPage: React.FC = () => { + useTrackPageview({ app: 'synthetics', path: 'edit-monitor' }); + useTrackPageview({ app: 'synthetics', path: 'edit-monitor', delay: 15000 }); + const { monitorId } = useParams<{ monitorId: string }>(); + useMonitorAddEditBreadcrumbs(true); + const dispatch = useDispatch(); + + useEffect(() => { + dispatch(getServiceLocations()); + }, [dispatch]); + + const { data, loading, error } = useFetcher(() => { + return getMonitorAPI({ id: monitorId }); + }, []); + + return data && !loading && !error ? ( + + + + + ) : ( + + ); +}; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/portals.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/portals.tsx new file mode 100644 index 00000000000000..cd32ca9d914d47 --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/portals.tsx @@ -0,0 +1,12 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { createHtmlPortalNode } from 'react-reverse-portal'; + +export const MonitorTypePortalNode = createHtmlPortalNode(); + +export const MonitorDetailsLinkPortalNode = createHtmlPortalNode(); diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/steps/index.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/steps/index.tsx new file mode 100644 index 00000000000000..e5be1cd627dd6d --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/steps/index.tsx @@ -0,0 +1,48 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { EuiSteps, EuiPanel, EuiSpacer, EuiText } from '@elastic/eui'; +import { useFormContext } from 'react-hook-form'; +import { ConfigKey, FormMonitorType, StepMap } from '../types'; +import { AdvancedConfig } from '../advanced'; +import { MonitorTypePortal } from './monitor_type_portal'; + +export const MonitorSteps = ({ + stepMap, + isEditFlow = false, +}: { + stepMap: StepMap; + isEditFlow?: boolean; +}) => { + const { watch } = useFormContext(); + const [type]: [FormMonitorType] = watch([ConfigKey.FORM_MONITOR_TYPE]); + const steps = stepMap[type]; + + return ( + <> + {isEditFlow ? ( + steps.map((step) => ( + <> + + +

{step.title}

+
+ + {step.children} +
+ + + )) + ) : ( + + )} + + + + ); +}; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/steps/monitor_type.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/steps/monitor_type.tsx new file mode 100644 index 00000000000000..8e4056a6b1a9f8 --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/steps/monitor_type.tsx @@ -0,0 +1,46 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { i18n } from '@kbn/i18n'; +import { EuiBetaBadge, EuiText, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; +import { FormMonitorType } from '../types'; +import { MONITOR_TYPE_CONFIG } from '../form/field_config'; + +export const MonitorType = ({ monitorType }: { monitorType: FormMonitorType }) => { + const config = MONITOR_TYPE_CONFIG[monitorType]; + return ( + <> + + {i18n.translate('xpack.synthetics.monitorConfig.monitorType.label', { + defaultMessage: 'Monitor type', + })} + + + + + {config.descriptionTitle} + + + {config.beta && ( + + )} + + + + + ); +}; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/steps/monitor_type_portal.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/steps/monitor_type_portal.tsx new file mode 100644 index 00000000000000..684956dadd569a --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/steps/monitor_type_portal.tsx @@ -0,0 +1,21 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { InPortal } from 'react-reverse-portal'; +import { MonitorTypePortalNode } from '../portals'; +import { FormMonitorType } from '../types'; + +import { MonitorType } from './monitor_type'; + +export const MonitorTypePortal = ({ monitorType }: { monitorType: FormMonitorType }) => { + return ( + + + + ); +}; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/steps/step.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/steps/step.tsx new file mode 100644 index 00000000000000..2abdca9e5c5f3a --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/steps/step.tsx @@ -0,0 +1,25 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { EuiFlexGroup, EuiFlexItem, EuiText } from '@elastic/eui'; + +interface Props { + description: React.ReactNode; + children: React.ReactNode; +} + +export const Step = ({ description, children }: Props) => { + return ( + + + {description} + + {children} + + ); +}; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/steps/step_config.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/steps/step_config.tsx new file mode 100644 index 00000000000000..83463610c4a4e9 --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/steps/step_config.tsx @@ -0,0 +1,153 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { EuiButton, EuiButtonEmpty, EuiFlexGroup, EuiFlexItem, EuiLink } from '@elastic/eui'; +import { FormMonitorType, Step, StepMap } from '../types'; +import { StepFields } from './step_fields'; + +const MONITOR_TYPE_STEP: Step = { + title: i18n.translate('xpack.synthetics.monitorConfig.monitorTypeStep.title', { + defaultMessage: 'Select a monitor type', + }), + children: ( + + {i18n.translate('xpack.synthetics.monitorConfig.monitorTypeStep.description', { + defaultMessage: 'Choose a monitor that best fits your use case', + })} +

+ } + stepKey="step1" + /> + ), +}; +const MONITOR_DETAILS_STEP: Step = { + title: i18n.translate('xpack.synthetics.monitorConfig.monitorDetailsStep.title', { + defaultMessage: 'Monitor details', + }), + children: ( + + {i18n.translate('xpack.synthetics.monitorConfig.monitorDetailsStep.description', { + defaultMessage: 'Provide some details about how your monitor should run', + })} +

+ } + stepKey="step2" + /> + ), +}; + +const SCRIPT_RECORDER_BTNS = ( + + + + {i18n.translate('xpack.synthetics.monitorConfig.monitorScriptStep.scriptRecorder.launch', { + defaultMessage: 'Launch Synthetics Recorder', + })} + + + + + {i18n.translate( + 'xpack.synthetics.monitorConfig.monitorScriptStep.scriptRecorder.download', + { + defaultMessage: 'Download Synthetics Recorder', + } + )} + + + +); + +const MONITOR_SCRIPT_STEP: Step = { + title: i18n.translate('xpack.synthetics.monitorConfig.monitorScriptStep.title', { + defaultMessage: 'Add a script', + }), + children: ( + +

+ + + + ), + }} + /> +

+ {SCRIPT_RECORDER_BTNS} + + } + stepKey="step3" + /> + ), +}; + +const MONITOR_SCRIPT_STEP_EDIT: Step = { + title: i18n.translate('xpack.synthetics.monitorConfig.monitorScriptEditStep.title', { + defaultMessage: 'Monitor script', + }), + children: ( + +

+ + + + ), + }} + /> +

+ {SCRIPT_RECORDER_BTNS} + + } + stepKey="scriptEdit" + /> + ), +}; + +export const ADD_MONITOR_STEPS: StepMap = { + [FormMonitorType.MULTISTEP]: [MONITOR_TYPE_STEP, MONITOR_DETAILS_STEP, MONITOR_SCRIPT_STEP], + [FormMonitorType.SINGLE]: [MONITOR_TYPE_STEP, MONITOR_DETAILS_STEP], + [FormMonitorType.HTTP]: [MONITOR_TYPE_STEP, MONITOR_DETAILS_STEP], + [FormMonitorType.ICMP]: [MONITOR_TYPE_STEP, MONITOR_DETAILS_STEP], + [FormMonitorType.TCP]: [MONITOR_TYPE_STEP, MONITOR_DETAILS_STEP], +}; + +export const EDIT_MONITOR_STEPS: StepMap = { + [FormMonitorType.MULTISTEP]: [MONITOR_SCRIPT_STEP_EDIT, MONITOR_DETAILS_STEP], + [FormMonitorType.SINGLE]: [MONITOR_DETAILS_STEP], + [FormMonitorType.HTTP]: [MONITOR_DETAILS_STEP], + [FormMonitorType.ICMP]: [MONITOR_DETAILS_STEP], + [FormMonitorType.TCP]: [MONITOR_DETAILS_STEP], +}; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/steps/step_fields.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/steps/step_fields.tsx new file mode 100644 index 00000000000000..2ac95831859131 --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/steps/step_fields.tsx @@ -0,0 +1,41 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { useFormContext, FieldError } from 'react-hook-form'; +import { Step } from './step'; +import { FORM_CONFIG } from '../form/form_config'; +import { Field } from '../form/field'; +import { ConfigKey, FormMonitorType, StepKey } from '../types'; + +export const StepFields = ({ + description, + stepKey, +}: { + description: React.ReactNode; + stepKey: StepKey; +}) => { + const { + watch, + formState: { errors }, + } = useFormContext(); + const [type]: [FormMonitorType] = watch([ConfigKey.FORM_MONITOR_TYPE]); + + return ( + + {FORM_CONFIG[type][stepKey]?.map((field) => { + return ( + + ); + })} + + ); +}; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/types.ts b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/types.ts new file mode 100644 index 00000000000000..e82dc2fa1fd978 --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/types.ts @@ -0,0 +1,68 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { + UseFormReturn, + ControllerRenderProps, + ControllerFieldState, + FormState, +} from 'react-hook-form'; +import { + ServiceLocations, + FormMonitorType, + SyntheticsMonitor, +} from '../../../../../common/runtime_types/monitor_management'; + +export type StepKey = 'step1' | 'step2' | 'step3' | 'scriptEdit'; + +export interface Step { + title: string; + children: React.ReactNode; +} + +export type StepMap = Record; + +export * from '../../../../../common/runtime_types/monitor_management'; +export * from '../../../../../common/types/monitor_validation'; + +export interface FieldMeta { + fieldKey: string; + component: React.ComponentType; + label?: string; + ariaLabel?: string; + helpText?: string | React.ReactNode; + props?: (params: { + field?: ControllerRenderProps; + formState: FormState; + setValue: UseFormReturn['setValue']; + reset: UseFormReturn['reset']; + locations: ServiceLocations; + dependencies: unknown[]; + dependenciesFieldMeta: Record; + space?: string; + isEdit?: boolean; + }) => Record; + controlled?: boolean; + required?: boolean; + shouldUseSetValue?: boolean; + customHook?: (value: unknown) => { + // custom hooks are only supported for controlled components and only supported for determining error validation + func: Function; + params: unknown; + fieldKey: string; + error: string; + }; + onChange?: ( + event: React.ChangeEvent, + formOnChange: (event: React.ChangeEvent) => void + ) => void; + showWhen?: [string, any]; // show field when another field equals an arbitrary value + validation?: (dependencies: unknown[]) => Parameters[1]; + error?: React.ReactNode; + dependencies?: string[]; // fields that another field may depend for or validation. Values are passed to the validation function +} diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/use_breadcrumbs.ts b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/use_breadcrumbs.ts index 2fb17340c25fcf..39d69bf64dea8d 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/use_breadcrumbs.ts +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/use_breadcrumbs.ts @@ -7,19 +7,24 @@ import { i18n } from '@kbn/i18n'; import { useKibana } from '@kbn/kibana-react-plugin/public'; import { useBreadcrumbs } from '../../hooks/use_breadcrumbs'; -import { MONITOR_ADD_ROUTE } from '../../../../../common/constants'; +import { MONITOR_ADD_ROUTE, MONITOR_EDIT_ROUTE } from '../../../../../common/constants'; import { PLUGIN } from '../../../../../common/constants/plugin'; -export const useMonitorAddEditBreadcrumbs = () => { +export const useMonitorAddEditBreadcrumbs = (isEdit?: boolean) => { const kibana = useKibana(); const appPath = kibana.services.application?.getUrlForApp(PLUGIN.SYNTHETICS_PLUGIN_ID) ?? ''; - useBreadcrumbs([ - { - text: ADD_MONITOR_CRUMB, - href: `${appPath}/${MONITOR_ADD_ROUTE}`, - }, - ]); + const config = isEdit + ? { + text: EDIT_MONITOR_CRUMB, + href: `${appPath}/${MONITOR_EDIT_ROUTE}`, + } + : { + text: ADD_MONITOR_CRUMB, + href: `${appPath}/${MONITOR_ADD_ROUTE}`, + }; + + useBreadcrumbs([config]); }; export const ADD_MONITOR_CRUMB = i18n.translate( @@ -28,3 +33,10 @@ export const ADD_MONITOR_CRUMB = i18n.translate( defaultMessage: 'Add monitor', } ); + +export const EDIT_MONITOR_CRUMB = i18n.translate( + 'xpack.synthetics.monitorManagement.editMonitorCrumb', + { + defaultMessage: 'Edit monitor', + } +); diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/management/monitor_list_table/actions.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/management/monitor_list_table/actions.tsx index aad917bccdee29..aeb5010f3496e9 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/management/monitor_list_table/actions.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/management/monitor_list_table/actions.tsx @@ -98,6 +98,7 @@ export const Actions = ({ euiTheme, id, name, reloadPage, canEditSynthetics }: P iconType="boxesHorizontal" color="primary" iconSide="right" + data-test-subj="syntheticsMonitorListActions" onClick={openPopover} /> ); @@ -139,7 +140,7 @@ export const Actions = ({ euiTheme, id, name, reloadPage, canEditSynthetics }: P key="xpack.synthetics.editMonitor" icon="pencil" onClick={closePopover} - href={`${basePath}/app/uptime/edit-monitor/${id}`} + href={`${basePath}/app/synthetics/edit-monitor/${id}`} disabled={!canEditSynthetics} > {labels.EDIT_LABEL} diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/management/monitor_list_table/monitor_details_link.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/management/monitor_list_table/monitor_details_link.tsx index c17112ce68aa9c..8a92811b9b5c8b 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/management/monitor_list_table/monitor_details_link.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/management/monitor_list_table/monitor_details_link.tsx @@ -13,6 +13,7 @@ import { ConfigKey, EncryptedSyntheticsSavedMonitor, } from '../../../../../../../common/runtime_types'; +import { useMonitorDetailLocator } from '../../hooks/use_monitor_detail_locator'; export const MonitorDetailsLink = ({ basePath, @@ -30,13 +31,11 @@ export const MonitorDetailsLink = ({ const locationId = lastSelectedLocationId && monitorHasLocation ? lastSelectedLocationId : firstMonitorLocationId; - const locationUrlQueryParam = locationId ? `?locationId=${locationId}` : ''; + const monitorDetailLinkUrl = useMonitorDetailLocator({ monitorId: monitor.id, locationId }); return ( <> - - {monitor.name} - + {monitor.name} ); }; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/management/page_header/monitors_page_header.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/management/page_header/monitors_page_header.tsx index 7ac40ae361ae6f..763965b0af17af 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/management/page_header/monitors_page_header.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/management/page_header/monitors_page_header.tsx @@ -42,7 +42,7 @@ export const MonitorsPageHeader = () => { fill iconSide="left" iconType="plusInCircleFilled" - href={`${basePath}/app/uptime${MONITOR_ADD_ROUTE}`} + href={`${basePath}/app/synthetics${MONITOR_ADD_ROUTE}`} isDisabled={!isEnabled} data-test-subj="syntheticsAddMonitorBtn" > diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/actions_popover.test.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/actions_popover.test.tsx new file mode 100644 index 00000000000000..af6799068c2785 --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/actions_popover.test.tsx @@ -0,0 +1,152 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { fireEvent } from '@testing-library/react'; +import { render } from '../../../../utils/testing/rtl_helpers'; +import { ActionsPopover } from './actions_popover'; +import * as editMonitorLocatorModule from '../../hooks/use_edit_monitor_locator'; +import * as monitorDetailLocatorModule from '../../hooks/use_monitor_detail_locator'; +import * as monitorEnableHandlerModule from '../../../../hooks/use_monitor_enable_handler'; +import { FETCH_STATUS } from '@kbn/observability-plugin/public'; +import { MonitorOverviewItem } from '../types'; + +describe('ActionsPopover', () => { + let testMonitor: MonitorOverviewItem; + + beforeEach(() => { + testMonitor = { + location: { + id: 'us_central', + isServiceManaged: true, + }, + isEnabled: true, + name: 'Monitor 1', + id: 'somelongstring', + }; + }); + + afterEach(() => { + jest.restoreAllMocks(); + }); + + it('renders the popover button', () => { + const { queryByText, getByLabelText } = render( + + ); + expect(getByLabelText('Open actions menu')); + expect(queryByText('Actions')).not.toBeInTheDocument(); + }); + + it('opens the popover on click', async () => { + const setIsPopoverOpen = jest.fn(); + const isPopoverOpen = false; + const { getByLabelText } = render( + + ); + const popoverButton = getByLabelText('Open actions menu'); + fireEvent.click(popoverButton); + expect(setIsPopoverOpen).toHaveBeenCalled(); + // the popover passes back a function that accepts a bool and returns the inverse, + // so we're calling it here just to make sure the behavior is correct + expect(setIsPopoverOpen.mock.calls[0][0](isPopoverOpen)).toBe(true); + }); + + it('closes the popover on subsequent click', async () => { + const setIsPopoverOpen = jest.fn(); + const isPopoverOpen = true; + const { getByLabelText } = render( + + ); + const popoverButton = getByLabelText('Open actions menu'); + fireEvent.click(popoverButton); + expect(setIsPopoverOpen).toHaveBeenCalled(); + // the popover passes back a function that accepts a bool and returns the inverse, + // so we're calling it here just to make sure the behavior is correct + expect(setIsPopoverOpen.mock.calls[0][0](isPopoverOpen)).toBe(false); + }); + + it('contains link to edit page', async () => { + jest + .spyOn(editMonitorLocatorModule, 'useEditMonitorLocator') + .mockReturnValue('/a/test/edit/url'); + const { getByRole } = render( + + ); + expect(getByRole('link')?.getAttribute('href')).toBe('/a/test/edit/url'); + }); + + it('contains link to detail page', async () => { + jest + .spyOn(monitorDetailLocatorModule, 'useMonitorDetailLocator') + .mockReturnValue('/a/test/detail/url'); + const { getByRole } = render( + + ); + expect(getByRole('link')?.getAttribute('href')).toBe('/a/test/detail/url'); + }); + + it('sets the enabled state', async () => { + const updateMonitorEnabledState = jest.fn(); + jest.spyOn(monitorEnableHandlerModule, 'useMonitorEnableHandler').mockReturnValue({ + status: FETCH_STATUS.SUCCESS, + isEnabled: true, + updateMonitorEnabledState, + }); + const { getByText } = render( + + ); + const enableButton = getByText('Disable monitor'); + fireEvent.click(enableButton); + expect(updateMonitorEnabledState).toHaveBeenCalledTimes(1); + expect(updateMonitorEnabledState.mock.calls[0]).toEqual([ + { + id: 'somelongstring', + isEnabled: true, + location: { id: 'us_central', isServiceManaged: true }, + name: 'Monitor 1', + }, + false, + ]); + }); + + it('sets enabled state to true', async () => { + const updateMonitorEnabledState = jest.fn(); + jest.spyOn(monitorEnableHandlerModule, 'useMonitorEnableHandler').mockReturnValue({ + status: FETCH_STATUS.PENDING, + isEnabled: null, + updateMonitorEnabledState, + }); + const { getByText } = render( + + ); + const enableButton = getByText('Enable monitor'); + fireEvent.click(enableButton); + expect(updateMonitorEnabledState).toHaveBeenCalledTimes(1); + expect(updateMonitorEnabledState.mock.calls[0]).toEqual([ + { + id: 'somelongstring', + isEnabled: false, + location: { id: 'us_central', isServiceManaged: true }, + name: 'Monitor 1', + }, + true, + ]); + }); +}); diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/actions_popover.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/actions_popover.tsx new file mode 100644 index 00000000000000..932c6344c4716a --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/actions_popover.tsx @@ -0,0 +1,220 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { i18n } from '@kbn/i18n'; +import { EuiPopover, EuiButtonIcon, EuiContextMenu, useEuiShadow } from '@elastic/eui'; +import { FETCH_STATUS } from '@kbn/observability-plugin/public'; +import { useTheme } from '@kbn/observability-plugin/public'; +import React, { useCallback, useEffect, useMemo, useState } from 'react'; +import { useDispatch, useSelector } from 'react-redux'; +import styled from 'styled-components'; +import { MonitorOverviewItem } from '../../../../../../../common/runtime_types'; +import { useMonitorEnableHandler } from '../../../../hooks/use_monitor_enable_handler'; +import { quietFetchOverviewAction } from '../../../../state/overview/actions'; +import { selectOverviewState } from '../../../../state/overview/selectors'; +import { useEditMonitorLocator } from '../../hooks/use_edit_monitor_locator'; +import { useMonitorDetailLocator } from '../../hooks/use_monitor_detail_locator'; + +interface ActionContainerProps { + boxShadow: string; +} + +const ActionContainer = styled.div` + // position + display: inline-block; + position: relative; + bottom: 42px; + left: 12px; + z-index: 1; + + // style + border-radius: ${({ theme }) => theme.eui.euiBorderRadius}; + ${({ boxShadow }) => boxShadow} +`; + +export function ActionsPopover({ + isPopoverOpen, + setIsPopoverOpen, + monitor, +}: { + isPopoverOpen: boolean; + monitor: MonitorOverviewItem; + setIsPopoverOpen: React.Dispatch>; +}) { + const theme = useTheme(); + const euiShadow = useEuiShadow('l'); + const dispatch = useDispatch(); + const { pageState } = useSelector(selectOverviewState); + + const detailUrl = useMonitorDetailLocator({ + monitorId: monitor.id, + locationId: monitor.location.id, + }); + const editUrl = useEditMonitorLocator({ monitorId: monitor.id }); + + const labels = useMemo( + () => ({ + enabledSuccessLabel: enabledSuccessLabel(monitor.name), + disabledSuccessLabel: disabledSuccessLabel(monitor.name), + failureLabel: enabledFailLabel(monitor.name), + }), + [monitor.name] + ); + const { status, isEnabled, updateMonitorEnabledState } = useMonitorEnableHandler({ + id: monitor.id, + reloadPage: useCallback(() => { + dispatch(quietFetchOverviewAction.get(pageState)); + setIsPopoverOpen(false); + }, [dispatch, pageState, setIsPopoverOpen]), + labels, + }); + + const [enableLabel, setEnableLabel] = useState( + monitor.isEnabled ? disableMonitorLabel : enableMonitorLabel + ); + + useEffect(() => { + if (status === FETCH_STATUS.LOADING) { + setEnableLabel(enableLabelLoading); + } else if (status === FETCH_STATUS.SUCCESS) { + setEnableLabel(isEnabled ? disableMonitorLabel : enableMonitorLabel); + } + }, [setEnableLabel, status, isEnabled, monitor.isEnabled]); + + return ( + + setIsPopoverOpen((b: boolean) => !b)} + /> + } + color="lightestShade" + isOpen={isPopoverOpen} + closePopover={() => setIsPopoverOpen(false)} + anchorPosition="rightUp" + panelPaddingSize="none" + > + { + if (status !== FETCH_STATUS.LOADING) + updateMonitorEnabledState(monitor, !monitor.isEnabled); + }, + }, + ], + }, + ]} + /> + + + ); +} + +const openActionsMenuAria = i18n.translate( + 'xpack.synthetics.overview.actions.openPopover.ariaLabel', + { + defaultMessage: 'Open actions menu', + } +); + +const actionsMenuTitle = i18n.translate('xpack.synthetics.overview.actions.menu.title', { + defaultMessage: 'Actions', + description: 'This is the text in the heading of a menu containing a set of actions', +}); + +const actionsMenuGoToMonitorName = i18n.translate( + 'xpack.synthetics.overview.actions.goToMonitor.name', + { + defaultMessage: 'Go to monitor', + description: + 'This is the text for a menu item that will take the user to the monitor detail page', + } +); + +const actionsMenuEditMonitorName = i18n.translate( + 'xpack.synthetics.overview.actions.editMonitor.name', + { + defaultMessage: 'Edit monitor', + description: + 'This is the text for a menu item that will take the user to the monitor edit page', + } +); + +const enableLabelLoading = i18n.translate('xpack.synthetics.overview.actions.enableLabel', { + defaultMessage: 'Loading...', +}); + +const enableMonitorLabel = i18n.translate( + 'xpack.synthetics.overview.actions.enableLabelEnableMonitor', + { + defaultMessage: 'Enable monitor', + } +); + +const disableMonitorLabel = i18n.translate( + 'xpack.synthetics.overview.actions.enableLabelDisableMonitor', + { + defaultMessage: 'Disable monitor', + } +); + +const enabledSuccessLabel = (name: string) => + i18n.translate('xpack.synthetics.overview.actions.enabledSuccessLabel', { + defaultMessage: 'Monitor "{name}" enabled successfully', + values: { name }, + }); + +export const disabledSuccessLabel = (name: string) => + i18n.translate('xpack.synthetics.overview.actions.disabledSuccessLabel', { + defaultMessage: 'Monitor "{name}" disabled successfully.', + values: { name }, + }); + +export const enabledFailLabel = (name: string) => + i18n.translate('xpack.synthetics.overview.actions.enabledFailLabel', { + defaultMessage: 'Unable to update monitor "{name}".', + values: { name }, + }); diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/metric_item.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/metric_item.tsx index 3348f529fe7992..755777bad04ea3 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/metric_item.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/metric_item.tsx @@ -4,15 +4,16 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import React from 'react'; import { i18n } from '@kbn/i18n'; +import React, { useState } from 'react'; import { Chart, Settings, Metric, MetricTrendShape } from '@elastic/charts'; import { EuiPanel, EuiLoadingChart } from '@elastic/eui'; import { DARK_THEME } from '@elastic/charts'; import { useTheme } from '@kbn/observability-plugin/public'; import { useLocationName, useStatusByLocation } from '../../../../hooks'; import { formatDuration } from '../../../../utils/formatting'; -import { Ping } from '../../../../../../../common/runtime_types'; +import { MonitorOverviewItem, Ping } from '../../../../../../../common/runtime_types'; +import { ActionsPopover } from './actions_popover'; export const getColor = (theme: ReturnType, isEnabled: boolean, ping?: Ping) => { if (!isEnabled) { @@ -24,24 +25,20 @@ export const getColor = (theme: ReturnType, isEnabled: boolean, }; export const MetricItem = ({ - monitorId, - locationId, - monitorName, - isMonitorEnabled, + monitor, averageDuration, data, loaded, }: { - monitorId: string; - locationId: string; - monitorName: string; - isMonitorEnabled: boolean; + monitor: MonitorOverviewItem; data: Array<{ x: number; y: number }>; averageDuration: number; loaded: boolean; }) => { - const locationName = useLocationName({ locationId }); - const { locations } = useStatusByLocation(monitorId); + const [isMouseOver, setIsMouseOver] = useState(false); + const [isPopoverOpen, setIsPopoverOpen] = useState(false); + const locationName = useLocationName({ locationId: monitor.location?.id }); + const { locations } = useStatusByLocation(monitor.id); const ping = locations.find((loc) => loc.observer?.geo?.name === locationName); const theme = useTheme(); @@ -53,6 +50,16 @@ export const MetricItem = ({ > {loaded ? ( { + if (!isMouseOver) { + setIsMouseOver(true); + } + }} + onMouseLeave={() => { + if (isMouseOver) { + setIsMouseOver(false); + } + }} style={{ padding: '0px', height: '100%', @@ -62,11 +69,11 @@ export const MetricItem = ({ ), valueFormatter: (d: number) => formatDuration(d), - color: getColor(theme, isMonitorEnabled, ping), + color: getColor(theme, monitor.isEnabled, ping), }, ], ]} /> + {(isMouseOver || isPopoverOpen) && ( + + )} ) : ( diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/overview_grid.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/overview_grid.tsx index 24059c6e903303..898e68ba840014 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/overview_grid.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/overview_grid.tsx @@ -40,12 +40,7 @@ export const OverviewGrid = () => { key={`${monitor.id}-${monitor.location?.id}`} data-test-subj="syntheticsOverviewGridItem" > - + ))} diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/overview_grid_item.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/overview_grid_item.tsx index b11534b096f91f..d9141c5cbeb851 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/overview_grid_item.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/overview_grid_item.tsx @@ -7,28 +7,14 @@ import React from 'react'; import { MetricItem } from './metric_item'; import { useLast50DurationChart } from '../../../../hooks'; +import { MonitorOverviewItem } from '../../../../../../../common/runtime_types'; -export const OverviewGridItem = ({ - monitorId, - monitorName, - locationId, - isMonitorEnabled, -}: { - monitorId: string; - monitorName: string; - locationId: string; - isMonitorEnabled: boolean; -}) => { - const { data, loading, averageDuration } = useLast50DurationChart({ locationId, monitorId }); +export const OverviewGridItem = ({ monitor }: { monitor: MonitorOverviewItem }) => { + const { data, loading, averageDuration } = useLast50DurationChart({ + locationId: monitor.location?.id, + monitorId: monitor.id, + }); return ( - + ); }; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/hooks/use_last_50_duration_chart.ts b/x-pack/plugins/synthetics/public/apps/synthetics/hooks/use_last_50_duration_chart.ts index 6bfd3616e86548..a543c146ec82bf 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/hooks/use_last_50_duration_chart.ts +++ b/x-pack/plugins/synthetics/public/apps/synthetics/hooks/use_last_50_duration_chart.ts @@ -37,7 +37,7 @@ export function useLast50DurationChart({ const coords = hits .reverse() // results are returned in desc order by timestamp. Reverse to ensure the data is in asc order by timestamp .map((hit, index) => { - const duration = hit['monitor.duration.us']?.[0]; + const duration = hit?.['monitor.duration.us']?.[0]; totalDuration += duration || 0; if (duration === undefined) { return null; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/hooks/use_monitor_enable_handler.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/hooks/use_monitor_enable_handler.tsx index e1703654f85383..6fed27f2df6b5b 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/hooks/use_monitor_enable_handler.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/hooks/use_monitor_enable_handler.tsx @@ -9,7 +9,11 @@ import { useKibana } from '@kbn/kibana-react-plugin/public'; import { FETCH_STATUS } from '@kbn/observability-plugin/public'; import React, { useCallback, useEffect, useState } from 'react'; import { useDispatch, useSelector } from 'react-redux'; -import { ConfigKey, EncryptedSyntheticsMonitor } from '../components/monitors_page/overview/types'; +import { + ConfigKey, + EncryptedSyntheticsMonitor, + MonitorOverviewItem, +} from '../components/monitors_page/overview/types'; import { clearMonitorUpsertStatus, fetchUpsertMonitorAction, @@ -37,7 +41,7 @@ export function useMonitorEnableHandler({ const savedObjEnabledState = upsertStatuses[id]?.enabled; const [isEnabled, setIsEnabled] = useState(null); const updateMonitorEnabledState = useCallback( - (monitor: EncryptedSyntheticsMonitor, enabled: boolean) => { + (monitor: EncryptedSyntheticsMonitor | MonitorOverviewItem, enabled: boolean) => { dispatch( fetchUpsertMonitorAction({ id, @@ -82,5 +86,5 @@ export function useMonitorEnableHandler({ savedObjEnabledState, ]); - return { isEnabled, setIsEnabled, updateMonitorEnabledState, status }; + return { isEnabled, updateMonitorEnabledState, status }; } diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/routes.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/routes.tsx index 9356b55ce5eb2f..34e3b23f48ca68 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/routes.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/routes.tsx @@ -7,26 +7,38 @@ import { EuiThemeComputed } from '@elastic/eui/src/services/theme/types'; import React, { FC, useEffect } from 'react'; -import { tint } from 'polished'; -import { EuiPageTemplateProps, EuiFlexGroup, EuiFlexItem, useEuiTheme } from '@elastic/eui'; +import { + EuiPageTemplateProps, + EuiFlexGroup, + EuiFlexItem, + EuiLink, + useEuiTheme, +} from '@elastic/eui'; import { Route, Switch, useHistory } from 'react-router-dom'; +import { OutPortal } from 'react-reverse-portal'; import { FormattedMessage } from '@kbn/i18n-react'; import { i18n } from '@kbn/i18n'; import { APP_WRAPPER_CLASS } from '@kbn/core/public'; import { useInspectorContext } from '@kbn/observability-plugin/public'; +import { MonitorAddPage } from './components/monitor_add_edit/monitor_add_page'; +import { MonitorEditPage } from './components/monitor_add_edit/monitor_edit_page'; import { RunTestManually } from './components/monitor_summary/run_test_manually'; import { MonitorSummaryHeaderContent } from './components/monitor_summary/monitor_summary_header_content'; import { MonitorSummaryTitle } from './components/monitor_summary/monitor_summary_title'; import { MonitorSummaryPage } from './components/monitor_summary/monitor_summary'; import { GettingStartedPage } from './components/getting_started/getting_started_page'; -import { MonitorAddEditPage } from './components/monitor_add_edit/monitor_add_edit_page'; import { MonitorsPageHeader } from './components/monitors_page/management/page_header/monitors_page_header'; import { OverviewPage } from './components/monitors_page/overview/overview_page'; import { SyntheticsPageTemplateComponent } from './components/common/pages/synthetics_page_template'; import { NotFoundPage } from './components/common/pages/not_found'; import { ServiceAllowedWrapper } from './components/common/wrappers/service_allowed_wrapper'; +import { + MonitorTypePortalNode, + MonitorDetailsLinkPortalNode, +} from './components/monitor_add_edit/portals'; import { MONITOR_ADD_ROUTE, + MONITOR_EDIT_ROUTE, MONITORS_ROUTE, OVERVIEW_ROUTE, GETTING_STARTED_ROUTE, @@ -158,17 +170,7 @@ const getRoutes = ( ), dataTestSubj: 'syntheticsMonitorManagementPage', - paddingSize: 'none', - pageBodyProps: { - style: { backgroundColor: tint(0.5, euiTheme.colors.body) }, - }, - pageContentProps: { - paddingSize: 'l', - style: { backgroundColor: euiTheme.colors.ghost }, - }, pageHeader: { - paddingSize: 'l', - style: { margin: 0 }, pageTitle: , tabs: [ { @@ -196,27 +198,68 @@ const getRoutes = ( }, }, { - title: i18n.translate('xpack.synthetics.addMonitorRoute.title', { - defaultMessage: 'Add Monitor | {baseTitle}', + title: i18n.translate('xpack.synthetics.createMonitorRoute.title', { + defaultMessage: 'Create Monitor | {baseTitle}', values: { baseTitle }, }), path: MONITOR_ADD_ROUTE, component: () => ( - + ), dataTestSubj: 'syntheticsMonitorAddPage', pageHeader: { pageTitle: ( ), + children: ( + + + + ), + }} + /> + ), + }, + }, + { + title: i18n.translate('xpack.synthetics.editMonitorRoute.title', { + defaultMessage: 'Edit Monitor | {baseTitle}', + values: { baseTitle }, + }), + path: MONITOR_EDIT_ROUTE, + component: () => ( + + + + ), + dataTestSubj: 'syntheticsMonitorEditPage', + pageHeader: { + pageTitle: ( + + ), + rightSideItems: [], + breadcrumbs: [ + { + text: , + }, + ], }, - // bottomBar: , - bottomBarProps: { paddingSize: 'm' as const }, }, ]; }; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/state/monitor_list/actions.ts b/x-pack/plugins/synthetics/public/apps/synthetics/state/monitor_list/actions.ts index bd65a771de531e..3315719a6bb160 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/state/monitor_list/actions.ts +++ b/x-pack/plugins/synthetics/public/apps/synthetics/state/monitor_list/actions.ts @@ -10,6 +10,7 @@ import { createAction } from '@reduxjs/toolkit'; import { EncryptedSyntheticsMonitor, MonitorManagementListResult, + MonitorOverviewItem, } from '../../../../../common/runtime_types'; import { createAsyncAction } from '../utils/actions'; @@ -22,7 +23,7 @@ export const fetchMonitorListAction = createAsyncAction< export interface UpsertMonitorRequest { id: string; - monitor: EncryptedSyntheticsMonitor; + monitor: EncryptedSyntheticsMonitor | MonitorOverviewItem; } export const fetchUpsertMonitorAction = createAction('fetchUpsertMonitor'); export const fetchUpsertSuccessAction = createAction<{ diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/state/monitor_list/api.ts b/x-pack/plugins/synthetics/public/apps/synthetics/state/monitor_list/api.ts index 97d60011e35d48..5e4e2e1bc1a673 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/state/monitor_list/api.ts +++ b/x-pack/plugins/synthetics/public/apps/synthetics/state/monitor_list/api.ts @@ -11,6 +11,7 @@ import { FetchMonitorManagementListQueryArgs, MonitorManagementListResult, MonitorManagementListResultCodec, + MonitorOverviewItem, ServiceLocationErrors, SyntheticsMonitor, } from '../../../../../common/runtime_types'; @@ -54,7 +55,7 @@ export const fetchUpsertMonitor = async ({ monitor, id, }: { - monitor: SyntheticsMonitor | EncryptedSyntheticsMonitor; + monitor: SyntheticsMonitor | EncryptedSyntheticsMonitor | MonitorOverviewItem; id?: string; }): Promise<{ attributes: { errors: ServiceLocationErrors } } | SyntheticsMonitor> => { if (id) { diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/state/monitor_management/api.ts b/x-pack/plugins/synthetics/public/apps/synthetics/state/monitor_management/api.ts new file mode 100644 index 00000000000000..66d298f26df2bf --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/state/monitor_management/api.ts @@ -0,0 +1,42 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { apiService } from '../../../../utils/api_service'; +import { + EncryptedSyntheticsMonitor, + ServiceLocationErrors, + SyntheticsMonitor, + SyntheticsMonitorWithId, +} from '../../../../../common/runtime_types'; +import { API_URLS } from '../../../../../common/constants'; +import { DecryptedSyntheticsMonitorSavedObject } from '../../../../../common/types'; + +export const createMonitorAPI = async ({ + monitor, +}: { + monitor: SyntheticsMonitor | EncryptedSyntheticsMonitor; +}): Promise<{ attributes: { errors: ServiceLocationErrors } } | SyntheticsMonitor> => { + return await apiService.post(API_URLS.SYNTHETICS_MONITORS, monitor); +}; + +export const updateMonitorAPI = async ({ + monitor, + id, +}: { + monitor: SyntheticsMonitor | EncryptedSyntheticsMonitor; + id: string; +}): Promise<{ attributes: { errors: ServiceLocationErrors } } | SyntheticsMonitorWithId> => { + return await apiService.put(`${API_URLS.SYNTHETICS_MONITORS}/${id}`, monitor); +}; + +export const getMonitorAPI = async ({ + id, +}: { + id: string; +}): Promise => { + return await apiService.get(`${API_URLS.SYNTHETICS_MONITORS}/${id}`); +}; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/synthetics_app.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/synthetics_app.tsx index 1efc0fdc69a4f2..da86d7d9510b68 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/synthetics_app.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/synthetics_app.tsx @@ -83,6 +83,7 @@ const Application = (props: SyntheticsAppProps) => { triggersActionsUi: startPlugins.triggersActionsUi, observability: startPlugins.observability, cases: startPlugins.cases, + spaces: startPlugins.spaces, }} > diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/app/use_no_data_config.ts b/x-pack/plugins/synthetics/public/legacy_uptime/app/use_no_data_config.ts index af51f397868986..64d72aa248d787 100644 --- a/x-pack/plugins/synthetics/public/legacy_uptime/app/use_no_data_config.ts +++ b/x-pack/plugins/synthetics/public/legacy_uptime/app/use_no_data_config.ts @@ -9,12 +9,12 @@ import { i18n } from '@kbn/i18n'; import { useContext } from 'react'; import { useSelector } from 'react-redux'; import { useKibana } from '@kbn/kibana-react-plugin/public'; -import { KibanaPageTemplateProps } from '@kbn/shared-ux-components'; +import type { NoDataConfig } from '@kbn/shared-ux-page-kibana-template'; import { UptimeSettingsContext } from '../contexts'; import { ClientPluginsStart } from '../../plugin'; import { indexStatusSelector } from '../state/selectors'; -export function useNoDataConfig(): KibanaPageTemplateProps['noDataConfig'] { +export function useNoDataConfig(): NoDataConfig | undefined { const { basePath } = useContext(UptimeSettingsContext); const { diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/normalizers.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/normalizers.ts index 6d1e51a66f49a2..0746f2cdae2799 100644 --- a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/normalizers.ts +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/normalizers.ts @@ -112,5 +112,6 @@ export const browserNormalizers: BrowserNormalizerMap = { [ConfigKey.PLAYWRIGHT_OPTIONS]: getBrowserNormalizer(ConfigKey.PLAYWRIGHT_OPTIONS), [ConfigKey.CUSTOM_HEARTBEAT_ID]: getBrowserNormalizer(ConfigKey.CUSTOM_HEARTBEAT_ID), [ConfigKey.ORIGINAL_SPACE]: getBrowserNormalizer(ConfigKey.ORIGINAL_SPACE), + [ConfigKey.TEXT_ASSERTION]: getBrowserNormalizer(ConfigKey.TEXT_ASSERTION), ...commonNormalizers, }; diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/common/normalizers.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/common/normalizers.ts index 4e67eb671fa22d..bdea46781dfd96 100644 --- a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/common/normalizers.ts +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/common/normalizers.ts @@ -91,4 +91,5 @@ export const commonNormalizers: CommonNormalizerMap = { fields?.[ConfigKey.NAMESPACE]?.value ?? DEFAULT_NAMESPACE_STRING, [ConfigKey.REVISION]: getCommonNormalizer(ConfigKey.REVISION), [ConfigKey.MONITOR_SOURCE_TYPE]: getCommonNormalizer(ConfigKey.MONITOR_SOURCE_TYPE), + [ConfigKey.FORM_MONITOR_TYPE]: getCommonNormalizer(ConfigKey.FORM_MONITOR_TYPE), }; diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/columns/ping_timestamp/ping_timestamp.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/columns/ping_timestamp/ping_timestamp.tsx index 3058aaacb4d850..1eef87ed9efcd1 100644 --- a/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/columns/ping_timestamp/ping_timestamp.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/columns/ping_timestamp/ping_timestamp.tsx @@ -7,7 +7,7 @@ import React, { useContext, useEffect, useState } from 'react'; import useIntersection from 'react-use/lib/useIntersection'; -import styled from 'styled-components'; +import { euiStyled } from '@kbn/kibana-react-plugin/common'; import { EuiFlexGroup, EuiFlexItem, EuiText } from '@elastic/eui'; import { useInProgressImage } from './use_in_progress_image'; @@ -23,11 +23,9 @@ import { StepImageCaption } from './step_image_caption'; import { StepImagePopover } from './step_image_popover'; import { formatCaptionContent } from './translations'; -const StepDiv = styled.div` - figure.euiImage { - div.stepArrowsFullScreen { - display: none; - } +const StepDiv = euiStyled.div` + figcaption { + display: none; } `; diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/columns/ping_timestamp/step_image_popover.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/columns/ping_timestamp/step_image_popover.tsx index 39b1a40570db23..511253b578a31c 100644 --- a/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/columns/ping_timestamp/step_image_popover.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/columns/ping_timestamp/step_image_popover.tsx @@ -7,23 +7,19 @@ import { EuiImage, EuiPopover } from '@elastic/eui'; import React from 'react'; -import styled from 'styled-components'; +import { euiStyled } from '@kbn/kibana-react-plugin/common'; import { LoadingImageState } from './no_image_available'; -import { ScreenshotRefImageData } from '../../../../../../../common/runtime_types/ping/synthetics'; +import { ScreenshotRefImageData } from '../../../../../../../common/runtime_types'; import { fullSizeImageAlt } from './translations'; import { useCompositeImage } from '../../../../../hooks/use_composite_image'; const POPOVER_IMG_HEIGHT = 360; const POPOVER_IMG_WIDTH = 640; -const StepImage = styled(EuiImage)` - &&& { - display: flex; - figure.euiImageFullScreenWrapper { +const StepImage = euiStyled(EuiImage)` + &&& .euiImageFullScreenWrapper { + figcaption { display: flex; - div.stepArrowsFullScreen { - display: flex; - } } } `; diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/settings/settings_bottom_bar.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/settings/settings_bottom_bar.tsx index b080c3ea897125..99d672b24dd748 100644 --- a/x-pack/plugins/synthetics/public/legacy_uptime/components/settings/settings_bottom_bar.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/settings/settings_bottom_bar.tsx @@ -6,7 +6,7 @@ */ import React from 'react'; -import { OutPortal, createPortalNode, InPortal } from 'react-reverse-portal'; +import { OutPortal, createHtmlPortalNode, InPortal } from 'react-reverse-portal'; import { SettingsActions, SettingsActionsProps } from './settings_actions'; export const SettingsBottomBar = () => { @@ -24,4 +24,4 @@ export const SettingsActionBarPortal = (props: SettingsActionsProps) => { ); }; -export const SettingsBarPortalNode = createPortalNode(); +export const SettingsBarPortalNode = createHtmlPortalNode(); diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/hooks/__snapshots__/use_url_params.test.tsx.snap b/x-pack/plugins/synthetics/public/legacy_uptime/hooks/__snapshots__/use_url_params.test.tsx.snap index 5bac7ff7caf766..febc67e115ef9f 100644 --- a/x-pack/plugins/synthetics/public/legacy_uptime/hooks/__snapshots__/use_url_params.test.tsx.snap +++ b/x-pack/plugins/synthetics/public/legacy_uptime/hooks/__snapshots__/use_url_params.test.tsx.snap @@ -148,6 +148,7 @@ exports[`useUrlParams deletes keys that do not have truthy values 1`] = ` Array [], Array [], Array [], + Array [], ], "results": Array [ Object { @@ -174,6 +175,12 @@ exports[`useUrlParams deletes keys that do not have truthy values 1`] = ` "selectedFilters": null, }, }, + Object { + "type": "return", + "value": Object { + "selectedFilters": null, + }, + }, ], }, "replaceReducer": [MockFunction], @@ -378,6 +385,7 @@ exports[`useUrlParams gets the expected values using the context 1`] = ` Array [], Array [], Array [], + Array [], ], "results": Array [ Object { @@ -404,6 +412,12 @@ exports[`useUrlParams gets the expected values using the context 1`] = ` "selectedFilters": null, }, }, + Object { + "type": "return", + "value": Object { + "selectedFilters": null, + }, + }, ], }, "replaceReducer": [MockFunction], diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/pages/monitor_management/portals.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/pages/monitor_management/portals.tsx index 2ca83d1f6972f8..b4574d2a5c6d38 100644 --- a/x-pack/plugins/synthetics/public/legacy_uptime/pages/monitor_management/portals.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/pages/monitor_management/portals.tsx @@ -5,10 +5,10 @@ * 2.0. */ -import { createPortalNode } from 'react-reverse-portal'; +import { createHtmlPortalNode } from 'react-reverse-portal'; -export const ActionBarPortalNode = createPortalNode(); +export const ActionBarPortalNode = createHtmlPortalNode(); -export const APIKeysPortalNode = createPortalNode(); +export const APIKeysPortalNode = createHtmlPortalNode(); -export const ManageLocationsPortalNode = createPortalNode(); +export const ManageLocationsPortalNode = createHtmlPortalNode(); diff --git a/x-pack/plugins/synthetics/public/plugin.ts b/x-pack/plugins/synthetics/public/plugin.ts index 4ccb6965a51228..cb70efbd19854b 100644 --- a/x-pack/plugins/synthetics/public/plugin.ts +++ b/x-pack/plugins/synthetics/public/plugin.ts @@ -40,6 +40,7 @@ import { Start as InspectorPluginStart } from '@kbn/inspector-plugin/public'; import { CasesUiStart } from '@kbn/cases-plugin/public'; import { CloudSetup, CloudStart } from '@kbn/cloud-plugin/public'; import { DataViewsPublicPluginStart } from '@kbn/data-views-plugin/public'; +import { SpacesPluginStart } from '@kbn/spaces-plugin/public'; import { PLUGIN } from '../common/constants/plugin'; import { MONITORS_ROUTE } from '../common/constants/ui'; import { @@ -76,6 +77,7 @@ export interface ClientPluginsStart { triggersActionsUi: TriggersAndActionsUIPublicPluginStart; cases: CasesUiStart; dataViews: DataViewsPublicPluginStart; + spaces: SpacesPluginStart; cloud?: CloudStart; } @@ -194,7 +196,6 @@ export class UptimePlugin ], mount: async (params: AppMountParameters) => { const [coreStart, corePlugins] = await core.getStartServices(); - const { renderApp } = await import('./legacy_uptime/app/render_app'); return renderApp(coreStart, plugins, corePlugins, params, this.initContext.env.mode.dev); }, diff --git a/x-pack/plugins/synthetics/server/routes/monitor_cruds/edit_monitor.ts b/x-pack/plugins/synthetics/server/routes/monitor_cruds/edit_monitor.ts index c692bd25415d0a..a5d8365d0de2ab 100644 --- a/x-pack/plugins/synthetics/server/routes/monitor_cruds/edit_monitor.ts +++ b/x-pack/plugins/synthetics/server/routes/monitor_cruds/edit_monitor.ts @@ -4,7 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ - +import { mergeWith } from 'lodash'; import { schema } from '@kbn/config-schema'; import { SavedObjectsUpdateResponse, @@ -20,6 +20,7 @@ import { SyntheticsMonitorWithSecrets, SyntheticsMonitor, ConfigKey, + FormMonitorType, } from '../../../common/runtime_types'; import { SyntheticsRestApiRouteFactory } from '../../legacy_uptime/routes/types'; import { API_URLS } from '../../../common/constants'; @@ -77,10 +78,7 @@ export const editSyntheticsMonitorRoute: SyntheticsRestApiRouteFactory = () => ( ); const normalizedPreviousMonitor = normalizeSecrets(decryptedPreviousMonitor).attributes; - const editedMonitor = { - ...normalizedPreviousMonitor, - ...monitor, - }; + const editedMonitor = mergeWith(normalizedPreviousMonitor, monitor, customizer); const validationResult = validateMonitor(editedMonitor as MonitorFields); @@ -94,12 +92,15 @@ export const editSyntheticsMonitorRoute: SyntheticsRestApiRouteFactory = () => ( revision: (previousMonitor.attributes[ConfigKey.REVISION] || 0) + 1, }; const formattedMonitor = formatSecrets(monitorWithRevision); + const isMultiStepMonitor = + monitor.type === 'browser' && + monitor[ConfigKey.FORM_MONITOR_TYPE] !== FormMonitorType.SINGLE; const editedMonitorSavedObject: SavedObjectsUpdateResponse = await savedObjectsClient.update( syntheticsMonitorType, monitorId, - monitor.type === 'browser' ? { ...formattedMonitor, urls: '' } : formattedMonitor + isMultiStepMonitor ? { ...formattedMonitor, urls: '' } : formattedMonitor ); const errors = await syncEditedMonitor({ @@ -185,3 +186,10 @@ export const syncEditedMonitor = async ({ throw e; } }; + +// Ensure that METADATA is merged deeply, to protect AAD and prevent decryption errors +const customizer = (_: any, srcValue: any, key: string) => { + if (key !== ConfigKey.METADATA) { + return srcValue; + } +}; diff --git a/x-pack/plugins/synthetics/server/routes/monitor_cruds/monitor_validation.test.ts b/x-pack/plugins/synthetics/server/routes/monitor_cruds/monitor_validation.test.ts index 58855477ab8a63..8a532279dda88c 100644 --- a/x-pack/plugins/synthetics/server/routes/monitor_cruds/monitor_validation.test.ts +++ b/x-pack/plugins/synthetics/server/routes/monitor_cruds/monitor_validation.test.ts @@ -12,6 +12,7 @@ import { CommonFields, ConfigKey, DataStream, + FormMonitorType, HTTPAdvancedFields, HTTPFields, HTTPSimpleFields, @@ -75,6 +76,7 @@ describe('validateMonitor', () => { }, ], [ConfigKey.NAMESPACE]: 'testnamespace', + [ConfigKey.FORM_MONITOR_TYPE]: FormMonitorType.MULTISTEP, }; testMetaData = { is_tls_enabled: false, @@ -90,6 +92,7 @@ describe('validateMonitor', () => { [ConfigKey.HOSTS]: 'test-hosts', [ConfigKey.WAIT]: '', [ConfigKey.MONITOR_TYPE]: DataStream.ICMP, + [ConfigKey.FORM_MONITOR_TYPE]: FormMonitorType.ICMP, }; testTLSFields = { @@ -105,6 +108,7 @@ describe('validateMonitor', () => { ...testCommonFields, [ConfigKey.METADATA]: testMetaData, [ConfigKey.HOSTS]: 'https://host1.com', + [ConfigKey.FORM_MONITOR_TYPE]: FormMonitorType.TCP, }; testTCPAdvancedFields = { @@ -126,6 +130,7 @@ describe('validateMonitor', () => { [ConfigKey.METADATA]: testMetaData, [ConfigKey.MAX_REDIRECTS]: '3', [ConfigKey.URLS]: 'https://example.com', + [ConfigKey.FORM_MONITOR_TYPE]: FormMonitorType.HTTP, }; testHTTPAdvancedFields = { @@ -162,6 +167,7 @@ describe('validateMonitor', () => { testBrowserSimpleFields = { ...testZipUrlTLSFields, ...testCommonFields, + [ConfigKey.FORM_MONITOR_TYPE]: FormMonitorType.MULTISTEP, [ConfigKey.MONITOR_SOURCE_TYPE]: SourceType.PROJECT, [ConfigKey.JOURNEY_ID]: '', [ConfigKey.PROJECT_ID]: '', @@ -414,6 +420,7 @@ function getJsonPayload() { ' "response.include_body": "never",' + ' "check.response.headers": {},' + ' "response.include_headers": true,' + + ' "form_monitor_type": "http",' + ' "check.response.status": [' + ' "200",' + ' "201"' + diff --git a/x-pack/plugins/synthetics/server/synthetics_service/formatters/browser.ts b/x-pack/plugins/synthetics/server/synthetics_service/formatters/browser.ts index 18812e4f175257..7e8c75a7084306 100644 --- a/x-pack/plugins/synthetics/server/synthetics_service/formatters/browser.ts +++ b/x-pack/plugins/synthetics/server/synthetics_service/formatters/browser.ts @@ -72,5 +72,6 @@ export const browserFormatters: BrowserFormatMap = { stringToObjectFormatter(fields[ConfigKey.PLAYWRIGHT_OPTIONS] || ''), [ConfigKey.CUSTOM_HEARTBEAT_ID]: null, [ConfigKey.ORIGINAL_SPACE]: null, + [ConfigKey.TEXT_ASSERTION]: null, ...commonFormatters, }; diff --git a/x-pack/plugins/synthetics/server/synthetics_service/formatters/common.ts b/x-pack/plugins/synthetics/server/synthetics_service/formatters/common.ts index 55427c01a1f22d..0163ee52981e50 100644 --- a/x-pack/plugins/synthetics/server/synthetics_service/formatters/common.ts +++ b/x-pack/plugins/synthetics/server/synthetics_service/formatters/common.ts @@ -29,6 +29,7 @@ export const commonFormatters: CommonFormatMap = { [ConfigKey.REVISION]: null, [ConfigKey.MONITOR_SOURCE_TYPE]: (fields) => fields[ConfigKey.MONITOR_SOURCE_TYPE] || SourceType.UI, + [ConfigKey.FORM_MONITOR_TYPE]: null, }; export const arrayFormatter = (value: string[] = []) => (value.length ? value : null); diff --git a/x-pack/plugins/synthetics/server/synthetics_service/formatters/format_configs.ts b/x-pack/plugins/synthetics/server/synthetics_service/formatters/format_configs.ts index 67347e405545a8..a1c1d68c4a829f 100644 --- a/x-pack/plugins/synthetics/server/synthetics_service/formatters/format_configs.ts +++ b/x-pack/plugins/synthetics/server/synthetics_service/formatters/format_configs.ts @@ -25,6 +25,8 @@ const UI_KEYS_TO_SKIP = [ ConfigKey.IS_THROTTLING_ENABLED, ConfigKey.REVISION, ConfigKey.CUSTOM_HEARTBEAT_ID, + ConfigKey.FORM_MONITOR_TYPE, + ConfigKey.TEXT_ASSERTION, 'secrets', ]; diff --git a/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.ts b/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.ts index 2e09c5906c65b0..5f797f34515cd5 100644 --- a/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.ts +++ b/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.ts @@ -11,6 +11,7 @@ import { BrowserFields, ConfigKey, DataStream, + FormMonitorType, Locations, ProjectBrowserMonitor, ScheduleUnit, @@ -58,6 +59,7 @@ export const normalizeProjectMonitor = ({ const defaultFields = DEFAULT_FIELDS[DataStream.BROWSER]; const normalizedFields: NormalizedPublicFields = { [ConfigKey.MONITOR_TYPE]: DataStream.BROWSER, + [ConfigKey.FORM_MONITOR_TYPE]: FormMonitorType.MULTISTEP, [ConfigKey.MONITOR_SOURCE_TYPE]: SourceType.PROJECT, [ConfigKey.NAME]: monitor.name || '', [ConfigKey.SCHEDULE]: { diff --git a/x-pack/plugins/synthetics/server/synthetics_service/project_monitor_formatter.ts b/x-pack/plugins/synthetics/server/synthetics_service/project_monitor_formatter.ts index 0b582dd74c4fca..3067ee6319052b 100644 --- a/x-pack/plugins/synthetics/server/synthetics_service/project_monitor_formatter.ts +++ b/x-pack/plugins/synthetics/server/synthetics_service/project_monitor_formatter.ts @@ -341,7 +341,7 @@ export class ProjectMonitorFormatter { } catch (e) { this.handleStreamingMessage({ message: `Monitor ${journeyId} could not be deleted` }); this.failedStaleMonitors.push({ - id: monitorId, + id: journeyId, reason: 'Failed to delete stale monitor', details: e.message, }); diff --git a/x-pack/plugins/task_manager/server/monitoring/monitoring_stats_stream.ts b/x-pack/plugins/task_manager/server/monitoring/monitoring_stats_stream.ts index e0e7ddd3e79a4b..a16e01189f4c7d 100644 --- a/x-pack/plugins/task_manager/server/monitoring/monitoring_stats_stream.ts +++ b/x-pack/plugins/task_manager/server/monitoring/monitoring_stats_stream.ts @@ -7,7 +7,7 @@ import { merge, of, Observable } from 'rxjs'; import { map, scan } from 'rxjs/operators'; -import { set } from '@elastic/safer-lodash-set'; +import { set } from '@kbn/safer-lodash-set'; import { Logger } from '@kbn/core/server'; import { JsonObject } from '@kbn/utility-types'; import { TaskStore } from '../task_store'; diff --git a/x-pack/plugins/task_manager/server/task_store.test.ts b/x-pack/plugins/task_manager/server/task_store.test.ts index e7696102db8ca4..561d4ac6a0989e 100644 --- a/x-pack/plugins/task_manager/server/task_store.test.ts +++ b/x-pack/plugins/task_manager/server/task_store.test.ts @@ -15,20 +15,15 @@ import { TaskLifecycleResult, SerializedConcreteTaskInstance, } from './task'; -import { elasticsearchServiceMock } from '@kbn/core/server/mocks'; +import { elasticsearchServiceMock, savedObjectsServiceMock } from '@kbn/core/server/mocks'; import { TaskStore, SearchOpts, AggregationOpts } from './task_store'; import { savedObjectsRepositoryMock } from '@kbn/core/server/mocks'; -import { - SavedObjectsSerializer, - SavedObjectTypeRegistry, - SavedObjectAttributes, - SavedObjectsErrorHelpers, -} from '@kbn/core/server'; +import { SavedObjectAttributes, SavedObjectsErrorHelpers } from '@kbn/core/server'; import { TaskTypeDictionary } from './task_type_dictionary'; import { mockLogger } from './test_utils'; const savedObjectsClient = savedObjectsRepositoryMock.create(); -const serializer = new SavedObjectsSerializer(new SavedObjectTypeRegistry()); +const serializer = savedObjectsServiceMock.createSerializer(); beforeEach(() => jest.resetAllMocks()); diff --git a/x-pack/plugins/threat_intelligence/common/constants.ts b/x-pack/plugins/threat_intelligence/common/constants.ts index eba5c281652a95..952323223f3524 100644 --- a/x-pack/plugins/threat_intelligence/common/constants.ts +++ b/x-pack/plugins/threat_intelligence/common/constants.ts @@ -7,8 +7,6 @@ export const EMPTY_VALUE = '-'; -export const DEFAULT_THREAT_INDEX_KEY = 'securitySolution:defaultThreatIndex' as const; - export const DEFAULT_DATE_FORMAT = 'dateFormat' as const; export const DEFAULT_DATE_FORMAT_TZ = 'dateFormat:tz' as const; diff --git a/x-pack/plugins/threat_intelligence/cypress/integration/indicators/indicators.spec.ts b/x-pack/plugins/threat_intelligence/cypress/integration/indicators/indicators.spec.ts index fa17dcac2d5d49..70dbd9e9fbf618 100644 --- a/x-pack/plugins/threat_intelligence/cypress/integration/indicators/indicators.spec.ts +++ b/x-pack/plugins/threat_intelligence/cypress/integration/indicators/indicators.spec.ts @@ -23,20 +23,18 @@ import { BREADCRUMBS, LEADING_BREADCRUMB, ENDING_BREADCRUMB, + FIELD_BROWSER, + FIELD_BROWSER_MODAL, } from '../../screens/indicators'; import { login } from '../../tasks/login'; import { esArchiverLoad, esArchiverUnload } from '../../tasks/es_archiver'; +import { selectRange } from '../../tasks/select_range'; before(() => { login(); }); -/** - * Time range extended to 15 years back to ensure fixtures are showing up correctly - * TODO: https://github.com/elastic/security-team/issues/4595 - */ -const THREAT_INTELLIGENCE_15Y_DATA = - '/app/security/threat_intelligence/indicators?indicators=(filterQuery:(language:kuery,query:%27%27),filters:!(),timeRange:(from:now-15y/d,to:now))'; +const THREAT_INTELLIGENCE = '/app/security/threat_intelligence/indicators'; const URL_WITH_CONTRADICTORY_FILTERS = '/app/security/threat_intelligence/indicators?indicators=(filterQuery:(language:kuery,query:%27%27),filters:!((%27$state%27:(store:appState),meta:(alias:!n,disabled:!f,index:%27%27,key:threat.indicator.type,negate:!f,params:(query:file),type:phrase),query:(match_phrase:(threat.indicator.type:file))),(%27$state%27:(store:appState),meta:(alias:!n,disabled:!f,index:%27%27,key:threat.indicator.type,negate:!f,params:(query:url),type:phrase),query:(match_phrase:(threat.indicator.type:url)))),timeRange:(from:now/d,to:now/d))'; @@ -51,7 +49,9 @@ describe('Indicators', () => { describe('Indicators page basics', () => { before(() => { - cy.visit(THREAT_INTELLIGENCE_15Y_DATA); + cy.visit(THREAT_INTELLIGENCE); + + selectRange(); }); it('should render the basic page elements', () => { @@ -90,7 +90,9 @@ describe('Indicators', () => { describe('Indicator page search', () => { before(() => { - cy.visit(THREAT_INTELLIGENCE_15Y_DATA); + cy.visit(THREAT_INTELLIGENCE); + + selectRange(); }); it('should narrow the results to url indicators when respective KQL search is executed', () => { @@ -121,10 +123,12 @@ describe('Indicators', () => { }); describe('No items match search criteria', () => { - before(() => + before(() => { // Contradictory filter set - cy.visit(URL_WITH_CONTRADICTORY_FILTERS) - ); + cy.visit(URL_WITH_CONTRADICTORY_FILTERS); + + selectRange(); + }); it('should not display the table when contractictory filters are set', () => { cy.get(FLYOUT_TABLE).should('not.exist'); @@ -147,4 +151,20 @@ describe('Indicators', () => { cy.get(`${FIELD_SELECTOR}`).should('have.value', threatIndicatorIp); }); }); + + describe('Field browser', () => { + before(() => { + cy.visit(THREAT_INTELLIGENCE); + + selectRange(); + }); + + describe('when field browser is triggered', () => { + it('should render proper modal window', () => { + cy.get(FIELD_BROWSER).last().click({ force: true }); + + cy.get(FIELD_BROWSER_MODAL).should('be.visible'); + }); + }); + }); }); diff --git a/x-pack/plugins/threat_intelligence/cypress/screens/indicators.ts b/x-pack/plugins/threat_intelligence/cypress/screens/indicators.ts index 3c68050c58f8c8..f5ab5f46f687d8 100644 --- a/x-pack/plugins/threat_intelligence/cypress/screens/indicators.ts +++ b/x-pack/plugins/threat_intelligence/cypress/screens/indicators.ts @@ -38,3 +38,11 @@ export const TABLE_CONTROLS = '[data-test-sub="dataGridControls"]'; export const INDICATOR_TYPE_CELL = '[data-gridcell-column-id="threat.indicator.type"]'; export const FIELD_SELECTOR = '[data-test-subj="tiIndicatorFieldSelectorDropdown"]'; + +export const FIELD_BROWSER = `[data-test-subj="show-field-browser"]`; + +export const FIELD_BROWSER_MODAL = `[data-test-subj="fields-browser-container"]`; + +export const FIELD_BROWSER_MODAL_SOURCE_CHECKBOX = `[data-test-subj="field-_source-checkbox"]`; + +export const FIELD_BROWSER_CLOSE = `[data-test-subj="close"]`; diff --git a/x-pack/plugins/threat_intelligence/cypress/tasks/select_range.ts b/x-pack/plugins/threat_intelligence/cypress/tasks/select_range.ts new file mode 100644 index 00000000000000..8bf94c7f920ee2 --- /dev/null +++ b/x-pack/plugins/threat_intelligence/cypress/tasks/select_range.ts @@ -0,0 +1,18 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { FIELD_BROWSER, TIME_RANGE_PICKER } from '../screens/indicators'; + +export const selectRange = () => { + cy.get(FIELD_BROWSER); + + cy.get(TIME_RANGE_PICKER).first().click({ force: true }); + cy.get('[aria-label="Time unit"]').select('y'); + cy.get('[data-test-subj="superDatePickerQuickMenu"] .euiQuickSelect__applyButton').click({ + force: true, + }); +}; diff --git a/x-pack/plugins/threat_intelligence/kibana.json b/x-pack/plugins/threat_intelligence/kibana.json index 18493feca7c4f1..efd1e8bce761ee 100644 --- a/x-pack/plugins/threat_intelligence/kibana.json +++ b/x-pack/plugins/threat_intelligence/kibana.json @@ -3,6 +3,7 @@ "version": "1.0.0", "kibanaVersion": "kibana", "ui": true, + "server": false, "owner": { "name": "Protections Experience Team", "githubTeam": "protections-experience" @@ -14,7 +15,8 @@ "unifiedSearch", "kibanaUtils", "navigation", - "kibanaReact" + "kibanaReact", + "triggersActionsUi" ], "requiredBundles": [ "data", diff --git a/x-pack/plugins/threat_intelligence/public/common/mocks/mock_kibana_data_service.tsx b/x-pack/plugins/threat_intelligence/public/common/mocks/mock_kibana_data_service.tsx deleted file mode 100644 index c002343369988b..00000000000000 --- a/x-pack/plugins/threat_intelligence/public/common/mocks/mock_kibana_data_service.tsx +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { Observable } from 'rxjs'; -import { TimeRangeBounds } from '@kbn/data-plugin/common'; -import * as hook from '../../hooks/use_kibana'; - -export interface MockSearchServiceParams { - searchSubject?: Observable; - calculateSubject?: TimeRangeBounds; -} - -export const mockKibanaDataService = ({ - searchSubject, - calculateSubject, -}: MockSearchServiceParams) => { - const search = jest.fn().mockReturnValue(searchSubject); - const showError = jest.fn(); - const getUiSetting = jest.fn(); - const calculateBounds = jest.fn().mockReturnValue(calculateSubject); - - (hook as jest.Mocked).useKibana.mockReturnValue({ - services: { - data: { - search: { search, showError }, - query: { timefilter: { timefilter: { calculateBounds } } }, - }, - uiSettings: { get: getUiSetting }, - }, - } as any); - - return { - search, - showError, - getUiSetting, - calculateBounds, - }; -}; diff --git a/x-pack/plugins/threat_intelligence/public/common/mocks/mock_security_context.tsx b/x-pack/plugins/threat_intelligence/public/common/mocks/mock_security_context.tsx new file mode 100644 index 00000000000000..666fc6318c5775 --- /dev/null +++ b/x-pack/plugins/threat_intelligence/public/common/mocks/mock_security_context.tsx @@ -0,0 +1,26 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { SecuritySolutionPluginContext } from '../..'; + +export const getSecuritySolutionContextMock = (): SecuritySolutionPluginContext => ({ + getFiltersGlobalComponent: + () => + ({ children }) => +
{children}
, + licenseService: { + isEnterprise() { + return true; + }, + }, + sourcererDataView: { + browserFields: {}, + selectedPatterns: [], + indexPattern: { fields: [], title: '' }, + }, +}); diff --git a/x-pack/plugins/threat_intelligence/public/common/mocks/mock_use_kibana_for_filters.ts b/x-pack/plugins/threat_intelligence/public/common/mocks/mock_use_kibana_for_filters.ts index cb77e0cec55238..598bec07732a07 100644 --- a/x-pack/plugins/threat_intelligence/public/common/mocks/mock_use_kibana_for_filters.ts +++ b/x-pack/plugins/threat_intelligence/public/common/mocks/mock_use_kibana_for_filters.ts @@ -42,7 +42,6 @@ export const mockUseKibanaForFilters = ({ }, }, dataViews: { getFieldsForWildcard }, - uiSettings: { get: () => ['mock-index'] }, }, } as any); diff --git a/x-pack/plugins/threat_intelligence/public/common/mocks/story_providers.tsx b/x-pack/plugins/threat_intelligence/public/common/mocks/story_providers.tsx new file mode 100644 index 00000000000000..752e93b756ddbf --- /dev/null +++ b/x-pack/plugins/threat_intelligence/public/common/mocks/story_providers.tsx @@ -0,0 +1,53 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { ReactNode, VFC } from 'react'; +import { createKibanaReactContext } from '@kbn/kibana-react-plugin/public'; +import { DataPublicPluginStart } from '@kbn/data-plugin/public'; +import { CoreStart, IUiSettingsClient } from '@kbn/core/public'; +import { SecuritySolutionContext } from '../../containers/security_solution_context'; +import { getSecuritySolutionContextMock } from './mock_security_context'; + +export interface KibanaContextMock { + /** + * For the data plugin (see {@link DataPublicPluginStart}) + */ + data?: DataPublicPluginStart; + /** + * For the core ui-settings package (see {@link IUiSettingsClient}) + */ + uiSettings?: IUiSettingsClient; +} + +export interface StoryProvidersComponentProps { + /** + * Used to generate a new KibanaReactContext (using {@link createKibanaReactContext}) + */ + kibana: KibanaContextMock; + /** + * Component(s) to be displayed inside + */ + children: ReactNode; +} + +/** + * Helper functional component used in Storybook stories. + * Wraps the story with our {@link SecuritySolutionContext} and KibanaReactContext. + */ +export const StoryProvidersComponent: VFC = ({ + children, + kibana, +}) => { + const KibanaReactContext = createKibanaReactContext(kibana as CoreStart); + const securitySolutionContextMock = getSecuritySolutionContextMock(); + + return ( + + {children} + + ); +}; diff --git a/x-pack/plugins/threat_intelligence/public/common/mocks/test_providers.tsx b/x-pack/plugins/threat_intelligence/public/common/mocks/test_providers.tsx index 019587c4b30fb3..a2c0318c482aaf 100644 --- a/x-pack/plugins/threat_intelligence/public/common/mocks/test_providers.tsx +++ b/x-pack/plugins/threat_intelligence/public/common/mocks/test_providers.tsx @@ -13,9 +13,11 @@ import { dataPluginMock } from '@kbn/data-plugin/public/mocks'; import type { IStorage } from '@kbn/kibana-utils-plugin/public'; import { Storage } from '@kbn/kibana-utils-plugin/public'; import { unifiedSearchPluginMock } from '@kbn/unified-search-plugin/public/mocks'; +import { BehaviorSubject } from 'rxjs'; +import { getSecuritySolutionContextMock } from './mock_security_context'; import { mockUiSetting } from './mock_kibana_ui_setting'; -import { KibanaContextProvider } from '../../hooks/use_kibana'; -import { Services, ThreatIntelligenceSecuritySolutionContext } from '../../types'; +import { KibanaContext } from '../../hooks/use_kibana'; +import { SecuritySolutionPluginContext } from '../../types'; import { SecuritySolutionContext } from '../../containers/security_solution_context'; export const localStorageMock = (): IStorage => { @@ -51,6 +53,7 @@ export const unifiedSearch = unifiedSearchPluginMock.createStartContract(); const validDate: string = '1 Jan 2022 00:00:00 GMT'; const data = dataPluginMock.createStartContract(); + const dataServiceMock = { ...data, query: { @@ -83,20 +86,7 @@ const dataServiceMock = { }, search: { ...data.search, - search: jest.fn().mockImplementation(() => ({ - subscribe: jest.fn().mockImplementation(() => ({ - error: jest.fn(), - next: jest.fn(), - unsubscribe: jest.fn(), - })), - pipe: jest.fn().mockImplementation(() => ({ - subscribe: jest.fn().mockImplementation(() => ({ - error: jest.fn(), - next: jest.fn(), - unsubscribe: jest.fn(), - })), - })), - })), + search: jest.fn().mockReturnValue(new BehaviorSubject({})), }, }; @@ -106,29 +96,31 @@ const coreServiceMock = { uiSettings: { get: jest.fn().mockImplementation(mockUiSetting) }, }; -const mockSecurityContext: ThreatIntelligenceSecuritySolutionContext = { - getFiltersGlobalComponent: - () => - ({ children }) => -
{children}
, - licenseService: { - isEnterprise() { - return true; - }, - }, -}; +const mockSecurityContext: SecuritySolutionPluginContext = getSecuritySolutionContextMock(); -const mockedServices = { +export const mockedServices = { ...coreServiceMock, data: dataServiceMock, storage, unifiedSearch, -} as unknown as Services; + triggersActionsUi: { + getFieldBrowser: jest.fn().mockReturnValue(null), + }, +}; export const TestProvidersComponent: FC = ({ children }) => ( - + {children} - + ); + +export type MockedSearch = jest.Mocked; +export type MockedTimefilter = jest.Mocked; +export type MockedTriggersActionsUi = jest.Mocked; + +export const mockedSearchService = mockedServices.data.search as MockedSearch; +export const mockedTimefilterService = mockedServices.data.query.timefilter as MockedTimefilter; +export const mockedTriggersActionsUiService = + mockedServices.triggersActionsUi as MockedTriggersActionsUi; diff --git a/x-pack/plugins/threat_intelligence/public/components/paywall/index.tsx b/x-pack/plugins/threat_intelligence/public/components/paywall/index.tsx new file mode 100644 index 00000000000000..46d2df81a1c8cb --- /dev/null +++ b/x-pack/plugins/threat_intelligence/public/components/paywall/index.tsx @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export * from './paywall'; diff --git a/x-pack/plugins/threat_intelligence/public/components/paywall/paywall.stories.tsx b/x-pack/plugins/threat_intelligence/public/components/paywall/paywall.stories.tsx new file mode 100644 index 00000000000000..14de7d5b907fba --- /dev/null +++ b/x-pack/plugins/threat_intelligence/public/components/paywall/paywall.stories.tsx @@ -0,0 +1,18 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { Paywall } from './paywall'; + +export default { + component: BasicPaywall, + title: 'Paywall', +}; + +export function BasicPaywall() { + return ; +} diff --git a/x-pack/plugins/threat_intelligence/public/components/paywall/paywall.tsx b/x-pack/plugins/threat_intelligence/public/components/paywall/paywall.tsx new file mode 100644 index 00000000000000..8f095a2fd9baab --- /dev/null +++ b/x-pack/plugins/threat_intelligence/public/components/paywall/paywall.tsx @@ -0,0 +1,74 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { VFC } from 'react'; +import { + EuiButton, + EuiButtonEmpty, + EuiEmptyPrompt, + EuiFlexGroup, + EuiFlexItem, + EuiIcon, +} from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n-react'; + +interface PaywallProps { + /** + * Can be obtained using `http.basePath.prepend('/app/management/stack/license_management')` + */ + licenseManagementHref: string; +} + +export const Paywall: VFC = ({ licenseManagementHref }) => { + return ( + } + color="subdued" + data-test-subj="tiPaywall" + title={ +

+ +

+ } + body={ +

+ +

+ } + actions={ + + +
+ + + +
+
+ +
+ + + +
+
+
+ } + /> + ); +}; diff --git a/x-pack/plugins/threat_intelligence/public/containers/enterprise_guard/enterprise_guard.test.tsx b/x-pack/plugins/threat_intelligence/public/containers/enterprise_guard/enterprise_guard.test.tsx index bb4739bb6251f6..a01c3b94e1cd41 100644 --- a/x-pack/plugins/threat_intelligence/public/containers/enterprise_guard/enterprise_guard.test.tsx +++ b/x-pack/plugins/threat_intelligence/public/containers/enterprise_guard/enterprise_guard.test.tsx @@ -7,7 +7,8 @@ import { render, screen } from '@testing-library/react'; import React from 'react'; -import { ThreatIntelligenceSecuritySolutionContext } from '../../types'; +import { TestProvidersComponent } from '../../common/mocks/test_providers'; +import { SecuritySolutionPluginContext } from '../../types'; import { SecuritySolutionContext } from '../security_solution_context'; import { EnterpriseGuard } from './enterprise_guard'; @@ -15,17 +16,19 @@ describe('', () => { describe('when on enterprise plan', () => { it('should render specified children', () => { render( - - -
enterprise only content
-
-
+ + + +
enterprise only content
+
+
+
); expect(screen.queryByText('enterprise only content')).toBeInTheDocument(); @@ -35,21 +38,23 @@ describe('', () => { describe('when not on enterprise plan', () => { it('should render specified children', () => { render( - - fallback for non enterprise
}> -
enterprise only content
- - + + + +
enterprise only content
+
+
+
); expect(screen.queryByText('enterprise only content')).not.toBeInTheDocument(); - expect(screen.queryByText('fallback for non enterprise')).toBeInTheDocument(); + expect(screen.queryByTestId('tiPaywall')).toBeInTheDocument(); }); }); }); diff --git a/x-pack/plugins/threat_intelligence/public/containers/enterprise_guard/enterprise_guard.tsx b/x-pack/plugins/threat_intelligence/public/containers/enterprise_guard/enterprise_guard.tsx index 67351c1e3d149f..06ca98973af093 100644 --- a/x-pack/plugins/threat_intelligence/public/containers/enterprise_guard/enterprise_guard.tsx +++ b/x-pack/plugins/threat_intelligence/public/containers/enterprise_guard/enterprise_guard.tsx @@ -5,20 +5,25 @@ * 2.0. */ -import React, { ReactElement } from 'react'; +import React from 'react'; import { FC } from 'react'; +import { Paywall } from '../../components/paywall'; +import { useKibana } from '../../hooks/use_kibana'; import { useSecurityContext } from '../../hooks/use_security_context'; -interface EnterpriseGuardProps { - fallback?: ReactElement; -} - -export const EnterpriseGuard: FC = ({ children, fallback = null }) => { +export const EnterpriseGuard: FC = ({ children }) => { const { licenseService } = useSecurityContext(); + const { + services: { http }, + } = useKibana(); if (licenseService.isEnterprise()) { return <>{children}; } - return fallback; + return ( + + ); }; diff --git a/x-pack/plugins/threat_intelligence/public/containers/security_solution_context.tsx b/x-pack/plugins/threat_intelligence/public/containers/security_solution_context.tsx index 0dae7e9538c38a..91a2934463d07c 100644 --- a/x-pack/plugins/threat_intelligence/public/containers/security_solution_context.tsx +++ b/x-pack/plugins/threat_intelligence/public/containers/security_solution_context.tsx @@ -6,8 +6,8 @@ */ import { createContext } from 'react'; -import { ThreatIntelligenceSecuritySolutionContext } from '../types'; +import { SecuritySolutionPluginContext } from '../types'; -export const SecuritySolutionContext = createContext< - ThreatIntelligenceSecuritySolutionContext | undefined ->(undefined); +export const SecuritySolutionContext = createContext( + undefined +); diff --git a/x-pack/plugins/threat_intelligence/public/hooks/use_kibana.ts b/x-pack/plugins/threat_intelligence/public/hooks/use_kibana.ts index 28e15734e6dcc4..a6431c3c40a8f5 100644 --- a/x-pack/plugins/threat_intelligence/public/hooks/use_kibana.ts +++ b/x-pack/plugins/threat_intelligence/public/hooks/use_kibana.ts @@ -5,9 +5,13 @@ * 2.0. */ -import { KibanaContextProvider, useKibana } from '@kbn/kibana-react-plugin/public'; +import { + KibanaContextProvider, + useKibana, + context as KibanaContext, +} from '@kbn/kibana-react-plugin/public'; import { Services } from '../types'; const useTypedKibana = () => useKibana(); -export { KibanaContextProvider, useTypedKibana as useKibana }; +export { KibanaContextProvider, useTypedKibana as useKibana, KibanaContext }; diff --git a/x-pack/plugins/threat_intelligence/public/hooks/use_security_context.ts b/x-pack/plugins/threat_intelligence/public/hooks/use_security_context.ts index 433f12bf548c0c..4d5fad34baf09c 100644 --- a/x-pack/plugins/threat_intelligence/public/hooks/use_security_context.ts +++ b/x-pack/plugins/threat_intelligence/public/hooks/use_security_context.ts @@ -7,9 +7,9 @@ import { useContext } from 'react'; import { SecuritySolutionContext } from '../containers/security_solution_context'; -import { ThreatIntelligenceSecuritySolutionContext } from '../types'; +import { SecuritySolutionPluginContext } from '../types'; -export const useSecurityContext = (): ThreatIntelligenceSecuritySolutionContext => { +export const useSecurityContext = (): SecuritySolutionPluginContext => { const contextValue = useContext(SecuritySolutionContext); if (!contextValue) { diff --git a/x-pack/plugins/threat_intelligence/public/index.ts b/x-pack/plugins/threat_intelligence/public/index.ts index 3751d0d0f70037..539b8074263415 100755 --- a/x-pack/plugins/threat_intelligence/public/index.ts +++ b/x-pack/plugins/threat_intelligence/public/index.ts @@ -24,5 +24,5 @@ export function plugin() { export type { ThreatIntelligencePluginSetup, ThreatIntelligencePluginStart, - ThreatIntelligenceSecuritySolutionContext, + SecuritySolutionPluginContext, } from './types'; diff --git a/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_barchart_wrapper/indicators_barchart_wrapper.stories.tsx b/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_barchart_wrapper/indicators_barchart_wrapper.stories.tsx index cda6671d03fda4..478b2ec398b979 100644 --- a/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_barchart_wrapper/indicators_barchart_wrapper.stories.tsx +++ b/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_barchart_wrapper/indicators_barchart_wrapper.stories.tsx @@ -7,12 +7,14 @@ import moment from 'moment'; import React from 'react'; +import { MemoryRouter } from 'react-router-dom'; import { of } from 'rxjs'; import { Story } from '@storybook/react'; import { DataView, DataViewField } from '@kbn/data-views-plugin/common'; -import { createKibanaReactContext } from '@kbn/kibana-react-plugin/public'; -import { CoreStart } from '@kbn/core/public'; import { TimeRange } from '@kbn/es-query'; +import { DataPublicPluginStart } from '@kbn/data-plugin/public'; +import { IUiSettingsClient } from '@kbn/core/public'; +import { StoryProvidersComponent } from '../../../../common/mocks/story_providers'; import { Aggregation, AGGREGATION_NAME } from '../../hooks/use_aggregated_indicators'; import { DEFAULT_TIME_RANGE } from '../../hooks/use_filters/utils'; import { IndicatorsBarChartWrapper } from './indicators_barchart_wrapper'; @@ -23,20 +25,18 @@ export default { }; const mockTimeRange: TimeRange = DEFAULT_TIME_RANGE; -const mockIndexPatterns: DataView[] = [ - { - fields: [ - { - name: '@timestamp', - type: 'date', - } as DataViewField, - { - name: 'threat.feed.name', - type: 'string', - } as DataViewField, - ], - } as DataView, -]; +const mockIndexPattern: DataView = { + fields: [ + { + name: '@timestamp', + type: 'date', + } as DataViewField, + { + name: 'threat.feed.name', + type: 'string', + } as DataViewField, + ], +} as DataView; const validDate: string = '1 Jan 2022 00:00:00 GMT'; const numberOfDays: number = 1; @@ -76,38 +76,43 @@ const aggregation2: Aggregation = { doc_count: 0, key: '[Filebeat] AbuseCH MalwareBazaar', }; -const KibanaReactContext = createKibanaReactContext({ - data: { - search: { - search: () => - of({ - rawResponse: { - aggregations: { - [AGGREGATION_NAME]: { - buckets: [aggregation1, aggregation2], - }, +const mockData = { + search: { + search: () => + of({ + rawResponse: { + aggregations: { + [AGGREGATION_NAME]: { + buckets: [aggregation1, aggregation2], }, }, - }), - }, - query: { - timefilter: { - timefilter: { - calculateBounds: () => ({ - min: moment(validDate), - max: moment(validDate).add(numberOfDays, 'days'), - }), }, + }), + }, + query: { + timefilter: { + timefilter: { + calculateBounds: () => ({ + min: moment(validDate), + max: moment(validDate).add(numberOfDays, 'days'), + }), }, }, + filterManager: { + getFilters: () => {}, + setFilters: () => {}, + getUpdates$: () => of(), + }, }, - uiSettings: { get: () => {} }, -} as unknown as Partial); +} as unknown as DataPublicPluginStart; + +const mockUiSettings = { get: () => {} } as unknown as IUiSettingsClient; export const Default: Story = () => { return ( - - - + + + ); }; +Default.decorators = [(story) => {story()}]; diff --git a/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_barchart_wrapper/indicators_barchart_wrapper.test.tsx b/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_barchart_wrapper/indicators_barchart_wrapper.test.tsx index 39afea8a11a0e2..9deeb4e5bcb8ad 100644 --- a/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_barchart_wrapper/indicators_barchart_wrapper.test.tsx +++ b/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_barchart_wrapper/indicators_barchart_wrapper.test.tsx @@ -12,28 +12,42 @@ import { DataView, DataViewField } from '@kbn/data-views-plugin/common'; import { TestProvidersComponent } from '../../../../common/mocks/test_providers'; import { IndicatorsBarChartWrapper } from './indicators_barchart_wrapper'; import { DEFAULT_TIME_RANGE } from '../../hooks/use_filters/utils'; +import { useFilters } from '../../hooks/use_filters'; + +jest.mock('../../hooks/use_filters'); + +const mockIndexPattern: DataView = { + fields: [ + { + name: '@timestamp', + type: 'date', + } as DataViewField, + { + name: 'threat.feed.name', + type: 'string', + } as DataViewField, + ], +} as DataView; -const mockIndexPatterns: DataView[] = [ - { - fields: [ - { - name: '@timestamp', - type: 'date', - } as DataViewField, - { - name: 'threat.feed.name', - type: 'string', - } as DataViewField, - ], - } as DataView, -]; const mockTimeRange: TimeRange = DEFAULT_TIME_RANGE; +const stub = () => {}; + describe('', () => { + beforeEach(() => { + (useFilters as jest.MockedFunction).mockReturnValue({ + filters: [], + filterQuery: { language: 'kuery', query: '' }, + filterManager: {} as any, + handleSavedQuery: stub, + handleSubmitQuery: stub, + handleSubmitTimeRange: stub, + }); + }); it('should render barchart and field selector dropdown', () => { const component = render( - + ); diff --git a/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_barchart_wrapper/indicators_barchart_wrapper.tsx b/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_barchart_wrapper/indicators_barchart_wrapper.tsx index 0988e50dc0007e..a30bdffe0e23c9 100644 --- a/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_barchart_wrapper/indicators_barchart_wrapper.tsx +++ b/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_barchart_wrapper/indicators_barchart_wrapper.tsx @@ -8,8 +8,8 @@ import React, { memo } from 'react'; import { EuiFlexGroup, EuiFlexItem, EuiTitle } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; -import { DataView } from '@kbn/data-views-plugin/common'; import { TimeRange } from '@kbn/es-query'; +import { SecuritySolutionDataViewBase } from '../../../../types'; import { RawIndicatorFieldId } from '../../../../../common/types/indicator'; import { useAggregatedIndicators } from '../../hooks/use_aggregated_indicators'; import { IndicatorsFieldSelector } from '../indicators_field_selector/indicators_field_selector'; @@ -19,11 +19,11 @@ const DEFAULT_FIELD = RawIndicatorFieldId.Feed; export interface IndicatorsBarChartWrapperProps { timeRange?: TimeRange; - indexPatterns: DataView[]; + indexPattern: SecuritySolutionDataViewBase; } export const IndicatorsBarChartWrapper = memo( - ({ timeRange, indexPatterns }) => { + ({ timeRange, indexPattern }) => { const { dateRange, indicators, onFieldChange } = useAggregatedIndicators({ timeRange }); return ( @@ -41,7 +41,7 @@ export const IndicatorsBarChartWrapper = memo( diff --git a/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_field_browser/index.tsx b/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_field_browser/index.tsx new file mode 100644 index 00000000000000..8fefebf88e799a --- /dev/null +++ b/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_field_browser/index.tsx @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export * from './indicators_field_browser'; diff --git a/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_field_browser/indicators_field_browser.test.tsx b/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_field_browser/indicators_field_browser.test.tsx new file mode 100644 index 00000000000000..29e97062cf22d2 --- /dev/null +++ b/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_field_browser/indicators_field_browser.test.tsx @@ -0,0 +1,43 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { + mockedTriggersActionsUiService, + TestProvidersComponent, +} from '../../../../common/mocks/test_providers'; +import { render } from '@testing-library/react'; +import React from 'react'; +import { IndicatorsFieldBrowser } from './indicators_field_browser'; + +const stub = jest.fn(); + +describe('', () => { + it('should retrieve the field browser widget from respective service', () => { + render( + , + { + wrapper: TestProvidersComponent, + } + ); + + expect(mockedTriggersActionsUiService.getFieldBrowser).toHaveBeenCalledTimes(1); + expect(mockedTriggersActionsUiService.getFieldBrowser).toHaveBeenCalledWith( + expect.objectContaining({ + browserFields: {}, + columnIds: [], + onResetColumns: stub, + onToggleColumn: stub, + options: {}, + }) + ); + }); +}); diff --git a/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_field_browser/indicators_field_browser.tsx b/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_field_browser/indicators_field_browser.tsx new file mode 100644 index 00000000000000..2adcc4ee5b9ee9 --- /dev/null +++ b/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_field_browser/indicators_field_browser.tsx @@ -0,0 +1,34 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { BrowserField } from '@kbn/triggers-actions-ui-plugin/public/application/sections/field_browser/types'; +import { VFC } from 'react'; +import { useKibana } from '../../../../hooks/use_kibana'; + +export interface IndicatorsFieldBrowserProps { + browserFields: Readonly>>; + columnIds: string[]; + onResetColumns: () => void; + onToggleColumn: (columnId: string) => void; +} + +export const IndicatorsFieldBrowser: VFC = ({ + browserFields, + columnIds, + onResetColumns, + onToggleColumn, +}) => { + const { triggersActionsUi } = useKibana().services; + + return triggersActionsUi.getFieldBrowser({ + browserFields, + columnIds, + onResetColumns, + onToggleColumn, + options: {}, + }); +}; diff --git a/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_field_selector/indicators_field_selector.stories.tsx b/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_field_selector/indicators_field_selector.stories.tsx index f7bb3300334a53..94ca9f903aec6f 100644 --- a/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_field_selector/indicators_field_selector.stories.tsx +++ b/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_field_selector/indicators_field_selector.stories.tsx @@ -11,20 +11,18 @@ import { DataView, DataViewField } from '@kbn/data-views-plugin/common'; import { RawIndicatorFieldId } from '../../../../../common/types/indicator'; import { IndicatorsFieldSelector } from './indicators_field_selector'; -const mockIndexPatterns: DataView[] = [ - { - fields: [ - { - name: '@timestamp', - type: 'date', - } as DataViewField, - { - name: 'threat.feed.name', - type: 'string', - } as DataViewField, - ], - } as DataView, -]; +const mockIndexPattern: DataView = { + fields: [ + { + name: '@timestamp', + type: 'date', + } as DataViewField, + { + name: 'threat.feed.name', + type: 'string', + } as DataViewField, + ], +} as DataView; export default { component: IndicatorsFieldSelector, @@ -34,7 +32,7 @@ export default { export const Default: Story = () => { return ( console.log(value)} /> @@ -44,7 +42,7 @@ export const Default: Story = () => { export const WithDefaultValue: Story = () => { return ( console.log(value)} defaultStackByValue={RawIndicatorFieldId.LastSeen} @@ -55,7 +53,7 @@ export const WithDefaultValue: Story = () => { export const NoData: Story = () => { return ( console.log(value)} /> diff --git a/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_field_selector/indicators_field_selector.test.tsx b/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_field_selector/indicators_field_selector.test.tsx index 21a0f56dfb36af..e3bd4129d4fc56 100644 --- a/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_field_selector/indicators_field_selector.test.tsx +++ b/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_field_selector/indicators_field_selector.test.tsx @@ -11,27 +11,25 @@ import { DataView, DataViewField } from '@kbn/data-views-plugin/common'; import { TestProvidersComponent } from '../../../../common/mocks/test_providers'; import { DROPDOWN_TEST_ID, IndicatorsFieldSelector } from './indicators_field_selector'; -const mockIndexPatterns: DataView[] = [ - { - fields: [ - { - name: '@timestamp', - type: 'date', - } as DataViewField, - { - name: 'threat.feed.name', - type: 'string', - } as DataViewField, - ], - } as DataView, -]; +const mockIndexPattern: DataView = { + fields: [ + { + name: '@timestamp', + type: 'date', + } as DataViewField, + { + name: 'threat.feed.name', + type: 'string', + } as DataViewField, + ], +} as DataView; describe('', () => { it('should handle empty array of indexPatterns', () => { const component = render( console.log(value)} /> @@ -45,7 +43,7 @@ describe('', () => { const component = render( console.log(value)} /> @@ -56,7 +54,7 @@ describe('', () => { const dropdownOptions: string = component.getByTestId(DROPDOWN_TEST_ID).innerHTML; const optionsCount: number = (dropdownOptions.match(/
{/* NOTE: canvasWorkpadContainer is used for exporting */}
({ - deselectElement: (ev) => { - ev.stopPropagation(); - dispatch(selectToplevelNodes([])); - }, -}); - -export const WorkpadApp = connect( - (state: State) => ({ - isWriteable: isWriteable(state) && canUserWrite(state), - workpad: getWorkpad(state), - }), - mapDispatchToProps -)(WorkpadAppComponent); +export const WorkpadApp = connect((state: State) => ({ + isWriteable: isWriteable(state) && canUserWrite(state), + workpad: getWorkpad(state), +}))(WorkpadAppComponent); diff --git a/x-pack/plugins/canvas/public/components/workpad_color_picker/workpad_color_picker.component.tsx b/x-pack/plugins/canvas/public/components/workpad_color_picker/workpad_color_picker.component.tsx index 0561ac005519b0..c14e54d8e85495 100644 --- a/x-pack/plugins/canvas/public/components/workpad_color_picker/workpad_color_picker.component.tsx +++ b/x-pack/plugins/canvas/public/components/workpad_color_picker/workpad_color_picker.component.tsx @@ -5,8 +5,11 @@ * 2.0. */ -import React from 'react'; +import React, { useCallback } from 'react'; +import { useDispatch, useSelector } from 'react-redux'; import { i18n } from '@kbn/i18n'; +import { addColor, removeColor } from '../../state/actions/workpad'; +import { getWorkpadColors } from '../../state/selectors/workpad'; import { ColorPickerPopover, Props } from '../color_picker_popover'; const strings = { @@ -17,9 +20,17 @@ const strings = { }; export const WorkpadColorPicker = (props: Props) => { + const dispatch = useDispatch(); + const onAddColor = useCallback((payload) => dispatch(addColor(payload)), [dispatch]); + const onRemoveColor = useCallback((payload) => dispatch(removeColor(payload)), [dispatch]); + const colors = useSelector(getWorkpadColors); + return ( diff --git a/x-pack/plugins/canvas/public/components/workpad_color_picker/workpad_color_picker.ts b/x-pack/plugins/canvas/public/components/workpad_color_picker/workpad_color_picker.ts index 140de2b73ddf01..fe029c88c8cf1b 100644 --- a/x-pack/plugins/canvas/public/components/workpad_color_picker/workpad_color_picker.ts +++ b/x-pack/plugins/canvas/public/components/workpad_color_picker/workpad_color_picker.ts @@ -5,20 +5,4 @@ * 2.0. */ -import { connect } from 'react-redux'; -import { addColor, removeColor } from '../../state/actions/workpad'; -import { getWorkpadColors } from '../../state/selectors/workpad'; - -import { WorkpadColorPicker as Component } from './workpad_color_picker.component'; -import { State } from '../../../types'; - -const mapStateToProps = (state: State) => ({ - colors: getWorkpadColors(state), -}); - -const mapDispatchToProps = { - onAddColor: addColor, - onRemoveColor: removeColor, -}; - -export const WorkpadColorPicker = connect(mapStateToProps, mapDispatchToProps)(Component); +export { WorkpadColorPicker } from './workpad_color_picker.component'; diff --git a/x-pack/plugins/canvas/public/components/workpad_header/refresh_control/refresh_control.component.tsx b/x-pack/plugins/canvas/public/components/workpad_header/refresh_control/refresh_control.component.tsx index 7b1df158087b40..ce93c370aa0f64 100644 --- a/x-pack/plugins/canvas/public/components/workpad_header/refresh_control/refresh_control.component.tsx +++ b/x-pack/plugins/canvas/public/components/workpad_header/refresh_control/refresh_control.component.tsx @@ -5,11 +5,15 @@ * 2.0. */ -import React, { MouseEventHandler } from 'react'; +import React, { useCallback } from 'react'; import PropTypes from 'prop-types'; import { EuiButtonIcon, EuiToolTip } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; +import { useDispatch, useSelector } from 'react-redux'; +// @ts-expect-error untyped local +import { fetchAllRenderables } from '../../../state/actions/elements'; +import { getInFlight } from '../../../state/selectors/resolved_args'; import { ToolTipShortcut } from '../../tool_tip_shortcut'; const strings = { @@ -23,30 +27,31 @@ const strings = { }), }; -export interface Props { - doRefresh: MouseEventHandler; - inFlight: boolean; -} +export const RefreshControl = () => { + const dispatch = useDispatch(); + const inFlight = useSelector(getInFlight); + const doRefresh = useCallback(() => dispatch(fetchAllRenderables()), [dispatch]); -export const RefreshControl = ({ doRefresh, inFlight }: Props) => ( - - {strings.getRefreshTooltip()} - - - } - > - - -); + return ( + + {strings.getRefreshTooltip()} + + + } + > + + + ); +}; RefreshControl.propTypes = { doRefresh: PropTypes.func.isRequired, diff --git a/x-pack/plugins/canvas/public/components/workpad_header/refresh_control/refresh_control.ts b/x-pack/plugins/canvas/public/components/workpad_header/refresh_control/refresh_control.ts index c9182eea7ff4d2..ef620ee897dc36 100644 --- a/x-pack/plugins/canvas/public/components/workpad_header/refresh_control/refresh_control.ts +++ b/x-pack/plugins/canvas/public/components/workpad_header/refresh_control/refresh_control.ts @@ -5,19 +5,4 @@ * 2.0. */ -import { connect } from 'react-redux'; -// @ts-expect-error untyped local -import { fetchAllRenderables } from '../../../state/actions/elements'; -import { getInFlight } from '../../../state/selectors/resolved_args'; -import { State } from '../../../../types'; -import { RefreshControl as Component } from './refresh_control.component'; - -const mapStateToProps = (state: State) => ({ - inFlight: getInFlight(state), -}); - -const mapDispatchToProps = { - doRefresh: fetchAllRenderables, -}; - -export const RefreshControl = connect(mapStateToProps, mapDispatchToProps)(Component); +export { RefreshControl } from './refresh_control.component'; diff --git a/x-pack/plugins/canvas/public/components/workpad_page/workpad_interactive_page/event_handlers.ts b/x-pack/plugins/canvas/public/components/workpad_page/workpad_interactive_page/event_handlers.ts index e8527089c9ac42..bb06444c0c8f61 100644 --- a/x-pack/plugins/canvas/public/components/workpad_page/workpad_interactive_page/event_handlers.ts +++ b/x-pack/plugins/canvas/public/components/workpad_page/workpad_interactive_page/event_handlers.ts @@ -76,7 +76,6 @@ const setupHandler = (commit: CommitFn, canvasOrigin: CanvasOriginFn, zoomScale? return; } - e.stopPropagation(); const { x, y } = localMousePosition(canvasOrigin, clientX, clientY, zoomScale); commit('mouseEvent', { event: 'mouseUp', x, y, altKey, metaKey, shiftKey, ctrlKey }); resetHandler(); @@ -123,7 +122,6 @@ const handleMouseDown = ( return; } - e.stopPropagation(); if (buttons !== 1 || !commit) { resetHandler(); return; // left-click only diff --git a/x-pack/plugins/canvas/public/expression_types/arg_types/font.js b/x-pack/plugins/canvas/public/expression_types/arg_types/font.js index 1ec6ba77685ef2..d1e71fb59bf4d0 100644 --- a/x-pack/plugins/canvas/public/expression_types/arg_types/font.js +++ b/x-pack/plugins/canvas/public/expression_types/arg_types/font.js @@ -8,7 +8,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { get, mapValues } from 'lodash'; -import { set } from '@elastic/safer-lodash-set'; +import { set } from '@kbn/safer-lodash-set'; import { openSans } from '../../../common/lib/fonts'; import { templateFromReactComponent } from '../../lib/template_from_react_component'; import { TextStylePicker } from '../../components/text_style_picker'; diff --git a/x-pack/plugins/canvas/public/functions/plot/index.ts b/x-pack/plugins/canvas/public/functions/plot/index.ts index 5880d833c5be1d..cc2a893777c2ef 100644 --- a/x-pack/plugins/canvas/public/functions/plot/index.ts +++ b/x-pack/plugins/canvas/public/functions/plot/index.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { set } from '@elastic/safer-lodash-set'; +import { set } from '@kbn/safer-lodash-set'; import { groupBy, get, keyBy, map, sortBy } from 'lodash'; import { ExpressionFunctionDefinition, Style } from '@kbn/expressions-plugin/common'; import type { PaletteRegistry, PaletteOutput } from '@kbn/coloring'; diff --git a/x-pack/plugins/canvas/storybook/decorators/redux_decorator.tsx b/x-pack/plugins/canvas/storybook/decorators/redux_decorator.tsx index 22dd3fcbd711ef..e3864086a85dd0 100644 --- a/x-pack/plugins/canvas/storybook/decorators/redux_decorator.tsx +++ b/x-pack/plugins/canvas/storybook/decorators/redux_decorator.tsx @@ -9,7 +9,7 @@ import React from 'react'; import { createStore } from 'redux'; import { Provider as ReduxProvider } from 'react-redux'; import { cloneDeep } from 'lodash'; -import { set } from '@elastic/safer-lodash-set'; +import { set } from '@kbn/safer-lodash-set'; import { CanvasWorkpad, CanvasElement, CanvasAsset, CanvasPage } from '../../types'; diff --git a/x-pack/plugins/cases/public/common/mock/test_providers.tsx b/x-pack/plugins/cases/public/common/mock/test_providers.tsx index 46dda67c23f7f4..dceb8fd0f30a71 100644 --- a/x-pack/plugins/cases/public/common/mock/test_providers.tsx +++ b/x-pack/plugins/cases/public/common/mock/test_providers.tsx @@ -12,7 +12,7 @@ import { ThemeProvider } from 'styled-components'; import { render as reactRender, RenderOptions, RenderResult } from '@testing-library/react'; import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public'; -import { QueryClient, QueryClientProvider } from 'react-query'; +import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { SECURITY_SOLUTION_OWNER } from '../../../common/constants'; import { CasesCapabilities, CasesFeatures, CasesPermissions } from '../../../common/ui/types'; import { CasesProvider } from '../../components/cases_context'; diff --git a/x-pack/plugins/cases/public/components/all_cases/selector_modal/all_cases_selector_modal.test.tsx b/x-pack/plugins/cases/public/components/all_cases/selector_modal/all_cases_selector_modal.test.tsx index eba8888f3367a5..98c89215aac21d 100644 --- a/x-pack/plugins/cases/public/components/all_cases/selector_modal/all_cases_selector_modal.test.tsx +++ b/x-pack/plugins/cases/public/components/all_cases/selector_modal/all_cases_selector_modal.test.tsx @@ -12,7 +12,7 @@ import { AllCasesSelectorModal } from '.'; import { TestProviders } from '../../../common/mock'; import { AllCasesList } from '../all_cases_list'; -jest.mock('../all_cases_list'); +jest.mock('../all_cases_list', () => ({ AllCasesList: jest.fn().mockReturnValue(<>) })); const onRowClick = jest.fn(); const defaultProps = { @@ -57,8 +57,7 @@ describe('AllCasesSelectorModal', () => { ); - // @ts-ignore idk what this mock style is but it works ¯\_(ツ)_/¯ - expect(AllCasesList.type.mock.calls[0][0]).toEqual( + expect((AllCasesList as unknown as jest.Mock).mock.calls[0][0]).toEqual( expect.objectContaining({ hiddenStatuses: fullProps.hiddenStatuses, isSelectorView: true, diff --git a/x-pack/plugins/cases/public/components/all_cases/selector_modal/all_cases_selector_modal.tsx b/x-pack/plugins/cases/public/components/all_cases/selector_modal/all_cases_selector_modal.tsx index 173d4ec76b2306..fccdf76abd2c4d 100644 --- a/x-pack/plugins/cases/public/components/all_cases/selector_modal/all_cases_selector_modal.tsx +++ b/x-pack/plugins/cases/public/components/all_cases/selector_modal/all_cases_selector_modal.tsx @@ -15,7 +15,7 @@ import { EuiModalHeaderTitle, } from '@elastic/eui'; import styled from 'styled-components'; -import { QueryClientProvider } from 'react-query'; +import { QueryClientProvider } from '@tanstack/react-query'; import { Case, CaseStatusWithAllStatus } from '../../../../common/ui/types'; import * as i18n from '../../../common/translations'; import { AllCasesList } from '../all_cases_list'; diff --git a/x-pack/plugins/cases/public/components/app/routes.tsx b/x-pack/plugins/cases/public/components/app/routes.tsx index 6e952ce84ba1e6..062007f3341e65 100644 --- a/x-pack/plugins/cases/public/components/app/routes.tsx +++ b/x-pack/plugins/cases/public/components/app/routes.tsx @@ -8,7 +8,7 @@ import React, { lazy, Suspense, useCallback } from 'react'; import { Redirect, Switch } from 'react-router-dom'; import { Route } from '@kbn/kibana-react-plugin/public'; -import { QueryClientProvider } from 'react-query'; +import { QueryClientProvider } from '@tanstack/react-query'; import { EuiLoadingSpinner } from '@elastic/eui'; import { AllCases } from '../all_cases'; import { CreateCase } from '../create'; diff --git a/x-pack/plugins/cases/public/components/case_view/case_view_page.test.tsx b/x-pack/plugins/cases/public/components/case_view/case_view_page.test.tsx index ea9ce128289388..284785b33d7207 100644 --- a/x-pack/plugins/cases/public/components/case_view/case_view_page.test.tsx +++ b/x-pack/plugins/cases/public/components/case_view/case_view_page.test.tsx @@ -40,7 +40,9 @@ jest.mock('../../containers/use_get_tags'); jest.mock('../../containers/use_get_case'); jest.mock('../../containers/configure/use_connectors'); jest.mock('../../containers/use_post_push_to_service'); -jest.mock('../user_actions/timestamp'); +jest.mock('../user_actions/timestamp', () => ({ + UserActionTimestamp: () => <>, +})); jest.mock('../../common/navigation/hooks'); jest.mock('../../common/hooks'); jest.mock('../connectors/resilient/api'); diff --git a/x-pack/plugins/cases/public/components/case_view/components/case_view_activity.test.tsx b/x-pack/plugins/cases/public/components/case_view/components/case_view_activity.test.tsx index 8a3a457bcfd00a..db5411525290b5 100644 --- a/x-pack/plugins/cases/public/components/case_view/components/case_view_activity.test.tsx +++ b/x-pack/plugins/cases/public/components/case_view/components/case_view_activity.test.tsx @@ -30,7 +30,9 @@ import { useGetTags } from '../../../containers/use_get_tags'; jest.mock('../../../containers/use_get_case_user_actions'); jest.mock('../../../containers/configure/use_connectors'); jest.mock('../../../containers/use_post_push_to_service'); -jest.mock('../../user_actions/timestamp'); +jest.mock('../../user_actions/timestamp', () => ({ + UserActionTimestamp: () => <>, +})); jest.mock('../../../common/navigation/hooks'); jest.mock('../../../containers/use_get_action_license'); jest.mock('../../../containers/use_get_tags'); diff --git a/x-pack/plugins/cases/public/components/case_view/index.test.tsx b/x-pack/plugins/cases/public/components/case_view/index.test.tsx index b9213a8eb887f1..20cf2c8d0d9b45 100644 --- a/x-pack/plugins/cases/public/components/case_view/index.test.tsx +++ b/x-pack/plugins/cases/public/components/case_view/index.test.tsx @@ -49,7 +49,9 @@ jest.mock('../../containers/use_get_case'); jest.mock('../../containers/use_get_case_metrics'); jest.mock('../../containers/configure/use_connectors'); jest.mock('../../containers/use_post_push_to_service'); -jest.mock('../user_actions/timestamp'); +jest.mock('../user_actions/timestamp', () => ({ + UserActionTimestamp: () => <>, +})); jest.mock('../../common/lib/kibana'); jest.mock('../../common/navigation/hooks'); jest.mock('../../containers/api'); @@ -171,7 +173,7 @@ describe('CaseView', () => { const queryClientSpy = jest.spyOn(appMockRenderer.queryClient, 'invalidateQueries'); const result = appMockRenderer.render(); userEvent.click(result.getByTestId('case-refresh')); - expect(queryClientSpy).toHaveBeenCalledWith('case'); + expect(queryClientSpy).toHaveBeenCalledWith(['case']); }); describe('when a `refreshRef` prop is provided', () => { @@ -203,7 +205,7 @@ describe('CaseView', () => { it('should refresh actions and comments', async () => { refreshRef!.current!.refreshCase(); await waitFor(() => { - expect(queryClientSpy).toHaveBeenCalledWith(CASE_VIEW_CACHE_KEY); + expect(queryClientSpy).toHaveBeenCalledWith([CASE_VIEW_CACHE_KEY]); }); }); }); diff --git a/x-pack/plugins/cases/public/components/case_view/use_on_refresh_case_view_page.tsx b/x-pack/plugins/cases/public/components/case_view/use_on_refresh_case_view_page.tsx index a4c36deabef80e..396f180a074a03 100644 --- a/x-pack/plugins/cases/public/components/case_view/use_on_refresh_case_view_page.tsx +++ b/x-pack/plugins/cases/public/components/case_view/use_on_refresh_case_view_page.tsx @@ -6,7 +6,7 @@ */ import { useCallback } from 'react'; -import { useQueryClient } from 'react-query'; +import { useQueryClient } from '@tanstack/react-query'; import { CASE_TAGS_CACHE_KEY, CASE_VIEW_CACHE_KEY } from '../../containers/constants'; /** @@ -20,7 +20,7 @@ import { CASE_TAGS_CACHE_KEY, CASE_VIEW_CACHE_KEY } from '../../containers/const export const useRefreshCaseViewPage = () => { const queryClient = useQueryClient(); return useCallback(() => { - queryClient.invalidateQueries(CASE_VIEW_CACHE_KEY); - queryClient.invalidateQueries(CASE_TAGS_CACHE_KEY); + queryClient.invalidateQueries([CASE_VIEW_CACHE_KEY]); + queryClient.invalidateQueries([CASE_TAGS_CACHE_KEY]); }, [queryClient]); }; diff --git a/x-pack/plugins/cases/public/components/cases_context/query_client.ts b/x-pack/plugins/cases/public/components/cases_context/query_client.ts index 08a135f5f93952..3f27e7b550adfe 100644 --- a/x-pack/plugins/cases/public/components/cases_context/query_client.ts +++ b/x-pack/plugins/cases/public/components/cases_context/query_client.ts @@ -5,6 +5,6 @@ * 2.0. */ -import { QueryClient } from 'react-query'; +import { QueryClient } from '@tanstack/react-query'; export const casesQueryClient = new QueryClient(); diff --git a/x-pack/plugins/cases/public/components/create/flyout/create_case_flyout.tsx b/x-pack/plugins/cases/public/components/create/flyout/create_case_flyout.tsx index be758e17184513..c7bcb9b0828c6c 100644 --- a/x-pack/plugins/cases/public/components/create/flyout/create_case_flyout.tsx +++ b/x-pack/plugins/cases/public/components/create/flyout/create_case_flyout.tsx @@ -9,7 +9,7 @@ import React from 'react'; import styled, { createGlobalStyle } from 'styled-components'; import { EuiFlyout, EuiFlyoutHeader, EuiTitle, EuiFlyoutBody } from '@elastic/eui'; -import { QueryClientProvider } from 'react-query'; +import { QueryClientProvider } from '@tanstack/react-query'; import * as i18n from '../translations'; import { Case } from '../../../../common/ui/types'; import { CreateCaseForm } from '../form'; diff --git a/x-pack/plugins/cases/public/components/header_page/__snapshots__/editable_title.test.tsx.snap b/x-pack/plugins/cases/public/components/header_page/__snapshots__/editable_title.test.tsx.snap index bc4dba5843e625..73f466aeec7710 100644 --- a/x-pack/plugins/cases/public/components/header_page/__snapshots__/editable_title.test.tsx.snap +++ b/x-pack/plugins/cases/public/components/header_page/__snapshots__/editable_title.test.tsx.snap @@ -14,11 +14,38 @@ exports[`EditableTitle renders 1`] = ` "retry": false, }, }, + "logger": BufferedConsole { + "Console": [Function], + "_buffer": Array [], + "_counters": Object {}, + "_groupDepth": 0, + "_timers": Object {}, + "assert": [Function], + "clear": [Function], + "count": [Function], + "countReset": [Function], + "debug": [Function], + "dir": [Function], + "dirxml": [Function], + "error": [Function], + "group": [Function], + "groupCollapsed": [Function], + "groupEnd": [Function], + "info": [Function], + "log": [Function], + "table": [Function], + "time": [Function], + "timeEnd": [Function], + "timeLog": [Function], + "trace": [Function], + "warn": [Function], + }, "mutationCache": MutationCache { "config": Object {}, "listeners": Array [], "mutationId": 0, "mutations": Array [], + "subscribe": [Function], }, "mutationDefaults": Array [], "queryCache": QueryCache { @@ -26,6 +53,7 @@ exports[`EditableTitle renders 1`] = ` "listeners": Array [], "queries": Array [], "queriesMap": Object {}, + "subscribe": [Function], }, "queryDefaults": Array [], } diff --git a/x-pack/plugins/cases/public/components/header_page/__snapshots__/index.test.tsx.snap b/x-pack/plugins/cases/public/components/header_page/__snapshots__/index.test.tsx.snap index 083975a40330ee..7e6d9e2b05d94b 100644 --- a/x-pack/plugins/cases/public/components/header_page/__snapshots__/index.test.tsx.snap +++ b/x-pack/plugins/cases/public/components/header_page/__snapshots__/index.test.tsx.snap @@ -14,11 +14,38 @@ exports[`HeaderPage it renders 1`] = ` "retry": false, }, }, + "logger": BufferedConsole { + "Console": [Function], + "_buffer": Array [], + "_counters": Object {}, + "_groupDepth": 0, + "_timers": Object {}, + "assert": [Function], + "clear": [Function], + "count": [Function], + "countReset": [Function], + "debug": [Function], + "dir": [Function], + "dirxml": [Function], + "error": [Function], + "group": [Function], + "groupCollapsed": [Function], + "groupEnd": [Function], + "info": [Function], + "log": [Function], + "table": [Function], + "time": [Function], + "timeEnd": [Function], + "timeLog": [Function], + "trace": [Function], + "warn": [Function], + }, "mutationCache": MutationCache { "config": Object {}, "listeners": Array [], "mutationId": 0, "mutations": Array [], + "subscribe": [Function], }, "mutationDefaults": Array [], "queryCache": QueryCache { @@ -26,6 +53,7 @@ exports[`HeaderPage it renders 1`] = ` "listeners": Array [], "queries": Array [], "queriesMap": Object {}, + "subscribe": [Function], }, "queryDefaults": Array [], } diff --git a/x-pack/plugins/cases/public/components/recent_cases/index.tsx b/x-pack/plugins/cases/public/components/recent_cases/index.tsx index 4cc070e77b76a8..c8b7581e531072 100644 --- a/x-pack/plugins/cases/public/components/recent_cases/index.tsx +++ b/x-pack/plugins/cases/public/components/recent_cases/index.tsx @@ -8,7 +8,7 @@ import { EuiFlexGroup, EuiFlexItem, EuiHorizontalRule, EuiText, EuiTitle } from '@elastic/eui'; import React, { useCallback, useMemo, useState } from 'react'; -import { QueryClientProvider } from 'react-query'; +import { QueryClientProvider } from '@tanstack/react-query'; import * as i18n from './translations'; import { LinkAnchor } from '../links'; import { RecentCasesFilters } from './filters'; diff --git a/x-pack/plugins/cases/public/components/user_actions/index.test.tsx b/x-pack/plugins/cases/public/components/user_actions/index.test.tsx index 9a971552f5ec30..60fc0e92d024bf 100644 --- a/x-pack/plugins/cases/public/components/user_actions/index.test.tsx +++ b/x-pack/plugins/cases/public/components/user_actions/index.test.tsx @@ -53,7 +53,9 @@ const defaultProps = { }; jest.mock('../../containers/use_update_comment'); -jest.mock('./timestamp'); +jest.mock('./timestamp', () => ({ + UserActionTimestamp: () => <>, +})); jest.mock('../../common/lib/kibana'); const useUpdateCommentMock = useUpdateComment as jest.Mock; diff --git a/x-pack/plugins/cases/public/containers/configure/use_action_types.tsx b/x-pack/plugins/cases/public/containers/configure/use_action_types.tsx index caca1de7afcec2..76a48e5d09ca30 100644 --- a/x-pack/plugins/cases/public/containers/configure/use_action_types.tsx +++ b/x-pack/plugins/cases/public/containers/configure/use_action_types.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { useQuery } from 'react-query'; +import { useQuery } from '@tanstack/react-query'; import * as i18n from '../translations'; import { fetchActionTypes } from './api'; import { useToasts } from '../../common/lib/kibana'; diff --git a/x-pack/plugins/cases/public/containers/configure/use_connectors.tsx b/x-pack/plugins/cases/public/containers/configure/use_connectors.tsx index 9f1d3f38655ae8..95124af988fb68 100644 --- a/x-pack/plugins/cases/public/containers/configure/use_connectors.tsx +++ b/x-pack/plugins/cases/public/containers/configure/use_connectors.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { useQuery } from 'react-query'; +import { useQuery } from '@tanstack/react-query'; import { fetchConnectors } from './api'; import { useApplicationCapabilities, useToasts } from '../../common/lib/kibana'; import * as i18n from './translations'; diff --git a/x-pack/plugins/cases/public/containers/use_get_action_license.tsx b/x-pack/plugins/cases/public/containers/use_get_action_license.tsx index a64a449783ba92..8e9aa28de440a9 100644 --- a/x-pack/plugins/cases/public/containers/use_get_action_license.tsx +++ b/x-pack/plugins/cases/public/containers/use_get_action_license.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { useQuery } from 'react-query'; +import { useQuery } from '@tanstack/react-query'; import { useToasts } from '../common/lib/kibana'; import { getActionLicense } from './api'; import * as i18n from './translations'; diff --git a/x-pack/plugins/cases/public/containers/use_get_case.test.tsx b/x-pack/plugins/cases/public/containers/use_get_case.test.tsx index 8a3d7263b78de6..7b07d44bdda788 100644 --- a/x-pack/plugins/cases/public/containers/use_get_case.test.tsx +++ b/x-pack/plugins/cases/public/containers/use_get_case.test.tsx @@ -10,7 +10,7 @@ import { useGetCase } from './use_get_case'; import * as api from './api'; import { waitFor } from '@testing-library/dom'; import React from 'react'; -import { QueryClient, QueryClientProvider } from 'react-query'; +import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { useToasts } from '../common/lib/kibana'; jest.mock('./api'); diff --git a/x-pack/plugins/cases/public/containers/use_get_case.tsx b/x-pack/plugins/cases/public/containers/use_get_case.tsx index ff0cce344b87fe..ded91240239a1c 100644 --- a/x-pack/plugins/cases/public/containers/use_get_case.tsx +++ b/x-pack/plugins/cases/public/containers/use_get_case.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { useQuery } from 'react-query'; +import { useQuery } from '@tanstack/react-query'; import { ResolvedCase } from './types'; import * as i18n from './translations'; import { useToasts } from '../common/lib/kibana'; diff --git a/x-pack/plugins/cases/public/containers/use_get_case_metrics.test.tsx b/x-pack/plugins/cases/public/containers/use_get_case_metrics.test.tsx index 3cd3904a24072c..7f613977281709 100644 --- a/x-pack/plugins/cases/public/containers/use_get_case_metrics.test.tsx +++ b/x-pack/plugins/cases/public/containers/use_get_case_metrics.test.tsx @@ -48,13 +48,11 @@ describe('useGetCaseMetrics', () => { throw new Error('Something went wrong'); }); - await act(async () => { - const { waitForNextUpdate } = renderHook(() => useGetCaseMetrics(basicCase.id, features), { - wrapper, - }); - await waitForNextUpdate(); - expect(spyOnGetCaseMetrics).toBeCalledWith(basicCase.id, features, abortCtrl.signal); - expect(addError).toHaveBeenCalled(); + const { waitForNextUpdate } = renderHook(() => useGetCaseMetrics(basicCase.id, features), { + wrapper, }); + await waitForNextUpdate(); + expect(spyOnGetCaseMetrics).toBeCalledWith(basicCase.id, features, abortCtrl.signal); + expect(addError).toHaveBeenCalled(); }); }); diff --git a/x-pack/plugins/cases/public/containers/use_get_case_metrics.tsx b/x-pack/plugins/cases/public/containers/use_get_case_metrics.tsx index 359bd6b7eeae9e..1e294c4a5ba6ec 100644 --- a/x-pack/plugins/cases/public/containers/use_get_case_metrics.tsx +++ b/x-pack/plugins/cases/public/containers/use_get_case_metrics.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { useQuery } from 'react-query'; +import { useQuery } from '@tanstack/react-query'; import { SingleCaseMetrics, SingleCaseMetricsFeature } from './types'; import { useToasts } from '../common/lib/kibana'; import { getSingleCaseMetrics } from './api'; diff --git a/x-pack/plugins/cases/public/containers/use_get_case_user_actions.test.tsx b/x-pack/plugins/cases/public/containers/use_get_case_user_actions.test.tsx index 3d231a9660ba2f..c5dbf017da8c94 100644 --- a/x-pack/plugins/cases/public/containers/use_get_case_user_actions.test.tsx +++ b/x-pack/plugins/cases/public/containers/use_get_case_user_actions.test.tsx @@ -22,7 +22,7 @@ import { } from './mock'; import { Actions } from '../../common/api'; import React from 'react'; -import { QueryClientProvider } from 'react-query'; +import { QueryClientProvider } from '@tanstack/react-query'; import { testQueryClient } from '../common/mock'; import { waitFor } from '@testing-library/dom'; import * as api from './api'; diff --git a/x-pack/plugins/cases/public/containers/use_get_case_user_actions.tsx b/x-pack/plugins/cases/public/containers/use_get_case_user_actions.tsx index 9376598b1fdf4f..da695201d6d768 100644 --- a/x-pack/plugins/cases/public/containers/use_get_case_user_actions.tsx +++ b/x-pack/plugins/cases/public/containers/use_get_case_user_actions.tsx @@ -8,7 +8,7 @@ import { isEmpty, uniqBy } from 'lodash/fp'; import deepEqual from 'fast-deep-equal'; -import { useQuery } from 'react-query'; +import { useQuery } from '@tanstack/react-query'; import { CaseUserActions, CaseExternalService } from '../../common/ui/types'; import { ActionTypes, CaseConnector, NONE_CONNECTOR_ID } from '../../common/api'; import { getCaseUserActions } from './api'; diff --git a/x-pack/plugins/cases/public/containers/use_get_cases.tsx b/x-pack/plugins/cases/public/containers/use_get_cases.tsx index 6274ac863200f3..ce19e68fa17988 100644 --- a/x-pack/plugins/cases/public/containers/use_get_cases.tsx +++ b/x-pack/plugins/cases/public/containers/use_get_cases.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { useQuery, UseQueryResult } from 'react-query'; +import { useQuery, UseQueryResult } from '@tanstack/react-query'; import { CASE_LIST_CACHE_KEY, DEFAULT_TABLE_ACTIVE_PAGE, DEFAULT_TABLE_LIMIT } from './constants'; import { Cases, FilterOptions, QueryParams, SortFieldCase, StatusAll, SeverityAll } from './types'; import { useToasts } from '../common/lib/kibana'; diff --git a/x-pack/plugins/cases/public/containers/use_get_tags.tsx b/x-pack/plugins/cases/public/containers/use_get_tags.tsx index 3e18ac0a013152..1696a9d1413a5e 100644 --- a/x-pack/plugins/cases/public/containers/use_get_tags.tsx +++ b/x-pack/plugins/cases/public/containers/use_get_tags.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { useQuery } from 'react-query'; +import { useQuery } from '@tanstack/react-query'; import { useToasts } from '../common/lib/kibana'; import { useCasesContext } from '../components/cases_context/use_cases_context'; import { ServerError } from '../types'; diff --git a/x-pack/plugins/cases/public/containers/user_profiles/use_bulk_get_user_profiles.ts b/x-pack/plugins/cases/public/containers/user_profiles/use_bulk_get_user_profiles.ts index cdaee1848613cf..78c310462f77e2 100644 --- a/x-pack/plugins/cases/public/containers/user_profiles/use_bulk_get_user_profiles.ts +++ b/x-pack/plugins/cases/public/containers/user_profiles/use_bulk_get_user_profiles.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { useQuery, UseQueryResult } from 'react-query'; +import { useQuery, UseQueryResult } from '@tanstack/react-query'; import { UserProfile } from '@kbn/security-plugin/common'; import * as i18n from '../translations'; import { useKibana, useToasts } from '../../common/lib/kibana'; diff --git a/x-pack/plugins/cases/public/containers/user_profiles/use_suggest_user_profiles.test.ts b/x-pack/plugins/cases/public/containers/user_profiles/use_suggest_user_profiles.test.ts index 5ae16c8fa6e00b..ef5fe32a23dff8 100644 --- a/x-pack/plugins/cases/public/containers/user_profiles/use_suggest_user_profiles.test.ts +++ b/x-pack/plugins/cases/public/containers/user_profiles/use_suggest_user_profiles.test.ts @@ -26,21 +26,8 @@ describe('useSuggestUserProfiles', () => { let appMockRender: AppMockRenderer; - beforeAll(() => { - jest.useFakeTimers(); - }); - beforeEach(() => { appMockRender = createAppMockRenderer(); - jest.clearAllMocks(); - }); - - afterEach(() => { - jest.clearAllTimers(); - }); - - afterAll(() => { - jest.useRealTimers(); }); it('calls suggestUserProfiles with correct arguments', async () => { @@ -50,7 +37,6 @@ describe('useSuggestUserProfiles', () => { wrapper: appMockRender.AppWrapper, }); - jest.advanceTimersByTime(500); await waitFor(() => result.current.isSuccess); expect(spyOnSuggestUserProfiles).toBeCalledWith({ @@ -75,7 +61,6 @@ describe('useSuggestUserProfiles', () => { wrapper: appMockRender.AppWrapper, }); - jest.advanceTimersByTime(500); await waitFor(() => result.current.isError); expect(addError).toHaveBeenCalled(); diff --git a/x-pack/plugins/cases/public/containers/user_profiles/use_suggest_user_profiles.ts b/x-pack/plugins/cases/public/containers/user_profiles/use_suggest_user_profiles.ts index 3705224e1d0c81..6c83f853b2624e 100644 --- a/x-pack/plugins/cases/public/containers/user_profiles/use_suggest_user_profiles.ts +++ b/x-pack/plugins/cases/public/containers/user_profiles/use_suggest_user_profiles.ts @@ -6,7 +6,7 @@ */ import { useState } from 'react'; -import { useQuery, UseQueryResult } from 'react-query'; +import { useQuery, UseQueryResult } from '@tanstack/react-query'; import useDebounce from 'react-use/lib/useDebounce'; import { UserProfile } from '@kbn/security-plugin/common'; import { DEFAULT_USER_SIZE } from '../../../common/constants'; diff --git a/x-pack/plugins/cases/server/services/so_reference_extractor.ts b/x-pack/plugins/cases/server/services/so_reference_extractor.ts index 622cce373e7551..27fdf17b5f727d 100644 --- a/x-pack/plugins/cases/server/services/so_reference_extractor.ts +++ b/x-pack/plugins/cases/server/services/so_reference_extractor.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { set } from '@elastic/safer-lodash-set'; +import { set } from '@kbn/safer-lodash-set'; import _ from 'lodash'; import { SavedObject, SavedObjectReference, SavedObjectsUpdateResponse } from '@kbn/core/server'; diff --git a/x-pack/plugins/cloud_security_posture/common/types.ts b/x-pack/plugins/cloud_security_posture/common/types.ts index f79b651f826ca1..f4d139d6a58dae 100644 --- a/x-pack/plugins/cloud_security_posture/common/types.ts +++ b/x-pack/plugins/cloud_security_posture/common/types.ts @@ -5,7 +5,7 @@ * 2.0. */ -import type { PackagePolicy, GetAgentPoliciesResponseItem } from '@kbn/fleet-plugin/common'; +import type { PackagePolicy, AgentPolicy } from '@kbn/fleet-plugin/common'; import type { CspRuleMetadata } from './schemas/csp_rule_metadata'; export type Evaluation = 'passed' | 'failed' | 'NA'; @@ -49,7 +49,7 @@ export interface ComplianceDashboardData { trend: PostureTrend[]; } -export type Status = +export type CspStatusCode = | 'indexed' // latest findings index exists and has results | 'indexing' // index timeout was not surpassed since installation, assumes data is being indexed | 'index-timeout' // index timeout was surpassed since installation @@ -58,16 +58,16 @@ export type Status = interface BaseCspSetupStatus { latestPackageVersion: string; - installedIntegrations: number; + installedPackagePolicies: number; healthyAgents: number; } interface CspSetupNotInstalledStatus extends BaseCspSetupStatus { - status: Extract; + status: Extract; } interface CspSetupInstalledStatus extends BaseCspSetupStatus { - status: Exclude; + status: Exclude; // if installedPackageVersion == undefined but status != 'not-installed' it means the integration was installed in the past and findings were found // status can be `indexed` but return with undefined package information in this case installedPackageVersion: string | undefined; @@ -81,6 +81,8 @@ export interface CspRulesStatus { disabled: number; } +export type AgentPolicyStatus = Pick & { agents: number }; + export interface Benchmark { package_policy: Pick< PackagePolicy, @@ -94,7 +96,7 @@ export interface Benchmark { | 'created_at' | 'created_by' >; - agent_policy: Pick; + agent_policy: AgentPolicyStatus; rules: CspRulesStatus; } diff --git a/x-pack/plugins/cloud_security_posture/public/application/csp_router.tsx b/x-pack/plugins/cloud_security_posture/public/application/csp_router.tsx index 2fd84c5967e290..9f17ae174dd67a 100644 --- a/x-pack/plugins/cloud_security_posture/public/application/csp_router.tsx +++ b/x-pack/plugins/cloud_security_posture/public/application/csp_router.tsx @@ -6,7 +6,7 @@ */ import React from 'react'; -import { QueryClient, QueryClientProvider } from 'react-query'; +import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { Redirect, Route, RouteComponentProps, type RouteProps, Switch } from 'react-router-dom'; import { CLOUD_SECURITY_POSTURE_BASE_PATH, type CspSecuritySolutionContext } from '..'; import { cloudPosturePages } from '../common/navigation/constants'; diff --git a/x-pack/plugins/cloud_security_posture/public/common/api/use_cis_kubernetes_integration.tsx b/x-pack/plugins/cloud_security_posture/public/common/api/use_cis_kubernetes_integration.tsx index 5660080cb0a43d..26b885ad443449 100644 --- a/x-pack/plugins/cloud_security_posture/public/common/api/use_cis_kubernetes_integration.tsx +++ b/x-pack/plugins/cloud_security_posture/public/common/api/use_cis_kubernetes_integration.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { useQuery } from 'react-query'; +import { useQuery } from '@tanstack/react-query'; import { epmRouteService, type GetInfoResponse, diff --git a/x-pack/plugins/cloud_security_posture/public/common/api/use_compliance_dashboard_data_api.ts b/x-pack/plugins/cloud_security_posture/public/common/api/use_compliance_dashboard_data_api.ts index feb9cf50ad120a..c1b108bb5f98a7 100644 --- a/x-pack/plugins/cloud_security_posture/public/common/api/use_compliance_dashboard_data_api.ts +++ b/x-pack/plugins/cloud_security_posture/public/common/api/use_compliance_dashboard_data_api.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { type QueryObserverOptions, useQuery } from 'react-query'; +import { type QueryObserverOptions, useQuery } from '@tanstack/react-query'; import { useKibana } from '../hooks/use_kibana'; import { ComplianceDashboardData } from '../../../common/types'; import { STATS_ROUTE_PATH } from '../../../common/constants'; diff --git a/x-pack/plugins/cloud_security_posture/public/common/api/use_latest_findings_data_view.ts b/x-pack/plugins/cloud_security_posture/public/common/api/use_latest_findings_data_view.ts index 8f7a9c9b59d5e9..e40a4c5a8e8c2f 100644 --- a/x-pack/plugins/cloud_security_posture/public/common/api/use_latest_findings_data_view.ts +++ b/x-pack/plugins/cloud_security_posture/public/common/api/use_latest_findings_data_view.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { useQuery } from 'react-query'; +import { useQuery } from '@tanstack/react-query'; import { useKibana } from '@kbn/kibana-react-plugin/public'; import type { DataView } from '@kbn/data-plugin/common'; import { CSP_LATEST_FINDINGS_DATA_VIEW } from '../../../common/constants'; diff --git a/x-pack/plugins/cloud_security_posture/public/common/api/use_setup_status_api.ts b/x-pack/plugins/cloud_security_posture/public/common/api/use_setup_status_api.ts index fce0b9c2d77900..7c5d4eb8dc31b8 100644 --- a/x-pack/plugins/cloud_security_posture/public/common/api/use_setup_status_api.ts +++ b/x-pack/plugins/cloud_security_posture/public/common/api/use_setup_status_api.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { useQuery, type UseQueryOptions } from 'react-query'; +import { useQuery, type UseQueryOptions } from '@tanstack/react-query'; import { useKibana } from '../hooks/use_kibana'; import { CspSetupStatus } from '../../../common/types'; import { STATUS_ROUTE_PATH } from '../../../common/constants'; diff --git a/x-pack/plugins/cloud_security_posture/public/components/cloud_posture_page.test.tsx b/x-pack/plugins/cloud_security_posture/public/components/cloud_posture_page.test.tsx index 3de37af1d7a654..c3cec5ca27774e 100644 --- a/x-pack/plugins/cloud_security_posture/public/components/cloud_posture_page.test.tsx +++ b/x-pack/plugins/cloud_security_posture/public/components/cloud_posture_page.test.tsx @@ -18,7 +18,7 @@ import { TestProvider } from '../test/test_provider'; import { coreMock } from '@kbn/core/public/mocks'; import { render, screen } from '@testing-library/react'; import React, { ComponentProps } from 'react'; -import { UseQueryResult } from 'react-query'; +import { UseQueryResult } from '@tanstack/react-query'; import { CloudPosturePage } from './cloud_posture_page'; import { NoDataPage } from '@kbn/kibana-react-plugin/public'; import { useCspSetupStatusApi } from '../common/api/use_setup_status_api'; diff --git a/x-pack/plugins/cloud_security_posture/public/components/cloud_posture_page.tsx b/x-pack/plugins/cloud_security_posture/public/components/cloud_posture_page.tsx index dfa1c51f5226aa..4ded9cb9060bbc 100644 --- a/x-pack/plugins/cloud_security_posture/public/components/cloud_posture_page.tsx +++ b/x-pack/plugins/cloud_security_posture/public/components/cloud_posture_page.tsx @@ -6,7 +6,7 @@ */ import React from 'react'; import { i18n } from '@kbn/i18n'; -import type { UseQueryResult } from 'react-query'; +import type { UseQueryResult } from '@tanstack/react-query'; import { EuiEmptyPrompt } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; import { NoDataPage } from '@kbn/kibana-react-plugin/public'; @@ -166,7 +166,7 @@ export const CloudPosturePage = ({ return defaultErrorRenderer(getSetupStatus.error); } - if (getSetupStatus.isLoading || getSetupStatus.isIdle) { + if (getSetupStatus.isLoading) { return defaultLoadingRenderer(); } @@ -182,7 +182,7 @@ export const CloudPosturePage = ({ return errorRender(query.error); } - if (query.isLoading || query.isIdle) { + if (query.isLoading) { return loadingRender(); } diff --git a/x-pack/plugins/cloud_security_posture/public/pages/benchmarks/benchmarks.test.tsx b/x-pack/plugins/cloud_security_posture/public/pages/benchmarks/benchmarks.test.tsx index 12ba2e9db38854..af10c55f19ea96 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/benchmarks/benchmarks.test.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/benchmarks/benchmarks.test.tsx @@ -7,7 +7,7 @@ import React from 'react'; import Chance from 'chance'; import { render, screen } from '@testing-library/react'; -import type { UseQueryResult } from 'react-query/types/react/types'; +import type { UseQueryResult } from '@tanstack/react-query'; import { createCspBenchmarkIntegrationFixture } from '../../test/fixtures/csp_benchmark_integration'; import { createReactQueryResponse } from '../../test/fixtures/react_query'; import { TestProvider } from '../../test/test_provider'; diff --git a/x-pack/plugins/cloud_security_posture/public/pages/benchmarks/benchmarks_table.test.tsx b/x-pack/plugins/cloud_security_posture/public/pages/benchmarks/benchmarks_table.test.tsx index 5fc9a120641536..463d19928db809 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/benchmarks/benchmarks_table.test.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/benchmarks/benchmarks_table.test.tsx @@ -65,7 +65,7 @@ describe('', () => { const agentPolicy = { id: chance.guid(), name: chance.sentence(), - number_of_agents: chance.integer({ min: 1 }), + agents: chance.integer({ min: 1 }), }; const benchmarks = [createCspBenchmarkIntegrationFixture({ agent_policy: agentPolicy })]; diff --git a/x-pack/plugins/cloud_security_posture/public/pages/benchmarks/use_csp_benchmark_integrations.ts b/x-pack/plugins/cloud_security_posture/public/pages/benchmarks/use_csp_benchmark_integrations.ts index 0315893ef4cc2b..ccdc3650b2596f 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/benchmarks/use_csp_benchmark_integrations.ts +++ b/x-pack/plugins/cloud_security_posture/public/pages/benchmarks/use_csp_benchmark_integrations.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { useQuery } from 'react-query'; +import { useQuery } from '@tanstack/react-query'; import type { ListResult } from '@kbn/fleet-plugin/common'; import { BENCHMARKS_ROUTE_PATH } from '../../../common/constants'; import type { BenchmarksQueryParams } from '../../../common/schemas/benchmark'; diff --git a/x-pack/plugins/cloud_security_posture/public/pages/findings/es_pit/findings_es_pit_context.ts b/x-pack/plugins/cloud_security_posture/public/pages/findings/es_pit/findings_es_pit_context.ts index 54105ad21495f3..aa1d660229d756 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/findings/es_pit/findings_es_pit_context.ts +++ b/x-pack/plugins/cloud_security_posture/public/pages/findings/es_pit/findings_es_pit_context.ts @@ -6,7 +6,7 @@ */ import { createContext, type MutableRefObject } from 'react'; -import type { UseQueryResult } from 'react-query'; +import type { UseQueryResult } from '@tanstack/react-query'; interface FindingsEsPitContextValue { setPitId(newPitId: string): void; diff --git a/x-pack/plugins/cloud_security_posture/public/pages/findings/es_pit/use_findings_es_pit.ts b/x-pack/plugins/cloud_security_posture/public/pages/findings/es_pit/use_findings_es_pit.ts index d7d7d6cbe34154..d8f2b22f501d4f 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/findings/es_pit/use_findings_es_pit.ts +++ b/x-pack/plugins/cloud_security_posture/public/pages/findings/es_pit/use_findings_es_pit.ts @@ -6,7 +6,7 @@ */ import { useCallback, useRef, useState } from 'react'; -import { useQuery } from 'react-query'; +import { useQuery } from '@tanstack/react-query'; import { CSP_LATEST_FINDINGS_DATA_VIEW, ES_PIT_ROUTE_PATH } from '../../../../common/constants'; import { useKibana } from '../../../common/hooks/use_kibana'; import { FINDINGS_PIT_KEEP_ALIVE } from '../constants'; diff --git a/x-pack/plugins/cloud_security_posture/public/pages/findings/findings.test.tsx b/x-pack/plugins/cloud_security_posture/public/pages/findings/findings.test.tsx index 7cc01358b17d50..2ee05a2565adc1 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/findings/findings.test.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/findings/findings.test.tsx @@ -6,7 +6,7 @@ */ import React from 'react'; import Chance from 'chance'; -import type { UseQueryResult } from 'react-query'; +import type { UseQueryResult } from '@tanstack/react-query'; import { of } from 'rxjs'; import { useLatestFindingsDataView } from '../../common/api/use_latest_findings_data_view'; import { Findings } from './findings'; diff --git a/x-pack/plugins/cloud_security_posture/public/pages/findings/findings.tsx b/x-pack/plugins/cloud_security_posture/public/pages/findings/findings.tsx index baf4391eb2cc8c..873b2c3c5cd764 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/findings/findings.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/findings/findings.tsx @@ -5,7 +5,7 @@ * 2.0. */ import React from 'react'; -import type { UseQueryResult } from 'react-query'; +import type { UseQueryResult } from '@tanstack/react-query'; import { Redirect, Switch, Route, useLocation } from 'react-router-dom'; import { useCspSetupStatusApi } from '../../common/api/use_setup_status_api'; import { NoFindingsStates } from '../../components/no_findings_states'; @@ -28,7 +28,7 @@ export const Findings = () => { if (!hasFindings) return ; let queryForCloudPosturePage: UseQueryResult = dataViewQuery; - if (pitQuery.isError || pitQuery.isLoading || pitQuery.isIdle) { + if (pitQuery.isError || pitQuery.isLoading) { queryForCloudPosturePage = pitQuery; } diff --git a/x-pack/plugins/cloud_security_posture/public/pages/findings/latest_findings/latest_findings_container.test.tsx b/x-pack/plugins/cloud_security_posture/public/pages/findings/latest_findings/latest_findings_container.test.tsx index 9dc42b2e4413c5..4090f80435b468 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/findings/latest_findings/latest_findings_container.test.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/findings/latest_findings/latest_findings_container.test.tsx @@ -4,7 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import type { UseQueryResult } from 'react-query'; +import type { UseQueryResult } from '@tanstack/react-query'; import { createReactQueryResponse } from '../../../test/fixtures/react_query'; import React from 'react'; import { render } from '@testing-library/react'; diff --git a/x-pack/plugins/cloud_security_posture/public/pages/findings/latest_findings/use_latest_findings.ts b/x-pack/plugins/cloud_security_posture/public/pages/findings/latest_findings/use_latest_findings.ts index 2766ddbebb0478..720d21cea20129 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/findings/latest_findings/use_latest_findings.ts +++ b/x-pack/plugins/cloud_security_posture/public/pages/findings/latest_findings/use_latest_findings.ts @@ -5,7 +5,7 @@ * 2.0. */ import { useContext } from 'react'; -import { useQuery } from 'react-query'; +import { useQuery } from '@tanstack/react-query'; import { number } from 'io-ts'; import { lastValueFrom } from 'rxjs'; import type { IKibanaSearchRequest, IKibanaSearchResponse } from '@kbn/data-plugin/common'; diff --git a/x-pack/plugins/cloud_security_posture/public/pages/findings/latest_findings_by_resource/resource_findings/use_resource_findings.ts b/x-pack/plugins/cloud_security_posture/public/pages/findings/latest_findings_by_resource/resource_findings/use_resource_findings.ts index 44be336f1c0412..53748c54eae0a6 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/findings/latest_findings_by_resource/resource_findings/use_resource_findings.ts +++ b/x-pack/plugins/cloud_security_posture/public/pages/findings/latest_findings_by_resource/resource_findings/use_resource_findings.ts @@ -4,7 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { useQuery } from 'react-query'; +import { useQuery } from '@tanstack/react-query'; import { lastValueFrom } from 'rxjs'; import { IKibanaSearchRequest, IKibanaSearchResponse } from '@kbn/data-plugin/common'; import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; diff --git a/x-pack/plugins/cloud_security_posture/public/pages/findings/latest_findings_by_resource/use_findings_by_resource.ts b/x-pack/plugins/cloud_security_posture/public/pages/findings/latest_findings_by_resource/use_findings_by_resource.ts index ebb8f56c84e403..6def567d64ddd7 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/findings/latest_findings_by_resource/use_findings_by_resource.ts +++ b/x-pack/plugins/cloud_security_posture/public/pages/findings/latest_findings_by_resource/use_findings_by_resource.ts @@ -5,7 +5,7 @@ * 2.0. */ import { useContext } from 'react'; -import { useQuery } from 'react-query'; +import { useQuery } from '@tanstack/react-query'; import { lastValueFrom } from 'rxjs'; import { IKibanaSearchRequest, IKibanaSearchResponse } from '@kbn/data-plugin/common'; import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; diff --git a/x-pack/plugins/cloud_security_posture/public/pages/rules/rules.test.tsx b/x-pack/plugins/cloud_security_posture/public/pages/rules/rules.test.tsx index 32fb45c9fe0256..82238c2d7c4d0d 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/rules/rules.test.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/rules/rules.test.tsx @@ -9,7 +9,7 @@ import React from 'react'; import Chance from 'chance'; import { Rules } from '.'; import { render, screen } from '@testing-library/react'; -import { QueryClient } from 'react-query'; +import { QueryClient } from '@tanstack/react-query'; import { TestProvider } from '../../test/test_provider'; import { useCspIntegrationInfo } from './use_csp_integration'; import { type RouteComponentProps } from 'react-router-dom'; diff --git a/x-pack/plugins/cloud_security_posture/public/pages/rules/rules_container.test.tsx b/x-pack/plugins/cloud_security_posture/public/pages/rules/rules_container.test.tsx index 64488f27d1353e..bd22be3fab482f 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/rules/rules_container.test.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/rules/rules_container.test.tsx @@ -8,7 +8,7 @@ import React from 'react'; import { RulesContainer } from './rules_container'; import { render, screen, fireEvent, within } from '@testing-library/react'; -import { QueryClient } from 'react-query'; +import { QueryClient } from '@tanstack/react-query'; import { useFindCspRules, useBulkUpdateCspRules, type RuleSavedObject } from './use_csp_rules'; import * as TEST_SUBJECTS from './test_subjects'; import { Chance } from 'chance'; diff --git a/x-pack/plugins/cloud_security_posture/public/pages/rules/use_csp_integration.tsx b/x-pack/plugins/cloud_security_posture/public/pages/rules/use_csp_integration.tsx index d28f63769a615a..3743127e9b9bd0 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/rules/use_csp_integration.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/rules/use_csp_integration.tsx @@ -4,7 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { useQuery } from 'react-query'; +import { useQuery } from '@tanstack/react-query'; import { type CopyAgentPolicyResponse, type GetOnePackagePolicyResponse, diff --git a/x-pack/plugins/cloud_security_posture/public/pages/rules/use_csp_rules.ts b/x-pack/plugins/cloud_security_posture/public/pages/rules/use_csp_rules.ts index 8e9b74429b4a36..01ca13870964b5 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/rules/use_csp_rules.ts +++ b/x-pack/plugins/cloud_security_posture/public/pages/rules/use_csp_rules.ts @@ -4,7 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { useQuery, useMutation, useQueryClient } from 'react-query'; +import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'; import { FunctionKeys } from 'utility-types'; import type { SavedObjectsFindOptions, SimpleSavedObject } from '@kbn/core/public'; import { i18n } from '@kbn/i18n'; @@ -74,10 +74,7 @@ export const useBulkUpdateCspRules = () => { }, onSettled: () => // Invalidate all queries for simplicity - queryClient.invalidateQueries({ - queryKey: CSP_RULE_SAVED_OBJECT_TYPE, - exact: false, - }), + queryClient.invalidateQueries([CSP_RULE_SAVED_OBJECT_TYPE]), } ); }; diff --git a/x-pack/plugins/cloud_security_posture/public/test/fixtures/react_query.ts b/x-pack/plugins/cloud_security_posture/public/test/fixtures/react_query.ts index 0169c359b26eb2..96055156188821 100644 --- a/x-pack/plugins/cloud_security_posture/public/test/fixtures/react_query.ts +++ b/x-pack/plugins/cloud_security_posture/public/test/fixtures/react_query.ts @@ -5,10 +5,10 @@ * 2.0. */ -import type { UseQueryResult } from 'react-query/types/react/types'; +import type { UseQueryResult } from '@tanstack/react-query'; interface CreateReactQueryResponseInput { - status?: UseQueryResult['status']; + status?: UseQueryResult['status'] | 'idle'; data?: TData; error?: TError; } @@ -35,12 +35,12 @@ export const createReactQueryResponse = ({ if (status === 'idle') { return { - status, + status: 'loading', data: undefined, isSuccess: false, - isLoading: false, + isLoading: true, isError: false, - isIdle: true, + fetchStatus: 'idle', }; } diff --git a/x-pack/plugins/cloud_security_posture/public/test/test_provider.tsx b/x-pack/plugins/cloud_security_posture/public/test/test_provider.tsx index 758cdb8ca3f60f..09c03c29750a7f 100755 --- a/x-pack/plugins/cloud_security_posture/public/test/test_provider.tsx +++ b/x-pack/plugins/cloud_security_posture/public/test/test_provider.tsx @@ -9,7 +9,7 @@ import type { AppMountParameters, CoreStart } from '@kbn/core/public'; import React, { useMemo } from 'react'; import { I18nProvider } from '@kbn/i18n-react'; import { Router, Switch, Route } from 'react-router-dom'; -import { QueryClient, QueryClientProvider } from 'react-query'; +import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { coreMock } from '@kbn/core/public/mocks'; import { dataPluginMock } from '@kbn/data-plugin/public/mocks'; import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public'; diff --git a/x-pack/plugins/cloud_security_posture/server/lib/is_latest_findings_index_exists.ts b/x-pack/plugins/cloud_security_posture/server/lib/check_for_findings.ts similarity index 69% rename from x-pack/plugins/cloud_security_posture/server/lib/is_latest_findings_index_exists.ts rename to x-pack/plugins/cloud_security_posture/server/lib/check_for_findings.ts index fda35a6d6e2ba4..b8ca29e6512aec 100644 --- a/x-pack/plugins/cloud_security_posture/server/lib/is_latest_findings_index_exists.ts +++ b/x-pack/plugins/cloud_security_posture/server/lib/check_for_findings.ts @@ -6,15 +6,16 @@ */ import { ElasticsearchClient, type Logger } from '@kbn/core/server'; -import { LATEST_FINDINGS_INDEX_DEFAULT_NS } from '../../common/constants'; +import { LATEST_FINDINGS_INDEX_DEFAULT_NS, FINDINGS_INDEX_PATTERN } from '../../common/constants'; -export const isLatestFindingsIndexExists = async ( +export const checkForFindings = async ( esClient: ElasticsearchClient, + latestIndex: boolean, logger: Logger ): Promise => { try { const queryResult = await esClient.search({ - index: LATEST_FINDINGS_INDEX_DEFAULT_NS, + index: latestIndex ? LATEST_FINDINGS_INDEX_DEFAULT_NS : FINDINGS_INDEX_PATTERN, query: { match_all: {}, }, @@ -23,7 +24,7 @@ export const isLatestFindingsIndexExists = async ( return !!queryResult.hits.hits.length; } catch (e) { - logger.error(e.message); + logger.debug(e); return false; } }; diff --git a/x-pack/plugins/cloud_security_posture/server/lib/fleet_util.ts b/x-pack/plugins/cloud_security_posture/server/lib/fleet_util.ts index e482f0af210a4b..9ef90e4175a6c0 100644 --- a/x-pack/plugins/cloud_security_posture/server/lib/fleet_util.ts +++ b/x-pack/plugins/cloud_security_posture/server/lib/fleet_util.ts @@ -12,7 +12,7 @@ import type { AgentService, } from '@kbn/fleet-plugin/server'; import type { - GetAgentPoliciesResponseItem, + GetAgentStatusResponse, PackagePolicy, AgentPolicy, ListResult, @@ -33,22 +33,24 @@ const getPackageNameQuery = (packageName: string, benchmarkFilter?: string): str return kquery; }; -export const addRunningAgentToAgentPolicy = async ( +export type AgentStatusByAgentPolicyMap = Record; + +export const getAgentStatusesByAgentPolicies = async ( agentService: AgentService, - agentPolicies: AgentPolicy[] -): Promise => { - if (!agentPolicies.length) return []; + agentPolicies: AgentPolicy[] | undefined +): Promise => { + if (!agentPolicies?.length) return {}; + + const internalAgentService = agentService.asInternalUser; + const result: AgentStatusByAgentPolicyMap = {}; - return Promise.all( - agentPolicies.map((agentPolicy) => - agentService.asInternalUser - .getAgentStatusForAgentPolicy(agentPolicy.id) - .then((agentStatus) => ({ - ...agentPolicy, - agents: agentStatus.total, - })) - ) - ); + for (const agentPolicy of agentPolicies) { + result[agentPolicy.id] = await internalAgentService.getAgentStatusForAgentPolicy( + agentPolicy.id + ); + } + + return result; }; export const getCspAgentPolicies = async ( @@ -56,7 +58,10 @@ export const getCspAgentPolicies = async ( packagePolicies: PackagePolicy[], agentPolicyService: AgentPolicyServiceInterface ): Promise => - agentPolicyService.getByIds(soClient, uniq(map(packagePolicies, 'policy_id'))); + agentPolicyService.getByIds(soClient, uniq(map(packagePolicies, 'policy_id')), { + withPackagePolicies: true, + ignoreMissing: true, + }); export const getCspPackagePolicies = ( soClient: SavedObjectsClientContract, diff --git a/x-pack/plugins/cloud_security_posture/server/routes/benchmarks/benchmarks.test.ts b/x-pack/plugins/cloud_security_posture/server/routes/benchmarks/benchmarks.test.ts index 258d5c4fdf1366..a950741ea2d8fc 100644 --- a/x-pack/plugins/cloud_security_posture/server/routes/benchmarks/benchmarks.test.ts +++ b/x-pack/plugins/cloud_security_posture/server/routes/benchmarks/benchmarks.test.ts @@ -312,7 +312,6 @@ describe('benchmarks API', () => { it('should build benchmark entry agent policy and package policy', async () => { const packagePolicy = createPackagePolicyMock(); const agentPolicy = createMockAgentPolicy(); - agentPolicy.agents = 3; const cspRulesStatus = { all: 100, @@ -320,7 +319,11 @@ describe('benchmarks API', () => { disabled: 48, }; const enrichAgentPolicy = await createBenchmarkEntry( - agentPolicy, + { + id: agentPolicy.id, + name: agentPolicy.name, + agents: 3, + }, packagePolicy, cspRulesStatus ); diff --git a/x-pack/plugins/cloud_security_posture/server/routes/benchmarks/benchmarks.ts b/x-pack/plugins/cloud_security_posture/server/routes/benchmarks/benchmarks.ts index ef4314d5426266..4bc00f5e0209d3 100644 --- a/x-pack/plugins/cloud_security_posture/server/routes/benchmarks/benchmarks.ts +++ b/x-pack/plugins/cloud_security_posture/server/routes/benchmarks/benchmarks.ts @@ -6,14 +6,14 @@ */ import type { SavedObjectsClientContract, SavedObjectsFindResponse } from '@kbn/core/server'; import { transformError } from '@kbn/securitysolution-es-utils'; -import type { GetAgentPoliciesResponseItem, PackagePolicy } from '@kbn/fleet-plugin/common'; +import type { AgentPolicy, PackagePolicy } from '@kbn/fleet-plugin/common'; import { BENCHMARKS_ROUTE_PATH, CLOUD_SECURITY_POSTURE_PACKAGE_NAME, CSP_RULE_SAVED_OBJECT_TYPE, } from '../../../common/constants'; import { benchmarksQueryParamsSchema } from '../../../common/schemas/benchmark'; -import type { Benchmark, CspRulesStatus } from '../../../common/types'; +import type { Benchmark, CspRulesStatus, AgentPolicyStatus } from '../../../common/types'; import type { CspRule } from '../../../common/schemas'; import { createCspRuleSearchFilterByPackagePolicy, @@ -21,7 +21,8 @@ import { } from '../../../common/utils/helpers'; import { CspRouter } from '../../types'; import { - addRunningAgentToAgentPolicy, + getAgentStatusesByAgentPolicies, + type AgentStatusByAgentPolicyMap, getCspAgentPolicies, getCspPackagePolicies, } from '../../lib/fleet_util'; @@ -74,7 +75,7 @@ export const addPackagePolicyCspRules = async ( }; export const createBenchmarkEntry = ( - agentPolicy: GetAgentPoliciesResponseItem, + agentPolicyStatus: AgentPolicyStatus, packagePolicy: PackagePolicy, cspRulesStatus: CspRulesStatus ): Benchmark => ({ @@ -95,17 +96,14 @@ export const createBenchmarkEntry = ( } : undefined, }, - agent_policy: { - id: agentPolicy.id, - name: agentPolicy.name, - agents: agentPolicy.agents, - }, + agent_policy: agentPolicyStatus, rules: cspRulesStatus, }); const createBenchmarks = ( soClient: SavedObjectsClientContract, - agentPolicies: GetAgentPoliciesResponseItem[], + agentPolicies: AgentPolicy[], + agentStatusByAgentPolicyId: AgentStatusByAgentPolicyMap, cspPackagePolicies: PackagePolicy[] ): Promise => { const cspPackagePoliciesMap = new Map( @@ -113,14 +111,20 @@ const createBenchmarks = ( ); return Promise.all( agentPolicies.flatMap((agentPolicy) => { - const cspPackagesOnAgent = agentPolicy.package_policies - .map((pckPolicyId) => { - if (typeof pckPolicyId === 'string') return cspPackagePoliciesMap.get(pckPolicyId); - }) - .filter(isNonNullable); + const cspPackagesOnAgent = + agentPolicy.package_policies + ?.map(({ id: pckPolicyId }) => { + return cspPackagePoliciesMap.get(pckPolicyId); + }) + .filter(isNonNullable) ?? []; const benchmarks = cspPackagesOnAgent.map(async (cspPackage) => { const cspRulesStatus = await addPackagePolicyCspRules(soClient, cspPackage); - const benchmark = createBenchmarkEntry(agentPolicy, cspPackage, cspRulesStatus); + const agentPolicyStatus = { + id: agentPolicy.id, + name: agentPolicy.name, + agents: agentStatusByAgentPolicyId[agentPolicy.id].total, + }; + const benchmark = createBenchmarkEntry(agentPolicyStatus, cspPackage, cspRulesStatus); return benchmark; }); @@ -159,14 +163,15 @@ export const defineGetBenchmarksRoute = (router: CspRouter): void => cspContext.agentPolicyService ); - const enrichAgentPolicies = await addRunningAgentToAgentPolicy( + const agentStatusesByAgentPolicyId = await getAgentStatusesByAgentPolicies( cspContext.agentService, agentPolicies ); const benchmarks = await createBenchmarks( cspContext.soClient, - enrichAgentPolicies, + agentPolicies, + agentStatusesByAgentPolicyId, cspPackagePolicies.items ); diff --git a/x-pack/plugins/cloud_security_posture/server/routes/configuration/update_rules_configuration.ts b/x-pack/plugins/cloud_security_posture/server/routes/configuration/update_rules_configuration.ts index 463bdab0cdb6e9..6c6358e772e6a2 100644 --- a/x-pack/plugins/cloud_security_posture/server/routes/configuration/update_rules_configuration.ts +++ b/x-pack/plugins/cloud_security_posture/server/routes/configuration/update_rules_configuration.ts @@ -24,8 +24,8 @@ import { createCspRuleSearchFilterByPackagePolicy } from '../../../common/utils/ import type { CspRule, CspRulesConfiguration } from '../../../common/schemas'; import { CLOUD_SECURITY_POSTURE_PACKAGE_NAME, - UPDATE_RULES_CONFIG_ROUTE_PATH, CSP_RULE_SAVED_OBJECT_TYPE, + UPDATE_RULES_CONFIG_ROUTE_PATH, } from '../../../common/constants'; import { CspRouter } from '../../types'; @@ -38,7 +38,7 @@ export const getPackagePolicy = async ( // PackagePolicies always contains one element, even when package does not exist if (!packagePolicies || !packagePolicies[0].version) { - throw new Error(`package policy Id '${packagePolicyId}' is not exist`); + throw new Error(`Package policy Id '${packagePolicyId}' does not exist`); } if (packagePolicies[0].package?.name !== CLOUD_SECURITY_POSTURE_PACKAGE_NAME) { throw new Error( diff --git a/x-pack/plugins/cloud_security_posture/server/routes/setup_routes.ts b/x-pack/plugins/cloud_security_posture/server/routes/setup_routes.ts index 03b42600b92619..436cd9eb7a5269 100644 --- a/x-pack/plugins/cloud_security_posture/server/routes/setup_routes.ts +++ b/x-pack/plugins/cloud_security_posture/server/routes/setup_routes.ts @@ -16,7 +16,7 @@ import { PLUGIN_ID } from '../../common'; import { defineGetComplianceDashboardRoute } from './compliance_dashboard/compliance_dashboard'; import { defineGetBenchmarksRoute } from './benchmarks/benchmarks'; import { defineUpdateRulesConfigRoute } from './configuration/update_rules_configuration'; -import { defineGetCspSetupStatusRoute } from './status/status'; +import { defineGetCspStatusRoute } from './status/status'; import { defineEsPitRoute } from './es_pit/es_pit'; /** @@ -34,7 +34,7 @@ export function setupRoutes({ defineGetComplianceDashboardRoute(router); defineGetBenchmarksRoute(router); defineUpdateRulesConfigRoute(router); - defineGetCspSetupStatusRoute(router); + defineGetCspStatusRoute(router); defineEsPitRoute(router); core.http.registerRouteHandlerContext( diff --git a/x-pack/plugins/cloud_security_posture/server/routes/status/status.test.ts b/x-pack/plugins/cloud_security_posture/server/routes/status/status.test.ts index a67448f05a5ad6..a066b3b409054c 100644 --- a/x-pack/plugins/cloud_security_posture/server/routes/status/status.test.ts +++ b/x-pack/plugins/cloud_security_posture/server/routes/status/status.test.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { defineGetCspSetupStatusRoute, INDEX_TIMEOUT_IN_MINUTES } from './status'; +import { defineGetCspStatusRoute, INDEX_TIMEOUT_IN_MINUTES } from './status'; import { httpServerMock, httpServiceMock } from '@kbn/core/server/mocks'; import type { ESSearchResponse } from '@kbn/core/types/elasticsearch'; import { @@ -79,7 +79,7 @@ describe('CspSetupStatus route', () => { }); it('validate the API route path', async () => { - defineGetCspSetupStatusRoute(router); + defineGetCspStatusRoute(router); const [config, _] = router.get.mock.calls[0]; expect(config.path).toEqual('/internal/cloud_security_posture/status'); @@ -101,7 +101,7 @@ describe('CspSetupStatus route', () => { }); // Act - defineGetCspSetupStatusRoute(router); + defineGetCspStatusRoute(router); const [_, handler] = router.get.mock.calls[0]; const mockResponse = httpServerMock.createResponseFactory(); @@ -116,7 +116,7 @@ describe('CspSetupStatus route', () => { await expect(body).toEqual({ status: 'indexed', latestPackageVersion: '0.0.14', - installedIntegrations: 0, + installedPackagePolicies: 0, healthyAgents: 0, installedPackageVersion: undefined, }); @@ -140,7 +140,7 @@ describe('CspSetupStatus route', () => { }); // Act - defineGetCspSetupStatusRoute(router); + defineGetCspStatusRoute(router); const [_, handler] = router.get.mock.calls[0]; const mockResponse = httpServerMock.createResponseFactory(); @@ -156,7 +156,7 @@ describe('CspSetupStatus route', () => { await expect(body).toEqual({ status: 'indexed', latestPackageVersion: '0.0.14', - installedIntegrations: 3, + installedPackagePolicies: 3, healthyAgents: 0, installedPackageVersion: '0.0.14', }); @@ -188,7 +188,7 @@ describe('CspSetupStatus route', () => { } as unknown as GetAgentStatusResponse['results']); // Act - defineGetCspSetupStatusRoute(router); + defineGetCspStatusRoute(router); const [_, handler] = router.get.mock.calls[0]; const mockResponse = httpServerMock.createResponseFactory(); @@ -204,7 +204,7 @@ describe('CspSetupStatus route', () => { await expect(body).toEqual({ status: 'indexed', latestPackageVersion: '0.0.14', - installedIntegrations: 3, + installedPackagePolicies: 3, healthyAgents: 1, installedPackageVersion: '0.0.14', }); @@ -224,13 +224,13 @@ describe('CspSetupStatus route', () => { page: 1, perPage: 100, }); - - // Act - defineGetCspSetupStatusRoute(router); + defineGetCspStatusRoute(router); const [_, handler] = router.get.mock.calls[0]; const mockResponse = httpServerMock.createResponseFactory(); const mockRequest = httpServerMock.createKibanaRequest(); + + // Act await handler(mockContext, mockRequest, mockResponse); // Assert @@ -242,7 +242,7 @@ describe('CspSetupStatus route', () => { await expect(body).toMatchObject({ status: 'not-installed', latestPackageVersion: '0.0.14', - installedIntegrations: 0, + installedPackagePolicies: 0, healthyAgents: 0, }); }); @@ -273,7 +273,7 @@ describe('CspSetupStatus route', () => { } as unknown as GetAgentStatusResponse['results']); // Act - defineGetCspSetupStatusRoute(router); + defineGetCspStatusRoute(router); const [_, handler] = router.get.mock.calls[0]; @@ -290,7 +290,7 @@ describe('CspSetupStatus route', () => { await expect(body).toMatchObject({ status: 'not-deployed', latestPackageVersion: '0.0.14', - installedIntegrations: 1, + installedPackagePolicies: 1, healthyAgents: 0, installedPackageVersion: '0.0.14', }); @@ -327,7 +327,7 @@ describe('CspSetupStatus route', () => { } as unknown as GetAgentStatusResponse['results']); // Act - defineGetCspSetupStatusRoute(router); + defineGetCspStatusRoute(router); const [_, handler] = router.get.mock.calls[0]; @@ -346,7 +346,7 @@ describe('CspSetupStatus route', () => { await expect(body).toMatchObject({ status: 'indexing', latestPackageVersion: '0.0.14', - installedIntegrations: 1, + installedPackagePolicies: 1, healthyAgents: 1, installedPackageVersion: '0.0.14', }); @@ -383,7 +383,7 @@ describe('CspSetupStatus route', () => { } as unknown as GetAgentStatusResponse['results']); // Act - defineGetCspSetupStatusRoute(router); + defineGetCspStatusRoute(router); const [_, handler] = router.get.mock.calls[0]; @@ -401,7 +401,7 @@ describe('CspSetupStatus route', () => { await expect(body).toMatchObject({ status: 'index-timeout', latestPackageVersion: '0.0.14', - installedIntegrations: 1, + installedPackagePolicies: 1, healthyAgents: 1, installedPackageVersion: '0.0.14', }); diff --git a/x-pack/plugins/cloud_security_posture/server/routes/status/status.ts b/x-pack/plugins/cloud_security_posture/server/routes/status/status.ts index b7deefff368ed0..a85d64e22c9943 100644 --- a/x-pack/plugins/cloud_security_posture/server/routes/status/status.ts +++ b/x-pack/plugins/cloud_security_posture/server/routes/status/status.ts @@ -6,123 +6,119 @@ */ import { transformError } from '@kbn/securitysolution-es-utils'; -import type { Logger, ElasticsearchClient, SavedObjectsClientContract } from '@kbn/core/server'; -import type { - AgentPolicyServiceInterface, - AgentService, - PackagePolicyServiceInterface, - PackageService, -} from '@kbn/fleet-plugin/server'; -import moment, { MomentInput } from 'moment'; +import type { SavedObjectsClientContract } from '@kbn/core/server'; +import type { AgentPolicyServiceInterface, AgentService } from '@kbn/fleet-plugin/server'; +import moment from 'moment'; import { PackagePolicy } from '@kbn/fleet-plugin/common'; import { CLOUD_SECURITY_POSTURE_PACKAGE_NAME, STATUS_ROUTE_PATH } from '../../../common/constants'; -import type { CspRouter } from '../../types'; -import type { CspSetupStatus, Status } from '../../../common/types'; +import type { CspApiRequestHandlerContext, CspRouter } from '../../types'; +import type { CspSetupStatus, CspStatusCode } from '../../../common/types'; import { - addRunningAgentToAgentPolicy, + getAgentStatusesByAgentPolicies, getCspAgentPolicies, getCspPackagePolicies, } from '../../lib/fleet_util'; -import { isLatestFindingsIndexExists } from '../../lib/is_latest_findings_index_exists'; +import { checkForFindings } from '../../lib/check_for_findings'; export const INDEX_TIMEOUT_IN_MINUTES = 10; -// this function currently returns all agents instead of healthy agents only +const calculateDiffFromNowInMinutes = (date: string | number): number => + moment().diff(moment(date), 'minutes'); + const getHealthyAgents = async ( soClient: SavedObjectsClientContract, - installedIntegrations: PackagePolicy[], + installedCspPackagePolicies: PackagePolicy[], agentPolicyService: AgentPolicyServiceInterface, agentService: AgentService ): Promise => { + // Get agent policies of package policies (from installed package policies) const agentPolicies = await getCspAgentPolicies( soClient, - installedIntegrations, + installedCspPackagePolicies, agentPolicyService ); - const enrichedAgentPolicies = await addRunningAgentToAgentPolicy( + // Get agents statuses of the following agent policies + const agentStatusesByAgentPolicyId = await getAgentStatusesByAgentPolicies( agentService, - agentPolicies || [] + agentPolicies ); - return enrichedAgentPolicies.reduce( - (previousValue, currentValue) => previousValue + (currentValue.agents || 0), - 0 - ); + // TODO: should be fixed - currently returns all agents instead of healthy agents only + return Object.values(agentStatusesByAgentPolicyId).reduce((sum, status) => sum + status.total, 0); }; -const getMinutesPassedSinceMoment = (momentInput: MomentInput): number => - moment().diff(moment(momentInput), 'minutes'); - -const getStatus = ( - findingsIndexExists: boolean, - installedIntegrations: number, +const calculateCspStatusCode = ( + hasFindings: boolean, + installedCspPackagePolicies: number, healthyAgents: number, - minutesPassedSinceInstallation: number -): Status => { - if (findingsIndexExists) return 'indexed'; - if (installedIntegrations === 0) return 'not-installed'; + timeSinceInstallationInMinutes: number +): CspStatusCode => { + if (hasFindings) return 'indexed'; + if (installedCspPackagePolicies === 0) return 'not-installed'; if (healthyAgents === 0) return 'not-deployed'; - if (minutesPassedSinceInstallation <= INDEX_TIMEOUT_IN_MINUTES) return 'indexing'; - if (minutesPassedSinceInstallation > INDEX_TIMEOUT_IN_MINUTES) return 'index-timeout'; + if (timeSinceInstallationInMinutes <= INDEX_TIMEOUT_IN_MINUTES) return 'indexing'; + if (timeSinceInstallationInMinutes > INDEX_TIMEOUT_IN_MINUTES) return 'index-timeout'; - throw new Error('Could not determine csp setup status'); + throw new Error('Could not determine csp status'); }; -const getCspSetupStatus = async ( - logger: Logger, - esClient: ElasticsearchClient, - soClient: SavedObjectsClientContract, - packageService: PackageService, - packagePolicyService: PackagePolicyServiceInterface, - agentPolicyService: AgentPolicyServiceInterface, - agentService: AgentService -): Promise => { - const [findingsIndexExists, installationPackageInfo, latestPackageInfo, installedIntegrations] = - await Promise.all([ - isLatestFindingsIndexExists(esClient, logger), +const getCspStatus = async ({ + logger, + esClient, + soClient, + packageService, + packagePolicyService, + agentPolicyService, + agentService, +}: CspApiRequestHandlerContext): Promise => { + const [hasFindings, installation, latestCspPackage, installedPackagePolicies] = await Promise.all( + [ + checkForFindings(esClient.asCurrentUser, true, logger), packageService.asInternalUser.getInstallation(CLOUD_SECURITY_POSTURE_PACKAGE_NAME), packageService.asInternalUser.fetchFindLatestPackage(CLOUD_SECURITY_POSTURE_PACKAGE_NAME), getCspPackagePolicies(soClient, packagePolicyService, CLOUD_SECURITY_POSTURE_PACKAGE_NAME, { per_page: 10000, }), - ]); + ] + ); const healthyAgents = await getHealthyAgents( soClient, - installedIntegrations.items, + installedPackagePolicies.items, agentPolicyService, agentService ); - const installedIntegrationsTotal = installedIntegrations.total; - const latestPackageVersion = latestPackageInfo.version; + const installedPackagePoliciesTotal = installedPackagePolicies.total; + const latestCspPackageVersion = latestCspPackage.version; - const status = getStatus( - findingsIndexExists, - installedIntegrationsTotal, + const MIN_DATE = 0; + const status = calculateCspStatusCode( + hasFindings, + installedPackagePoliciesTotal, healthyAgents, - getMinutesPassedSinceMoment(installationPackageInfo?.install_started_at || 0) + calculateDiffFromNowInMinutes(installation?.install_started_at || MIN_DATE) ); if (status === 'not-installed') return { status, - latestPackageVersion, + latestPackageVersion: latestCspPackageVersion, healthyAgents, - installedIntegrations: installedIntegrationsTotal, + installedPackagePolicies: installedPackagePoliciesTotal, }; return { status, - latestPackageVersion, + latestPackageVersion: latestCspPackageVersion, healthyAgents, - installedIntegrations: installedIntegrationsTotal, - installedPackageVersion: installationPackageInfo?.install_version, + installedPackagePolicies: installedPackagePoliciesTotal, + installedPackageVersion: installation?.install_version, }; }; -export const defineGetCspSetupStatusRoute = (router: CspRouter): void => +export const defineGetCspStatusRoute = (router: CspRouter): void => router.get( { path: STATUS_ROUTE_PATH, @@ -134,25 +130,15 @@ export const defineGetCspSetupStatusRoute = (router: CspRouter): void => async (context, _, response) => { const cspContext = await context.csp; try { - const cspSetupStatus = await getCspSetupStatus( - cspContext.logger, - cspContext.esClient.asCurrentUser, - cspContext.soClient, - cspContext.packageService, - cspContext.packagePolicyService, - cspContext.agentPolicyService, - cspContext.agentService - ); - - const body: CspSetupStatus = cspSetupStatus; - + const status = await getCspStatus(cspContext); return response.ok({ - body, + body: status, }); } catch (err) { - const error = transformError(err); - cspContext.logger.error(`Error while fetching status: ${err}`); + cspContext.logger.error(`Error getting csp status`); + cspContext.logger.error(err); + const error = transformError(err); return response.customError({ body: { message: error.message }, statusCode: error.statusCode, diff --git a/x-pack/plugins/cloud_security_posture/server/types.ts b/x-pack/plugins/cloud_security_posture/server/types.ts index ab77f1090552ae..43f47585d09f65 100644 --- a/x-pack/plugins/cloud_security_posture/server/types.ts +++ b/x-pack/plugins/cloud_security_posture/server/types.ts @@ -54,7 +54,7 @@ export type CspServerPluginStartServices = Promise< [CoreStart, CspServerPluginStartDeps, CspServerPluginStart] >; -interface CspApiRequestHandlerContext { +export interface CspApiRequestHandlerContext { user: ReturnType; logger: Logger; esClient: IScopedClusterClient; diff --git a/x-pack/plugins/encrypted_saved_objects/server/saved_objects/encrypted_saved_objects_client_wrapper.test.ts b/x-pack/plugins/encrypted_saved_objects/server/saved_objects/encrypted_saved_objects_client_wrapper.test.ts index 724178f9b70887..75dd3fdfe8dce2 100644 --- a/x-pack/plugins/encrypted_saved_objects/server/saved_objects/encrypted_saved_objects_client_wrapper.test.ts +++ b/x-pack/plugins/encrypted_saved_objects/server/saved_objects/encrypted_saved_objects_client_wrapper.test.ts @@ -15,11 +15,12 @@ import { EncryptionErrorOperation } from '../crypto/encryption_error'; import { encryptedSavedObjectsServiceMock } from '../crypto/index.mock'; import { EncryptedSavedObjectsClientWrapper } from './encrypted_saved_objects_client_wrapper'; -jest.mock('@kbn/core/server/saved_objects/service/lib/utils', () => { - const { SavedObjectsUtils } = jest.requireActual( - '@kbn/core/server/saved_objects/service/lib/utils' +jest.mock('@kbn/core-saved-objects-utils-server', () => { + const { SavedObjectsUtils, ...actual } = jest.requireActual( + '@kbn/core-saved-objects-utils-server' ); return { + ...actual, SavedObjectsUtils: { namespaceStringToId: SavedObjectsUtils.namespaceStringToId, isRandomId: SavedObjectsUtils.isRandomId, @@ -699,6 +700,7 @@ describe('#bulkUpdate', () => { expectOptionsNamespaceInDescriptor: boolean; expectObjectNamespaceInDescriptor: boolean; } + const doTest = async ({ optionsNamespace, objectNamespace, diff --git a/x-pack/plugins/enterprise_search/common/types/analytics.ts b/x-pack/plugins/enterprise_search/common/types/analytics.ts new file mode 100644 index 00000000000000..e75617645a139c --- /dev/null +++ b/x-pack/plugins/enterprise_search/common/types/analytics.ts @@ -0,0 +1,14 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export interface AnalyticsCollection { + id: string; + name: string; + event_retention_day_length: number; +} + +export type AnalyticsCollectionDocument = Omit; diff --git a/x-pack/plugins/enterprise_search/common/types/error_codes.ts b/x-pack/plugins/enterprise_search/common/types/error_codes.ts index 327d000003f9bb..46a787ae257ec1 100644 --- a/x-pack/plugins/enterprise_search/common/types/error_codes.ts +++ b/x-pack/plugins/enterprise_search/common/types/error_codes.ts @@ -6,6 +6,7 @@ */ export enum ErrorCode { + ANALYTICS_COLLECTION_ALREADY_EXISTS = 'analytics_collection_already_exists', CONNECTOR_DOCUMENT_ALREADY_EXISTS = 'connector_document_already_exists', CRAWLER_ALREADY_EXISTS = 'crawler_already_exists', INDEX_ALREADY_EXISTS = 'index_already_exists', diff --git a/x-pack/plugins/enterprise_search/common/types/indices.ts b/x-pack/plugins/enterprise_search/common/types/indices.ts index 38f4b9873eba2e..08f4125ef8efab 100644 --- a/x-pack/plugins/enterprise_search/common/types/indices.ts +++ b/x-pack/plugins/enterprise_search/common/types/indices.ts @@ -18,6 +18,7 @@ import { Crawler } from './crawler'; export interface ElasticsearchIndex { count: number; // Elasticsearch _count health?: HealthStatus; + hidden: boolean; name: IndexName; status?: IndicesStatsIndexMetadataState; total: { diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/__mocks__/engine_creation_logic.mock.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/__mocks__/engine_creation_logic.mock.ts index 6cfba782698b5c..42e9c546d85aea 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/__mocks__/engine_creation_logic.mock.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/__mocks__/engine_creation_logic.mock.ts @@ -38,6 +38,7 @@ export const mockElasticsearchIndices: ElasticsearchIndexWithPrivileges[] = [ { count: 0, health: 'yellow', + hidden: false, status: 'open', name: 'search-my-index-1', uuid: 'ydlR_QQJTeyZP66tzQSmMQ', @@ -56,6 +57,7 @@ export const mockElasticsearchIndices: ElasticsearchIndexWithPrivileges[] = [ { count: 100, health: 'green', + hidden: false, status: 'open', name: 'my-index-2', uuid: '4dlR_QQJTe2ZP6qtzQSmMQ', @@ -74,6 +76,7 @@ export const mockElasticsearchIndices: ElasticsearchIndexWithPrivileges[] = [ { count: 100, health: 'green', + hidden: false, status: 'open', name: 'search-my-index-2', uuid: '4dlR_QQJTe2ZP6qtzQSmMQ', @@ -92,6 +95,7 @@ export const mockElasticsearchIndices: ElasticsearchIndexWithPrivileges[] = [ { count: 100, health: 'green', + hidden: false, status: 'open', name: 'alias-my-index-2', uuid: '4dlR_QQJTe2ZP6qtzQSmMQ', @@ -110,6 +114,7 @@ export const mockElasticsearchIndices: ElasticsearchIndexWithPrivileges[] = [ { count: 100, health: 'green', + hidden: false, status: 'open', name: 'index-without-read-privilege', uuid: '4dlR_QQJTe2ZP6qtzQSmMQ', @@ -128,6 +133,7 @@ export const mockElasticsearchIndices: ElasticsearchIndexWithPrivileges[] = [ { count: 100, health: 'green', + hidden: false, status: 'open', name: 'index-without-manage-privilege', uuid: '4dlR_QQJTe2ZP6qtzQSmMQ', @@ -146,6 +152,7 @@ export const mockElasticsearchIndices: ElasticsearchIndexWithPrivileges[] = [ { count: 100, health: 'green', + hidden: false, status: 'open', name: 'alias-without-manage-privilege', uuid: '4dlR_QQJTe2ZP6qtzQSmMQ', diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/engine_creation.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/engine_creation.tsx index 95ed3875888f4a..b9fd23ac904f0b 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/engine_creation.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/engine_creation.tsx @@ -12,6 +12,7 @@ import { useLocation } from 'react-router-dom'; import { Location } from 'history'; import { useActions, useValues } from 'kea'; +import { ESINDEX_QUERY_PARAMETER } from '../../../shared/constants'; import { parseQueryParams } from '../../../shared/query_params'; import { ENGINES_TITLE } from '../engines'; import { AppSearchPageTemplate } from '../layout'; @@ -25,15 +26,19 @@ import { SelectEngineType } from './select_engine_type'; export const EngineCreation: React.FC = () => { const { search } = useLocation() as Location; - const { method } = parseQueryParams(search); + const { method, ...params } = parseQueryParams(search); const { engineType, currentEngineCreationStep } = useValues(EngineCreationLogic); - const { setIngestionMethod } = useActions(EngineCreationLogic); + const { setIngestionMethod, initializeWithESIndex } = useActions(EngineCreationLogic); useEffect(() => { if (typeof method === 'string') { setIngestionMethod(method); } + const esIndexParam = params[ESINDEX_QUERY_PARAMETER]; + if (typeof esIndexParam === 'string') { + initializeWithESIndex(esIndexParam); + } }, []); return ( diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/engine_creation_logic.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/engine_creation_logic.ts index dbf7efa907c74e..347846686b5cde 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/engine_creation_logic.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_creation/engine_creation_logic.ts @@ -42,6 +42,7 @@ interface EngineCreationActions { setSelectedIndex(selectedIndexName: string): { selectedIndexName: string }; setEngineType(engineType: EngineType): { engineType: EngineType }; setIsAliasAllowed(isAliasAllowed: boolean): { isAliasAllowed: boolean }; + initializeWithESIndex(indexName: string): { indexName: string }; } interface EngineCreationValues { @@ -82,6 +83,7 @@ export const EngineCreationLogic = kea ({ engineType }), setCreationStep: (currentEngineCreationStep) => currentEngineCreationStep, setIsAliasAllowed: (isAliasAllowed) => ({ isAliasAllowed }), + initializeWithESIndex: (indexName) => ({ indexName }), }, reducers: { ingestionMethod: [ @@ -118,6 +120,10 @@ export const EngineCreationLogic = kea + indexName.length === 0 || indexName.startsWith('search-') + ? '' + : `search-${indexName}-alias`, }, ], isAliasAllowed: [ @@ -145,18 +151,21 @@ export const EngineCreationLogic = kea selectedIndexName, onSubmitError: () => '', + initializeWithESIndex: (_, { indexName }) => indexName, }, ], engineType: [ 'appSearch', { setEngineType: (_, { engineType }) => engineType, + initializeWithESIndex: () => 'elasticsearch', }, ], currentEngineCreationStep: [ EngineCreationSteps.SelectStep, { setCreationStep: (_, currentEngineCreationStep) => currentEngineCreationStep, + initializeWithESIndex: () => EngineCreationSteps.ConfigureStep, }, ], }, diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/__mocks__/search_indices.mock.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/__mocks__/search_indices.mock.ts index ba72c8ada0dd1c..e39ff051f962b7 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/__mocks__/search_indices.mock.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/__mocks__/search_indices.mock.ts @@ -11,6 +11,7 @@ import { ElasticsearchIndexWithIngestion } from '../../../../common/types/indice export const indices: ElasticsearchIndexWithIngestion[] = [ { count: 1, + hidden: false, name: 'api', total: { docs: { @@ -41,6 +42,7 @@ export const indices: ElasticsearchIndexWithIngestion[] = [ sync_now: false, }, count: 1, + hidden: false, name: 'connector', total: { docs: { @@ -56,6 +58,7 @@ export const indices: ElasticsearchIndexWithIngestion[] = [ id: '3', index_name: 'crawler', }, + hidden: false, name: 'crawler', total: { docs: { diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/__mocks__/view_index.mock.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/__mocks__/view_index.mock.ts index 9ade186d55380c..bc226baa77f7fd 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/__mocks__/view_index.mock.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/__mocks__/view_index.mock.ts @@ -20,6 +20,7 @@ export const apiIndex: ApiViewIndex = { ingestionMethod: IngestionMethod.API, ingestionStatus: IngestionStatus.CONNECTED, lastUpdated: null, + hidden: false, name: 'api', total: { docs: { @@ -50,6 +51,7 @@ export const connectorIndex: ConnectorViewIndex = { sync_now: false, }, count: 1, + hidden: false, ingestionMethod: IngestionMethod.CONNECTOR, ingestionStatus: IngestionStatus.INCOMPLETE, lastUpdated: 'never', @@ -68,6 +70,7 @@ export const crawlerIndex: CrawlerViewIndex = { id: '3', index_name: 'crawler', }, + hidden: false, ingestionMethod: IngestionMethod.CRAWLER, ingestionStatus: IngestionStatus.INCOMPLETE, lastUpdated: null, diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/index/delete_index_api_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/index/delete_index_api_logic.test.ts new file mode 100644 index 00000000000000..6eaa5b3e95cf29 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/index/delete_index_api_logic.test.ts @@ -0,0 +1,29 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { mockHttpValues } from '../../../__mocks__/kea_logic'; + +import { nextTick } from '@kbn/test-jest-helpers'; + +import { deleteIndex } from './delete_index_api_logic'; + +describe('deleteIndexApiLogic', () => { + const { http } = mockHttpValues; + beforeEach(() => { + jest.clearAllMocks(); + }); + describe('deleteIndex', () => { + it('calls correct api', async () => { + const promise = Promise.resolve(); + http.post.mockReturnValue(promise); + const result = deleteIndex({ indexName: 'deleteIndex' }); + await nextTick(); + expect(http.delete).toHaveBeenCalledWith('/internal/enterprise_search/indices/deleteIndex'); + await expect(result).resolves; + }); + }); +}); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/index/delete_index_api_logic.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/index/delete_index_api_logic.ts new file mode 100644 index 00000000000000..ff92e4ecef6bc5 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/index/delete_index_api_logic.ts @@ -0,0 +1,21 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { createApiLogic } from '../../../shared/api_logic/create_api_logic'; +import { HttpLogic } from '../../../shared/http'; + +export interface DeleteIndexApiLogicArgs { + indexName: string; +} + +export const deleteIndex = async ({ indexName }: DeleteIndexApiLogicArgs): Promise => { + const route = `/internal/enterprise_search/indices/${indexName}`; + await HttpLogic.values.http.delete(route); + return; +}; + +export const DeleteIndexApiLogic = createApiLogic(['delete_index_api_logic'], deleteIndex); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/index/fetch_indices_api_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/index/fetch_indices_api_logic.test.ts index 13b75e7c534be6..42d78b65df449a 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/index/fetch_indices_api_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/index/fetch_indices_api_logic.test.ts @@ -28,7 +28,12 @@ describe('FetchIndicesApiLogic', () => { expect(http.get).toHaveBeenCalledWith('/internal/enterprise_search/indices', { query: { page: 1, return_hidden_indices: false, search_query: null, size: 20 }, }); - await expect(result).resolves.toEqual({ isInitialRequest: true, result: 'result' }); + await expect(result).resolves.toEqual({ + isInitialRequest: true, + result: 'result', + returnHiddenIndices: false, + searchQuery: undefined, + }); }); it('sets initialRequest to false if page is not the first page', async () => { const promise = Promise.resolve({ result: 'result' }); @@ -41,7 +46,12 @@ describe('FetchIndicesApiLogic', () => { expect(http.get).toHaveBeenCalledWith('/internal/enterprise_search/indices', { query: { page: 2, return_hidden_indices: false, search_query: null, size: 20 }, }); - await expect(result).resolves.toEqual({ isInitialRequest: false, result: 'result' }); + await expect(result).resolves.toEqual({ + isInitialRequest: false, + result: 'result', + returnHiddenIndices: false, + searchQuery: undefined, + }); }); it('sets initialRequest to false if searchQuery is not empty', async () => { const promise = Promise.resolve({ result: 'result' }); @@ -55,7 +65,12 @@ describe('FetchIndicesApiLogic', () => { expect(http.get).toHaveBeenCalledWith('/internal/enterprise_search/indices', { query: { page: 1, return_hidden_indices: false, search_query: 'a', size: 20 }, }); - await expect(result).resolves.toEqual({ isInitialRequest: false, result: 'result' }); + await expect(result).resolves.toEqual({ + isInitialRequest: false, + result: 'result', + returnHiddenIndices: false, + searchQuery: 'a', + }); }); }); }); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/index/fetch_indices_api_logic.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/index/fetch_indices_api_logic.ts index a1ca3a9c3141f5..709c47ed919c0f 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/index/fetch_indices_api_logic.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/index/fetch_indices_api_logic.ts @@ -38,7 +38,7 @@ export const fetchIndices = async ({ // We need this to determine whether to show the empty state on the indices page const isInitialRequest = meta.page.current === 1 && !searchQuery; - return { ...response, isInitialRequest }; + return { ...response, isInitialRequest, returnHiddenIndices, searchQuery }; }; export const FetchIndicesAPILogic = createApiLogic(['content', 'indices_api_logic'], fetchIndices); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/layout/page_template.test.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/layout/page_template.test.tsx index b3aa172dd5bc0b..d7e0f4c2b20e35 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/layout/page_template.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/layout/page_template.test.tsx @@ -13,7 +13,7 @@ import React from 'react'; import { shallow } from 'enzyme'; -import { SetEnterpriseSearchChrome } from '../../../shared/kibana_chrome'; +import { SetEnterpriseSearchContentChrome } from '../../../shared/kibana_chrome'; import { EnterpriseSearchPageTemplateWrapper } from '../../../shared/layout'; import { SendEnterpriseSearchTelemetry } from '../../../shared/telemetry'; @@ -39,7 +39,7 @@ describe('EnterpriseSearchContentPageTemplate', () => { .find(EnterpriseSearchPageTemplateWrapper) .prop('setPageChrome') as any; - expect(setPageChrome.type).toEqual(SetEnterpriseSearchChrome); + expect(setPageChrome.type).toEqual(SetEnterpriseSearchContentChrome); expect(setPageChrome.props.trail).toEqual(['Some page']); }); }); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/layout/page_template.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/layout/page_template.tsx index d512175f2842e5..0bc6dc03c43884 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/layout/page_template.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/layout/page_template.tsx @@ -8,7 +8,7 @@ import React from 'react'; import { ENTERPRISE_SEARCH_CONTENT_PLUGIN } from '../../../../../common/constants'; -import { SetEnterpriseSearchChrome } from '../../../shared/kibana_chrome'; +import { SetEnterpriseSearchContentChrome } from '../../../shared/kibana_chrome'; import { EnterpriseSearchPageTemplateWrapper, PageTemplateProps } from '../../../shared/layout'; import { useEnterpriseSearchNav } from '../../../shared/layout'; import { SendEnterpriseSearchTelemetry } from '../../../shared/telemetry'; @@ -27,7 +27,7 @@ export const EnterpriseSearchContentPageTemplate: React.FC = name: ENTERPRISE_SEARCH_CONTENT_PLUGIN.NAME, }} restrictWidth - setPageChrome={pageChrome && } + setPageChrome={pageChrome && } > {pageViewTelemetry && ( diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/components/client_libraries_popover/popover.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/components/client_libraries_popover/popover.tsx index b89f489952ab87..3ec4cab0a6ff68 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/components/client_libraries_popover/popover.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/components/client_libraries_popover/popover.tsx @@ -14,10 +14,14 @@ import { EuiContextMenuPanel, EuiContextMenuItem, EuiText, + EuiIcon, + EuiFlexItem, + EuiFlexGroup, } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; +import { icons } from '../../../../../../assets/client_libraries'; import { docLinks } from '../../../../../shared/doc_links'; import { OverviewLogic } from '../../overview.logic'; @@ -25,6 +29,7 @@ import { OverviewLogic } from '../../overview.logic'; const libraries = [ { href: docLinks.clientsJavaIntroduction, + icon: icons.java, key: 'java', text: i18n.translate( 'xpack.enterpriseSearch.content.overview.documentExample.clientLibraries.java', @@ -33,6 +38,7 @@ const libraries = [ }, { href: docLinks.clientsJsIntro, + icon: icons.javascript, key: 'javascript', text: i18n.translate( 'xpack.enterpriseSearch.content.overview.documentExample.clientLibraries.javascript', @@ -41,6 +47,7 @@ const libraries = [ }, { href: docLinks.clientsRubyOverview, + icon: icons.ruby, key: 'ruby', text: i18n.translate( 'xpack.enterpriseSearch.content.overview.documentExample.clientLibraries.ruby', @@ -49,6 +56,7 @@ const libraries = [ }, { href: docLinks.clientsGoIndex, + icon: icons.go, key: 'go', text: i18n.translate( 'xpack.enterpriseSearch.content.overview.documentExample.clientLibraries.go', @@ -57,6 +65,7 @@ const libraries = [ }, { href: docLinks.clientsNetIntroduction, + icon: icons.dotnet, key: 'dotnet', text: i18n.translate( 'xpack.enterpriseSearch.content.overview.documentExample.clientLibraries.dotnet', @@ -65,6 +74,7 @@ const libraries = [ }, { href: docLinks.clientsPhpGuide, + icon: icons.php, key: 'php', text: i18n.translate( 'xpack.enterpriseSearch.content.overview.documentExample.clientLibraries.php', @@ -73,6 +83,7 @@ const libraries = [ }, { href: docLinks.clientsPerlGuide, + icon: icons.perl, key: 'perl', text: i18n.translate( 'xpack.enterpriseSearch.content.overview.documentExample.clientLibraries.perl', @@ -81,6 +92,7 @@ const libraries = [ }, { href: docLinks.clientsPythonOverview, + icon: icons.python, key: 'python', text: i18n.translate( 'xpack.enterpriseSearch.content.overview.documentExample.clientLibraries.python', @@ -89,6 +101,7 @@ const libraries = [ }, { href: docLinks.clientsRustOverview, + icon: icons.rust, key: 'rust', text: i18n.translate( 'xpack.enterpriseSearch.content.overview.documentExample.clientLibraries.rust', @@ -116,15 +129,25 @@ export const ClientLibrariesPopover: React.FC = () => { > { - return ( - - -

{item.text}

-
-
- ); - })} + items={libraries.map((item) => ( + : undefined} + > + + + +

{item.text}

+
+
+ + + +
+
+ ))} /> ); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/components/header_actions/create_engine_menu_item.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/components/header_actions/create_engine_menu_item.tsx new file mode 100644 index 00000000000000..a5667327a8208a --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/components/header_actions/create_engine_menu_item.tsx @@ -0,0 +1,63 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; + +import { EuiBetaBadge, EuiContextMenuItem, EuiText, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; + +import { i18n } from '@kbn/i18n'; + +import { APP_SEARCH_PLUGIN } from '../../../../../../../common/constants'; +import { ENGINE_CREATION_PATH } from '../../../../../app_search/routes'; +import { ESINDEX_QUERY_PARAMETER } from '../../../../../shared/constants'; +import { generateEncodedPath } from '../../../../../shared/encode_path_params'; +import { KibanaLogic } from '../../../../../shared/kibana'; + +export interface CreateEngineMenuItemProps { + indexName?: string; + isHiddenIndex?: boolean; +} + +export const CreateEngineMenuItem: React.FC = ({ + indexName, + isHiddenIndex, +}) => { + const engineCreationPath = !indexName + ? `${APP_SEARCH_PLUGIN.URL}${ENGINE_CREATION_PATH}` + : generateEncodedPath(`${APP_SEARCH_PLUGIN.URL}${ENGINE_CREATION_PATH}?:indexKey=:indexName`, { + indexKey: ESINDEX_QUERY_PARAMETER, + indexName, + }); + + return ( + + + { + KibanaLogic.values.navigateToUrl(engineCreationPath, { + shouldNotCreateHref: true, + }); + }} + disabled={isHiddenIndex} + > + +

+ {i18n.translate('xpack.enterpriseSearch.content.index.searchEngines.createEngine', { + defaultMessage: 'Create an App Search engine', + })} +

+
+
+
+ + + +
+ ); +}; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/components/header_actions/header_actions.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/components/header_actions/header_actions.tsx index 3809483e053e70..9f04dd7ba16ce5 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/components/header_actions/header_actions.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/components/header_actions/header_actions.tsx @@ -18,5 +18,5 @@ import { SyncButton } from './sync_button'; export const getHeaderActions = (indexData?: ElasticsearchIndexWithIngestion) => [ ...(isCrawlerIndex(indexData) ? [] : []), ...(isConnectorIndex(indexData) ? [] : []), - , + , ]; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/components/header_actions/search_engines_popover.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/components/header_actions/search_engines_popover.tsx index d535d37a4a8ee8..2ac1682f8676cb 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/components/header_actions/search_engines_popover.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/components/header_actions/search_engines_popover.tsx @@ -15,17 +15,26 @@ import { EuiContextMenuPanel, EuiContextMenuItem, EuiText, + EuiToolTip, } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { APP_SEARCH_PLUGIN } from '../../../../../../../common/constants'; -import { ENGINE_CREATION_PATH } from '../../../../../app_search/routes'; import { KibanaLogic } from '../../../../../shared/kibana'; +import { CreateEngineMenuItem } from './create_engine_menu_item'; import { SearchEnginesPopoverLogic } from './search_engines_popover_logic'; -export const SearchEnginesPopover: React.FC = () => { +export interface SearchEnginesPopoverProps { + indexName?: string; + isHiddenIndex?: boolean; +} + +export const SearchEnginesPopover: React.FC = ({ + indexName, + isHiddenIndex, +}) => { const { isSearchEnginesPopoverOpen } = useValues(SearchEnginesPopoverLogic); const { toggleSearchEnginesPopover } = useActions(SearchEnginesPopoverLogic); @@ -60,22 +69,20 @@ export const SearchEnginesPopover: React.FC = () => {

, - { - KibanaLogic.values.navigateToUrl(APP_SEARCH_PLUGIN.URL + ENGINE_CREATION_PATH, { - shouldNotCreateHref: true, - }); - }} - > - -

- {i18n.translate('xpack.enterpriseSearch.content.index.searchEngines.createEngine', { - defaultMessage: 'Create a new App Search engine', - })} -

-
-
, + isHiddenIndex ? ( + + ) : ( + + ), ]} /> diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_indices/delete_index_modal.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_indices/delete_index_modal.tsx new file mode 100644 index 00000000000000..6dbb44d658b8c0 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_indices/delete_index_modal.tsx @@ -0,0 +1,69 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; + +import { useActions, useValues } from 'kea'; + +import { EuiConfirmModal } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; + +import { ingestionMethodToText } from '../../utils/indices'; + +import { IndicesLogic } from './indices_logic'; + +export const DeleteIndexModal: React.FC = () => { + const { closeDeleteModal, deleteIndex } = useActions(IndicesLogic); + const { + deleteModalIndexName: indexName, + deleteModalIngestionMethod: ingestionMethod, + isDeleteModalVisible, + } = useValues(IndicesLogic); + return isDeleteModalVisible ? ( + { + closeDeleteModal(); + }} + onConfirm={() => { + deleteIndex({ indexName }); + }} + cancelButtonText={i18n.translate( + 'xpack.enterpriseSearch.content.searchIndices.deleteModal.cancelButton.title', + { + defaultMessage: 'Cancel', + } + )} + confirmButtonText={i18n.translate( + 'xpack.enterpriseSearch.content.searchIndices.deleteModal.confirmButton.title', + { + defaultMessage: 'Delete index', + } + )} + defaultFocusedButton="confirm" + buttonColor="danger" + > +

+ {i18n.translate( + 'xpack.enterpriseSearch.content.searchIndices.deleteModal.delete.description', + { + defaultMessage: + 'Deleting this index will also delete all of its data and its {ingestionMethod} configuration. Any associated search engines will no longer be able to access any data stored in this index.This can not be undone.', + values: { + ingestionMethod: ingestionMethodToText(ingestionMethod), + }, + } + )} +

+
+ ) : ( + <> + ); +}; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_indices/indices_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_indices/indices_logic.test.ts index 36157301d3bae3..a636199dd1e471 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_indices/indices_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_indices/indices_logic.test.ts @@ -22,17 +22,22 @@ import { DEFAULT_META } from '../../../shared/constants'; import { FetchIndicesAPILogic } from '../../api/index/fetch_indices_api_logic'; -import { IngestionStatus } from '../../types'; +import { IngestionMethod, IngestionStatus } from '../../types'; import { IndicesLogic } from './indices_logic'; const DEFAULT_VALUES = { data: undefined, + deleteModalIndex: null, + deleteModalIndexName: '', + deleteModalIngestionMethod: IngestionMethod.API, hasNoIndices: false, indices: [], + isDeleteModalVisible: false, isFirstRequest: true, isLoading: true, meta: DEFAULT_META, + searchParams: { meta: DEFAULT_META, returnHiddenIndices: false }, status: Status.IDLE, }; @@ -64,11 +69,77 @@ describe('IndicesLogic', () => { current: 3, }, }, + searchParams: { + ...DEFAULT_VALUES.searchParams, + meta: { page: { ...DEFAULT_META.page, current: 3 } }, + }, }); }); }); + describe('openDeleteModal', () => { + it('should set deleteIndexName and set isDeleteModalVisible to true', () => { + IndicesLogic.actions.openDeleteModal(connectorIndex); + expect(IndicesLogic.values).toEqual({ + ...DEFAULT_VALUES, + deleteModalIndex: connectorIndex, + deleteModalIndexName: 'connector', + deleteModalIngestionMethod: IngestionMethod.CONNECTOR, + isDeleteModalVisible: true, + }); + }); + }); + describe('closeDeleteModal', () => { + it('should set deleteIndexName to empty and set isDeleteModalVisible to false', () => { + IndicesLogic.actions.openDeleteModal(connectorIndex); + IndicesLogic.actions.closeDeleteModal(); + expect(IndicesLogic.values).toEqual(DEFAULT_VALUES); + }); + }); }); describe('reducers', () => { + describe('isFirstRequest', () => { + it('should update to true on setIsFirstRequest', () => { + IndicesLogic.actions.setIsFirstRequest(); + expect(IndicesLogic.values).toEqual({ ...DEFAULT_VALUES, isFirstRequest: true }); + }); + it('should update to false on apiError', () => { + IndicesLogic.actions.setIsFirstRequest(); + IndicesLogic.actions.apiError({} as HttpError); + + expect(IndicesLogic.values).toEqual({ + ...DEFAULT_VALUES, + hasNoIndices: false, + indices: [], + isFirstRequest: false, + isLoading: false, + status: Status.ERROR, + }); + }); + it('should update to false on apiSuccess', () => { + IndicesLogic.actions.setIsFirstRequest(); + IndicesLogic.actions.apiSuccess({ + indices: [], + isInitialRequest: false, + meta: DEFAULT_VALUES.meta, + returnHiddenIndices: false, + }); + + expect(IndicesLogic.values).toEqual({ + ...DEFAULT_VALUES, + data: { + indices: [], + isInitialRequest: false, + meta: DEFAULT_VALUES.meta, + returnHiddenIndices: false, + }, + hasNoIndices: false, + indices: [], + isFirstRequest: false, + isLoading: false, + status: Status.SUCCESS, + }); + }); + }); describe('meta', () => { it('updates when apiSuccess listener triggered', () => { const newMeta = { @@ -84,18 +155,28 @@ describe('IndicesLogic', () => { indices, isInitialRequest: true, meta: newMeta, + returnHiddenIndices: true, + searchQuery: 'a', }); expect(IndicesLogic.values).toEqual({ + ...DEFAULT_VALUES, data: { indices, isInitialRequest: true, meta: newMeta, + returnHiddenIndices: true, + searchQuery: 'a', }, hasNoIndices: false, indices: elasticsearchViewIndices, isFirstRequest: false, isLoading: false, meta: newMeta, + searchParams: { + meta: newMeta, + returnHiddenIndices: true, + searchQuery: 'a', + }, status: Status.SUCCESS, }); }); @@ -115,18 +196,25 @@ describe('IndicesLogic', () => { indices: [], isInitialRequest: true, meta, + returnHiddenIndices: false, }); expect(IndicesLogic.values).toEqual({ + ...DEFAULT_VALUES, data: { indices: [], isInitialRequest: true, meta, + returnHiddenIndices: false, }, hasNoIndices: true, indices: [], isFirstRequest: false, isLoading: false, meta, + searchParams: { + ...DEFAULT_VALUES.searchParams, + meta, + }, status: Status.SUCCESS, }); }); @@ -144,18 +232,25 @@ describe('IndicesLogic', () => { indices: [], isInitialRequest: false, meta, + returnHiddenIndices: false, }); expect(IndicesLogic.values).toEqual({ + ...DEFAULT_VALUES, data: { indices: [], isInitialRequest: false, meta, + returnHiddenIndices: false, }, hasNoIndices: false, indices: [], isFirstRequest: false, isLoading: false, meta, + searchParams: { + ...DEFAULT_VALUES.searchParams, + meta, + }, status: Status.SUCCESS, }); }); @@ -172,6 +267,21 @@ describe('IndicesLogic', () => { expect(mockFlashMessageHelpers.flashAPIErrors).toHaveBeenCalledTimes(1); expect(mockFlashMessageHelpers.flashAPIErrors).toHaveBeenCalledWith({}); }); + it('calls flashAPIErrors on deleteError', () => { + IndicesLogic.actions.deleteError({} as HttpError); + expect(mockFlashMessageHelpers.flashAPIErrors).toHaveBeenCalledTimes(1); + expect(mockFlashMessageHelpers.flashAPIErrors).toHaveBeenCalledWith({}); + }); + it('calls flashSuccessToast, closeDeleteModal and fetchIndices on deleteSuccess', () => { + IndicesLogic.actions.fetchIndices = jest.fn(); + IndicesLogic.actions.closeDeleteModal = jest.fn(); + IndicesLogic.actions.deleteSuccess(); + expect(mockFlashMessageHelpers.flashSuccessToast).toHaveBeenCalledTimes(1); + expect(IndicesLogic.actions.fetchIndices).toHaveBeenCalledWith( + IndicesLogic.values.searchParams + ); + expect(IndicesLogic.actions.closeDeleteModal).toHaveBeenCalled(); + }); it('calls makeRequest on fetchIndices', async () => { jest.useFakeTimers(); IndicesLogic.actions.makeRequest = jest.fn(); @@ -223,13 +333,16 @@ describe('IndicesLogic', () => { indices: elasticsearchViewIndices, isInitialRequest: true, meta: DEFAULT_META, + returnHiddenIndices: false, }); expect(IndicesLogic.values).toEqual({ + ...DEFAULT_VALUES, data: { indices: elasticsearchViewIndices, isInitialRequest: true, meta: DEFAULT_META, + returnHiddenIndices: false, }, hasNoIndices: false, indices: elasticsearchViewIndices, @@ -256,9 +369,11 @@ describe('IndicesLogic', () => { ], isInitialRequest: true, meta: DEFAULT_META, + returnHiddenIndices: false, }); expect(IndicesLogic.values).toEqual({ + ...DEFAULT_VALUES, data: { indices: [ { @@ -272,6 +387,7 @@ describe('IndicesLogic', () => { ], isInitialRequest: true, meta: DEFAULT_META, + returnHiddenIndices: false, }, hasNoIndices: false, indices: [ @@ -302,9 +418,11 @@ describe('IndicesLogic', () => { ], isInitialRequest: true, meta: DEFAULT_META, + returnHiddenIndices: false, }); expect(IndicesLogic.values).toEqual({ + ...DEFAULT_VALUES, data: { indices: [ { @@ -314,6 +432,7 @@ describe('IndicesLogic', () => { ], isInitialRequest: true, meta: DEFAULT_META, + returnHiddenIndices: false, }, hasNoIndices: false, indices: [ @@ -343,9 +462,11 @@ describe('IndicesLogic', () => { ], isInitialRequest: true, meta: DEFAULT_META, + returnHiddenIndices: false, }); expect(IndicesLogic.values).toEqual({ + ...DEFAULT_VALUES, data: { indices: [ { @@ -355,6 +476,7 @@ describe('IndicesLogic', () => { ], isInitialRequest: true, meta: DEFAULT_META, + returnHiddenIndices: false, }, hasNoIndices: false, indices: [ @@ -385,9 +507,11 @@ describe('IndicesLogic', () => { ], isInitialRequest: true, meta: DEFAULT_META, + returnHiddenIndices: false, }); expect(IndicesLogic.values).toEqual({ + ...DEFAULT_VALUES, data: { indices: [ { @@ -401,6 +525,7 @@ describe('IndicesLogic', () => { ], isInitialRequest: true, meta: DEFAULT_META, + returnHiddenIndices: false, }, hasNoIndices: false, indices: [ diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_indices/indices_logic.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_indices/indices_logic.ts index 59640a948ddbc5..5b90b26dba002b 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_indices/indices_logic.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_indices/indices_logic.ts @@ -7,15 +7,26 @@ import { kea, MakeLogicType } from 'kea'; +import { i18n } from '@kbn/i18n'; + import { Meta } from '../../../../../common/types'; import { HttpError, Status } from '../../../../../common/types/api'; import { ElasticsearchIndexWithIngestion } from '../../../../../common/types/indices'; +import { Actions } from '../../../shared/api_logic/create_api_logic'; import { DEFAULT_META } from '../../../shared/constants'; -import { flashAPIErrors, clearFlashMessages } from '../../../shared/flash_messages'; +import { + flashAPIErrors, + clearFlashMessages, + flashSuccessToast, +} from '../../../shared/flash_messages'; import { updateMetaPageIndex } from '../../../shared/table_pagination'; +import { + DeleteIndexApiLogic, + DeleteIndexApiLogicArgs, +} from '../../api/index/delete_index_api_logic'; import { FetchIndicesAPILogic } from '../../api/index/fetch_indices_api_logic'; -import { ElasticsearchViewIndex } from '../../types'; -import { indexToViewIndex } from '../../utils/indices'; +import { ElasticsearchViewIndex, IngestionMethod } from '../../types'; +import { getIngestionMethod, indexToViewIndex } from '../../utils/indices'; export interface IndicesActions { apiError(error: HttpError): HttpError; @@ -23,15 +34,25 @@ export interface IndicesActions { indices, isInitialRequest, meta, + returnHiddenIndices, + searchQuery, }: { indices: ElasticsearchIndexWithIngestion[]; isInitialRequest: boolean; meta: Meta; + returnHiddenIndices: boolean; + searchQuery?: string; }): { indices: ElasticsearchIndexWithIngestion[]; isInitialRequest: boolean; meta: Meta; + returnHiddenIndices: boolean; + searchQuery?: string; }; + closeDeleteModal(): void; + deleteError: Actions['apiError']; + deleteIndex: Actions['makeRequest']; + deleteSuccess: Actions['apiSuccess']; fetchIndices({ meta, returnHiddenIndices, @@ -43,34 +64,61 @@ export interface IndicesActions { }): { meta: Meta; returnHiddenIndices: boolean; searchQuery?: string }; makeRequest: typeof FetchIndicesAPILogic.actions.makeRequest; onPaginate(newPageIndex: number): { newPageIndex: number }; - setIsFirstRequest(): boolean; + openDeleteModal(index: ElasticsearchViewIndex): { index: ElasticsearchViewIndex }; + setIsFirstRequest(): void; } export interface IndicesValues { data: typeof FetchIndicesAPILogic.values.data; + deleteModalIndex: ElasticsearchViewIndex | null; + deleteModalIndexName: string; + deleteModalIngestionMethod: IngestionMethod; hasNoIndices: boolean; indices: ElasticsearchViewIndex[]; + isDeleteModalVisible: boolean; isFirstRequest: boolean; isLoading: boolean; meta: Meta; + searchParams: { meta: Meta; returnHiddenIndices: boolean; searchQuery?: string }; status: typeof FetchIndicesAPILogic.values.status; } export const IndicesLogic = kea>({ actions: { + closeDeleteModal: true, fetchIndices: ({ meta, returnHiddenIndices, searchQuery }) => ({ meta, returnHiddenIndices, searchQuery, }), onPaginate: (newPageIndex) => ({ newPageIndex }), - setIsFirstRequest: () => true, + openDeleteModal: (index) => ({ index }), + setIsFirstRequest: true, }, connect: { - actions: [FetchIndicesAPILogic, ['makeRequest', 'apiSuccess', 'apiError']], + actions: [ + FetchIndicesAPILogic, + ['makeRequest', 'apiSuccess', 'apiError'], + DeleteIndexApiLogic, + ['apiError as deleteError', 'apiSuccess as deleteSuccess', 'makeRequest as deleteIndex'], + ], values: [FetchIndicesAPILogic, ['data', 'status']], }, - listeners: ({ actions }) => ({ + listeners: ({ actions, values }) => ({ apiError: (e) => flashAPIErrors(e), + deleteError: (e) => flashAPIErrors(e), + deleteSuccess: () => { + flashSuccessToast( + i18n.translate('xpack.enterpriseSearch.content.indices.deleteIndex.successToast.title', { + defaultMessage: + 'Your index {indexName} and any associated ingestion configurations were successfully deleted', + values: { + indexName: values.deleteModalIndexName, + }, + }) + ); + actions.closeDeleteModal(); + actions.fetchIndices(values.searchParams); + }, fetchIndices: async (input, breakpoint) => { await breakpoint(150); actions.makeRequest(input); @@ -79,6 +127,20 @@ export const IndicesLogic = kea>({ }), path: ['enterprise_search', 'content', 'indices_logic'], reducers: () => ({ + deleteModalIndex: [ + null, + { + closeDeleteModal: () => null, + openDeleteModal: (_, { index }) => index, + }, + ], + isDeleteModalVisible: [ + false, + { + closeDeleteModal: () => false, + openDeleteModal: () => true, + }, + ], isFirstRequest: [ true, { @@ -87,15 +149,28 @@ export const IndicesLogic = kea>({ setIsFirstRequest: () => true, }, ], - meta: [ - DEFAULT_META, + searchParams: [ + { meta: DEFAULT_META, returnHiddenIndices: false }, { - apiSuccess: (_, { meta }) => meta, - onPaginate: (state, { newPageIndex }) => updateMetaPageIndex(state, newPageIndex), + apiSuccess: (_, { meta, returnHiddenIndices, searchQuery }) => ({ + meta, + returnHiddenIndices, + searchQuery, + }), + onPaginate: (state, { newPageIndex }) => ({ + ...state, + meta: updateMetaPageIndex(state.meta, newPageIndex), + }), }, ], }), selectors: ({ selectors }) => ({ + deleteModalIndexName: [() => [selectors.deleteModalIndex], (index) => index?.name ?? ''], + deleteModalIngestionMethod: [ + () => [selectors.deleteModalIndex], + (index: ElasticsearchViewIndex | null) => + index ? getIngestionMethod(index) : IngestionMethod.API, + ], hasNoIndices: [ // We need this to show the landing page on the overview page if there are no indices // We can't rely just on there being no indices, because user might have entered a search query @@ -110,5 +185,6 @@ export const IndicesLogic = kea>({ () => [selectors.status, selectors.isFirstRequest], (status, isFirstRequest) => [Status.LOADING, Status.IDLE].includes(status) && isFirstRequest, ], + meta: [() => [selectors.searchParams], (searchParams) => searchParams.meta], }), }); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_indices/indices_table.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_indices/indices_table.tsx index d68ce14b1b1838..8ff7550b61ffda 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_indices/indices_table.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_indices/indices_table.tsx @@ -7,6 +7,8 @@ import React from 'react'; +import { useValues } from 'kea'; + import { CriteriaWithPagination, EuiBasicTable, @@ -18,7 +20,8 @@ import { i18n } from '@kbn/i18n'; import { Meta } from '../../../../../common/types'; import { generateEncodedPath } from '../../../shared/encode_path_params'; -import { EuiLinkTo, EuiButtonIconTo } from '../../../shared/react_router_helpers'; +import { KibanaLogic } from '../../../shared/kibana'; +import { EuiLinkTo } from '../../../shared/react_router_helpers'; import { EuiBadgeTo } from '../../../shared/react_router_helpers/eui_components'; import { convertMetaToPagination } from '../../../shared/table_pagination'; import { SEARCH_INDEX_PATH } from '../../routes'; @@ -37,122 +40,12 @@ const healthColorsMap = { yellow: 'warning', }; -const columns: Array> = [ - { - field: 'name', - name: i18n.translate('xpack.enterpriseSearch.content.searchIndices.name.columnTitle', { - defaultMessage: 'Index name', - }), - render: (name: string) => ( - - {name} - - ), - sortable: true, - truncateText: true, - width: '40%', - }, - { - field: 'health', - name: i18n.translate('xpack.enterpriseSearch.content.searchIndices.health.columnTitle', { - defaultMessage: 'Index health', - }), - render: (health: 'red' | 'green' | 'yellow' | 'unavailable') => ( - - -  {health ?? '-'} - - ), - sortable: true, - truncateText: true, - width: '10%', - }, - { - field: 'count', - name: i18n.translate('xpack.enterpriseSearch.content.searchIndices.docsCount.columnTitle', { - defaultMessage: 'Docs count', - }), - sortable: true, - truncateText: true, - width: '10%', - }, - { - field: 'ingestionMethod', - name: i18n.translate( - 'xpack.enterpriseSearch.content.searchIndices.ingestionMethod.columnTitle', - { - defaultMessage: 'Ingestion method', - } - ), - render: (ingestionMethod: IngestionMethod) => ( - {ingestionMethodToText(ingestionMethod)} - ), - truncateText: true, - width: '10%', - }, - { - name: i18n.translate( - 'xpack.enterpriseSearch.content.searchIndices.ingestionStatus.columnTitle', - { - defaultMessage: 'Ingestion status', - } - ), - render: (index: ElasticsearchViewIndex) => { - const overviewPath = generateEncodedPath(SEARCH_INDEX_PATH, { indexName: index.name }); - if (isCrawlerIndex(index)) { - const label = crawlerStatusToText(index.crawler?.most_recent_crawl_request_status); - - return ( - - ); - } else { - const label = ingestionStatusToText(index.ingestionStatus); - return ( - - ); - } - }, - truncateText: true, - width: '10%', - }, - { - actions: [ - { - render: ({ name }) => ( - - ), - }, - ], - name: i18n.translate('xpack.enterpriseSearch.content.searchIndices.actions.columnTitle', { - defaultMessage: 'Actions', - }), - width: '5%', - }, -]; - interface IndicesTableProps { indices: ElasticsearchViewIndex[]; isLoading?: boolean; meta: Meta; onChange: (criteria: CriteriaWithPagination) => void; + onDelete: (index: ElasticsearchViewIndex) => void; } export const IndicesTable: React.FC = ({ @@ -160,13 +53,138 @@ export const IndicesTable: React.FC = ({ isLoading, meta, onChange, -}) => ( - -); + onDelete, +}) => { + const { navigateToUrl } = useValues(KibanaLogic); + const columns: Array> = [ + { + field: 'name', + name: i18n.translate('xpack.enterpriseSearch.content.searchIndices.name.columnTitle', { + defaultMessage: 'Index name', + }), + render: (name: string) => ( + + {name} + + ), + sortable: true, + truncateText: true, + width: '40%', + }, + { + field: 'health', + name: i18n.translate('xpack.enterpriseSearch.content.searchIndices.health.columnTitle', { + defaultMessage: 'Index health', + }), + render: (health: 'red' | 'green' | 'yellow' | 'unavailable') => ( + + +  {health ?? '-'} + + ), + sortable: true, + truncateText: true, + width: '10%', + }, + { + field: 'count', + name: i18n.translate('xpack.enterpriseSearch.content.searchIndices.docsCount.columnTitle', { + defaultMessage: 'Docs count', + }), + sortable: true, + truncateText: true, + width: '10%', + }, + { + field: 'ingestionMethod', + name: i18n.translate( + 'xpack.enterpriseSearch.content.searchIndices.ingestionMethod.columnTitle', + { + defaultMessage: 'Ingestion method', + } + ), + render: (ingestionMethod: IngestionMethod) => ( + {ingestionMethodToText(ingestionMethod)} + ), + truncateText: true, + width: '10%', + }, + { + name: i18n.translate( + 'xpack.enterpriseSearch.content.searchIndices.ingestionStatus.columnTitle', + { + defaultMessage: 'Ingestion status', + } + ), + render: (index: ElasticsearchViewIndex) => { + const overviewPath = generateEncodedPath(SEARCH_INDEX_PATH, { indexName: index.name }); + if (isCrawlerIndex(index)) { + const label = crawlerStatusToText(index.crawler?.most_recent_crawl_request_status); + + return ( + + ); + } else { + const label = ingestionStatusToText(index.ingestionStatus); + return ( + + ); + } + }, + truncateText: true, + width: '15%', + }, + { + actions: [ + { + description: 'View this index', + icon: 'eye', + isPrimary: false, + name: (index) => `View ${index.name}`, + onClick: (index) => + navigateToUrl( + generateEncodedPath(SEARCH_INDEX_PATH, { + indexName: index.name, + }) + ), + type: 'icon', + }, + { + available: (index) => !isCrawlerIndex(index), + color: 'danger', + description: 'Delete this index', + icon: 'trash', + isPrimary: false, + name: (index) => `Delete ${index.name}`, + onClick: (index) => onDelete(index), + type: 'icon', + }, + ], + name: i18n.translate('xpack.enterpriseSearch.content.searchIndices.actions.columnTitle', { + defaultMessage: 'Actions', + }), + width: '10%', + }, + ]; + return ( + + ); +}; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_indices/search_indices.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_indices/search_indices.tsx index 96019c8139c978..f2efea5ef1e51a 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_indices/search_indices.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_indices/search_indices.tsx @@ -34,22 +34,20 @@ import { useLocalStorage } from '../../../shared/use_local_storage'; import { NEW_INDEX_PATH } from '../../routes'; import { EnterpriseSearchContentPageTemplate } from '../layout/page_template'; +import { DeleteIndexModal } from './delete_index_modal'; import { IndicesLogic } from './indices_logic'; import { IndicesTable } from './indices_table'; import './search_indices.scss'; export const baseBreadcrumbs = [ - i18n.translate('xpack.enterpriseSearch.content.searchIndices.content.breadcrumb', { - defaultMessage: 'Content', - }), i18n.translate('xpack.enterpriseSearch.content.searchIndices.searchIndices.breadcrumb', { defaultMessage: 'Elasticsearch indices', }), ]; export const SearchIndices: React.FC = () => { - const { fetchIndices, onPaginate, setIsFirstRequest } = useActions(IndicesLogic); + const { fetchIndices, onPaginate, openDeleteModal, setIsFirstRequest } = useActions(IndicesLogic); const { meta, indices, hasNoIndices, isLoading } = useValues(IndicesLogic); const [showHiddenIndices, setShowHiddenIndices] = useState(false); const [searchQuery, setSearchValue] = useState(''); @@ -85,6 +83,7 @@ export const SearchIndices: React.FC = () => { return ( <> + { - + ) : ( diff --git a/x-pack/plugins/enterprise_search/public/applications/index.test.tsx b/x-pack/plugins/enterprise_search/public/applications/index.test.tsx index c8722adfebbd28..455707779e739e 100644 --- a/x-pack/plugins/enterprise_search/public/applications/index.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/index.test.tsx @@ -7,6 +7,7 @@ import React from 'react'; +import { act } from '@testing-library/react'; import { getContext } from 'kea'; import { chartPluginMock } from '@kbn/charts-plugin/public/mocks'; @@ -47,7 +48,7 @@ describe('renderApp', () => { const unmount = renderApp(MockApp, kibanaDeps, pluginData); expect(mockContainer.querySelector('.hello-world')).not.toBeNull(); - unmount(); + act(() => unmount()); expect(mockContainer.innerHTML).toEqual(''); }); @@ -60,20 +61,30 @@ describe('renderApp', () => { }; describe('Enterprise Search apps', () => { - afterEach(() => unmount()); + afterEach(() => { + act(() => { + unmount(); + }); + }); it('renders EnterpriseSearchOverview', () => { - mount(EnterpriseSearchOverview); + act(() => { + mount(EnterpriseSearchOverview); + }); expect(mockContainer.querySelector('.kbnPageTemplate')).not.toBeNull(); }); it('renders AppSearch', () => { - mount(AppSearch); + act(() => { + mount(AppSearch); + }); expect(mockContainer.querySelector('.setupGuide')).not.toBeNull(); }); it('renders WorkplaceSearch', () => { - mount(WorkplaceSearch); + act(() => { + mount(WorkplaceSearch); + }); expect(mockContainer.querySelector('.setupGuide')).not.toBeNull(); }); }); diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/constants/index.ts b/x-pack/plugins/enterprise_search/public/applications/shared/constants/index.ts index 6075f6e9822d3e..fa9eb67cf9fe49 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/constants/index.ts +++ b/x-pack/plugins/enterprise_search/public/applications/shared/constants/index.ts @@ -7,6 +7,7 @@ export * from './actions'; export * from './labels'; +export * from './query_params'; export * from './tables'; export * from './units'; export { DEFAULT_META } from './default_meta'; diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/constants/query_params.ts b/x-pack/plugins/enterprise_search/public/applications/shared/constants/query_params.ts new file mode 100644 index 00000000000000..1a95b9734043e8 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/shared/constants/query_params.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export const ESINDEX_QUERY_PARAMETER = 'esindex'; diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/generate_breadcrumbs.ts b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/generate_breadcrumbs.ts index 516fa3d2ef392b..5f985aeae169b9 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/generate_breadcrumbs.ts +++ b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/generate_breadcrumbs.ts @@ -13,6 +13,7 @@ import { ENTERPRISE_SEARCH_OVERVIEW_PLUGIN, APP_SEARCH_PLUGIN, WORKPLACE_SEARCH_PLUGIN, + ENTERPRISE_SEARCH_CONTENT_PLUGIN, } from '../../../../common/constants'; import { stripLeadingSlash } from '../../../../common/strip_slashes'; @@ -118,3 +119,9 @@ export const useWorkplaceSearchBreadcrumbs = (breadcrumbs: Breadcrumbs = []) => { text: WORKPLACE_SEARCH_PLUGIN.NAME, path: '/' }, ...breadcrumbs, ]); + +export const useEnterpriseSearchContentBreadcrumbs = (breadcrumbs: Breadcrumbs = []) => + useEnterpriseSearchBreadcrumbs([ + { text: ENTERPRISE_SEARCH_CONTENT_PLUGIN.NAV_TITLE, path: '/' }, + ...breadcrumbs, + ]); diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/index.ts b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/index.ts index b14171b4798a5a..d410d392f92a8a 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/index.ts +++ b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/index.ts @@ -7,6 +7,7 @@ export { SetEnterpriseSearchChrome, + SetEnterpriseSearchContentChrome, SetElasticsearchChrome, SetAppSearchChrome, SetWorkplaceSearchChrome, diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/set_chrome.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/set_chrome.tsx index 3698a8cac35a97..83d05bb2bef731 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/set_chrome.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/set_chrome.tsx @@ -14,6 +14,7 @@ import { KibanaLogic } from '../kibana'; import { useGenerateBreadcrumbs, useEnterpriseSearchBreadcrumbs, + useEnterpriseSearchContentBreadcrumbs, useElasticsearchBreadcrumbs, useAppSearchBreadcrumbs, useWorkplaceSearchBreadcrumbs, @@ -113,5 +114,22 @@ export const SetWorkplaceSearchChrome: React.FC = ({ trail = [] return null; }; +export const SetEnterpriseSearchContentChrome: React.FC = ({ trail = [] }) => { + const { setBreadcrumbs, setDocTitle } = useValues(KibanaLogic); + + const title = reverseArray(trail); + const docTitle = appSearchTitle(title); + + const crumbs = useGenerateBreadcrumbs(trail); + const breadcrumbs = useEnterpriseSearchContentBreadcrumbs(crumbs); + + useEffect(() => { + setBreadcrumbs(breadcrumbs); + setDocTitle(docTitle); + }, [trail]); + + return null; +}; + // Small util - performantly reverses an array without mutating the original array const reverseArray = (array: string[]) => array.slice().reverse(); diff --git a/x-pack/plugins/enterprise_search/public/assets/client_libraries/dotnet.svg b/x-pack/plugins/enterprise_search/public/assets/client_libraries/dotnet.svg new file mode 100644 index 00000000000000..30fa56d08bffc8 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/assets/client_libraries/dotnet.svg @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/x-pack/plugins/enterprise_search/public/assets/client_libraries/go.svg b/x-pack/plugins/enterprise_search/public/assets/client_libraries/go.svg new file mode 100644 index 00000000000000..5b5fd6e7698afc --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/assets/client_libraries/go.svg @@ -0,0 +1,4 @@ + + + + diff --git a/x-pack/plugins/enterprise_search/public/assets/client_libraries/index.ts b/x-pack/plugins/enterprise_search/public/assets/client_libraries/index.ts new file mode 100644 index 00000000000000..0e0e774aa5bba6 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/assets/client_libraries/index.ts @@ -0,0 +1,28 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import dotnet from './dotnet.svg'; +import go from './go.svg'; +import java from './java.svg'; +import javascript from './javascript.svg'; +import perl from './perl.svg'; +import php from './php.svg'; +import python from './python.svg'; +import ruby from './ruby.svg'; +import rust from './rust.svg'; + +export const icons = { + dotnet, + go, + java, + javascript, + perl, + php, + python, + ruby, + rust, +}; diff --git a/x-pack/plugins/enterprise_search/public/assets/client_libraries/java.svg b/x-pack/plugins/enterprise_search/public/assets/client_libraries/java.svg new file mode 100644 index 00000000000000..dbe654cdd99cfe --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/assets/client_libraries/java.svg @@ -0,0 +1,3 @@ + + + diff --git a/x-pack/plugins/enterprise_search/public/assets/client_libraries/javascript.svg b/x-pack/plugins/enterprise_search/public/assets/client_libraries/javascript.svg new file mode 100644 index 00000000000000..cdb7bd1a038481 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/assets/client_libraries/javascript.svg @@ -0,0 +1,4 @@ + + + + diff --git a/x-pack/plugins/enterprise_search/public/assets/client_libraries/perl.svg b/x-pack/plugins/enterprise_search/public/assets/client_libraries/perl.svg new file mode 100644 index 00000000000000..72a2d21cc297a0 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/assets/client_libraries/perl.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/x-pack/plugins/enterprise_search/public/assets/client_libraries/php.svg b/x-pack/plugins/enterprise_search/public/assets/client_libraries/php.svg new file mode 100644 index 00000000000000..b80e9a92c9d5ff --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/assets/client_libraries/php.svg @@ -0,0 +1,3 @@ + + + diff --git a/x-pack/plugins/enterprise_search/public/assets/client_libraries/python.svg b/x-pack/plugins/enterprise_search/public/assets/client_libraries/python.svg new file mode 100644 index 00000000000000..b2c778e6355c51 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/assets/client_libraries/python.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/x-pack/plugins/enterprise_search/public/assets/client_libraries/ruby.svg b/x-pack/plugins/enterprise_search/public/assets/client_libraries/ruby.svg new file mode 100644 index 00000000000000..0af569f1ee7ae6 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/assets/client_libraries/ruby.svg @@ -0,0 +1,3 @@ + + + diff --git a/x-pack/plugins/enterprise_search/public/assets/client_libraries/rust.svg b/x-pack/plugins/enterprise_search/public/assets/client_libraries/rust.svg new file mode 100644 index 00000000000000..9cbccb35b2bafc --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/assets/client_libraries/rust.svg @@ -0,0 +1,3 @@ + + + diff --git a/x-pack/plugins/enterprise_search/server/__mocks__/fetch_indices.mock.ts b/x-pack/plugins/enterprise_search/server/__mocks__/fetch_indices.mock.ts index 5305cc8ecdb556..a860069af9e937 100644 --- a/x-pack/plugins/enterprise_search/server/__mocks__/fetch_indices.mock.ts +++ b/x-pack/plugins/enterprise_search/server/__mocks__/fetch_indices.mock.ts @@ -15,6 +15,7 @@ export const mockSingleIndexStatsResponse = { indices: { 'search-regular-index': { health: 'green', + hidden: false, status: 'open', total: { docs: { @@ -115,6 +116,7 @@ export const getIndexReturnValue = (indexName: string) => { alias: indexName.startsWith('alias') || indexName.startsWith('search-alias'), count: 100, name: indexName, + hidden: indexName.includes('hidden'), privileges: { manage: true, read: true }, total: { ...mockMultiStatsResponse.indices[indexName].total, diff --git a/x-pack/plugins/enterprise_search/server/index.ts b/x-pack/plugins/enterprise_search/server/index.ts index 41cd17181b68b1..3c409c09ff6428 100644 --- a/x-pack/plugins/enterprise_search/server/index.ts +++ b/x-pack/plugins/enterprise_search/server/index.ts @@ -42,3 +42,5 @@ export const CONNECTORS_INDEX = '.elastic-connectors'; export const CONNECTORS_JOBS_INDEX = '.elastic-connectors-sync-jobs'; export const CONNECTORS_VERSION = '1'; export const CRAWLERS_INDEX = '.ent-search-actastic-crawler2_configurations'; +export const ANALYTICS_COLLECTIONS_INDEX = '.elastic-analytics-collections'; +export const ANALYTICS_VERSION = '1'; diff --git a/x-pack/plugins/enterprise_search/server/lib/analytics/add_analytics_collection.test.ts b/x-pack/plugins/enterprise_search/server/lib/analytics/add_analytics_collection.test.ts new file mode 100644 index 00000000000000..7f8e8401a37d90 --- /dev/null +++ b/x-pack/plugins/enterprise_search/server/lib/analytics/add_analytics_collection.test.ts @@ -0,0 +1,108 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { IScopedClusterClient } from '@kbn/core-elasticsearch-server'; + +import { ANALYTICS_COLLECTIONS_INDEX } from '../..'; +import { ErrorCode } from '../../../common/types/error_codes'; + +import { addAnalyticsCollection } from './add_analytics_collection'; +import { fetchAnalyticsCollectionByName } from './fetch_analytics_collection'; +import { setupAnalyticsCollectionIndex } from './setup_indices'; + +jest.mock('./fetch_analytics_collection', () => ({ fetchAnalyticsCollectionByName: jest.fn() })); +jest.mock('./setup_indices', () => ({ + setupAnalyticsCollectionIndex: jest.fn(), +})); + +describe('add analytics collection lib function', () => { + const mockClient = { + asCurrentUser: { + index: jest.fn(), + indices: { + create: jest.fn(), + exists: jest.fn(), + refresh: jest.fn(), + }, + }, + asInternalUser: {}, + }; + + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('should add analytics collection', async () => { + mockClient.asCurrentUser.index.mockImplementation(() => ({ _id: 'fakeId' })); + mockClient.asCurrentUser.indices.exists.mockImplementation(() => false); + + await expect( + addAnalyticsCollection(mockClient as unknown as IScopedClusterClient, { + name: 'example', + }) + ).resolves.toEqual({ event_retention_day_length: 180, id: 'fakeId', name: 'example' }); + + expect(mockClient.asCurrentUser.index).toHaveBeenCalledWith({ + document: { + event_retention_day_length: 180, + name: 'example', + }, + index: ANALYTICS_COLLECTIONS_INDEX, + }); + }); + + it('should reject if index already exists', async () => { + mockClient.asCurrentUser.index.mockImplementation(() => ({ _id: 'fakeId' })); + (fetchAnalyticsCollectionByName as jest.Mock).mockImplementation(() => true); + + await expect( + addAnalyticsCollection(mockClient as unknown as IScopedClusterClient, { + name: 'index_name', + }) + ).rejects.toEqual(new Error(ErrorCode.ANALYTICS_COLLECTION_ALREADY_EXISTS)); + expect(mockClient.asCurrentUser.index).not.toHaveBeenCalled(); + }); + + it('should create index if no analytics collection index exists', async () => { + mockClient.asCurrentUser.indices.exists.mockImplementation(() => false); + + (fetchAnalyticsCollectionByName as jest.Mock).mockImplementation(() => undefined); + + mockClient.asCurrentUser.index.mockImplementation(() => ({ _id: 'fakeId' })); + + await expect( + addAnalyticsCollection(mockClient as unknown as IScopedClusterClient, { + name: 'example', + }) + ).resolves.toEqual({ event_retention_day_length: 180, id: 'fakeId', name: 'example' }); + + expect(mockClient.asCurrentUser.index).toHaveBeenCalledWith({ + document: { + event_retention_day_length: 180, + name: 'example', + }, + index: ANALYTICS_COLLECTIONS_INDEX, + }); + + expect(setupAnalyticsCollectionIndex).toHaveBeenCalledWith(mockClient.asCurrentUser); + }); + + it('should not create index if status code is not 404', async () => { + mockClient.asCurrentUser.index.mockImplementationOnce(() => { + return Promise.reject({ statusCode: 500 }); + }); + mockClient.asCurrentUser.indices.exists.mockImplementation(() => true); + (fetchAnalyticsCollectionByName as jest.Mock).mockImplementation(() => false); + await expect( + addAnalyticsCollection(mockClient as unknown as IScopedClusterClient, { + name: 'example', + }) + ).rejects.toEqual({ statusCode: 500 }); + expect(setupAnalyticsCollectionIndex).not.toHaveBeenCalled(); + expect(mockClient.asCurrentUser.index).toHaveBeenCalledTimes(1); + }); +}); diff --git a/x-pack/plugins/enterprise_search/server/lib/analytics/add_analytics_collection.ts b/x-pack/plugins/enterprise_search/server/lib/analytics/add_analytics_collection.ts new file mode 100644 index 00000000000000..1cad55a3e884c2 --- /dev/null +++ b/x-pack/plugins/enterprise_search/server/lib/analytics/add_analytics_collection.ts @@ -0,0 +1,59 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { IScopedClusterClient } from '@kbn/core/server'; + +import { ANALYTICS_COLLECTIONS_INDEX } from '../..'; +import { AnalyticsCollectionDocument, AnalyticsCollection } from '../../../common/types/analytics'; + +import { ErrorCode } from '../../../common/types/error_codes'; + +import { fetchAnalyticsCollectionByName } from './fetch_analytics_collection'; +import { setupAnalyticsCollectionIndex } from './setup_indices'; + +const createAnalyticsCollection = async ( + client: IScopedClusterClient, + document: AnalyticsCollectionDocument +): Promise => { + const analyticsCollection = await fetchAnalyticsCollectionByName(client, document.name); + + if (analyticsCollection) { + throw new Error(ErrorCode.ANALYTICS_COLLECTION_ALREADY_EXISTS); + } + + // index the document + const result = await client.asCurrentUser.index({ + document, + index: ANALYTICS_COLLECTIONS_INDEX, + }); + + await client.asCurrentUser.indices.refresh({ index: ANALYTICS_COLLECTIONS_INDEX }); + + return { + id: result._id, + ...document, + }; +}; + +export const addAnalyticsCollection = async ( + client: IScopedClusterClient, + input: { name: string } +): Promise => { + const document: AnalyticsCollectionDocument = { + event_retention_day_length: 180, + name: input.name, + }; + + const analyticsCollectionIndexExists = await client.asCurrentUser.indices.exists({ + index: ANALYTICS_COLLECTIONS_INDEX, + }); + + if (!analyticsCollectionIndexExists) { + await setupAnalyticsCollectionIndex(client.asCurrentUser); + } + + return await createAnalyticsCollection(client, document); +}; diff --git a/x-pack/plugins/enterprise_search/server/lib/analytics/fetch_analytics_collection.test.ts b/x-pack/plugins/enterprise_search/server/lib/analytics/fetch_analytics_collection.test.ts new file mode 100644 index 00000000000000..6fb4e55dd63615 --- /dev/null +++ b/x-pack/plugins/enterprise_search/server/lib/analytics/fetch_analytics_collection.test.ts @@ -0,0 +1,175 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { IScopedClusterClient } from '@kbn/core-elasticsearch-server'; + +import { ANALYTICS_COLLECTIONS_INDEX } from '../..'; + +import { + fetchAnalyticsCollectionByName, + fetchAnalyticsCollections, +} from './fetch_analytics_collection'; +import { setupAnalyticsCollectionIndex } from './setup_indices'; + +jest.mock('./setup_indices', () => ({ + setupAnalyticsCollectionIndex: jest.fn(), +})); + +describe('fetch analytics collection lib function', () => { + const mockClient = { + asCurrentUser: { + search: jest.fn(), + }, + asInternalUser: {}, + }; + + beforeEach(() => { + jest.clearAllMocks(); + }); + + describe('fetch collections', () => { + it('should return a list of analytics collections', async () => { + mockClient.asCurrentUser.search.mockImplementationOnce(() => + Promise.resolve({ + hits: { + hits: [ + { _id: '2', _source: { name: 'example' } }, + { _id: '1', _source: { name: 'example2' } }, + ], + }, + }) + ); + await expect( + fetchAnalyticsCollections(mockClient as unknown as IScopedClusterClient) + ).resolves.toEqual([ + { id: '2', name: 'example' }, + { id: '1', name: 'example2' }, + ]); + }); + + it('should setup the indexes if none exist and return an empty array', async () => { + mockClient.asCurrentUser.search.mockImplementationOnce(() => + Promise.reject({ + meta: { + body: { + error: { + type: 'index_not_found_exception', + }, + }, + }, + }) + ); + + await expect( + fetchAnalyticsCollections(mockClient as unknown as IScopedClusterClient) + ).resolves.toEqual([]); + + expect(setupAnalyticsCollectionIndex as jest.Mock).toHaveBeenCalledWith( + mockClient.asCurrentUser + ); + }); + + it('should not call setup analytics index on other errors and return error', async () => { + const error = { + meta: { + body: { + error: { + type: 'other error', + }, + }, + }, + }; + mockClient.asCurrentUser.search.mockImplementationOnce(() => Promise.reject(error)); + await expect( + fetchAnalyticsCollections(mockClient as unknown as IScopedClusterClient) + ).rejects.toMatchObject(error); + + expect(mockClient.asCurrentUser.search).toHaveBeenCalledWith({ + from: 0, + index: ANALYTICS_COLLECTIONS_INDEX, + query: { + match_all: {}, + }, + size: 1000, + }); + expect(setupAnalyticsCollectionIndex as jest.Mock).not.toHaveBeenCalled(); + }); + }); + + describe('fetch collection by name', () => { + it('should fetch analytics collection by name', async () => { + mockClient.asCurrentUser.search.mockImplementationOnce(() => + Promise.resolve({ hits: { hits: [{ _id: 'fakeId', _source: { name: 'example' } }] } }) + ); + + await expect( + fetchAnalyticsCollectionByName(mockClient as unknown as IScopedClusterClient, 'example') + ).resolves.toEqual({ id: 'fakeId', name: 'example' }); + + expect(mockClient.asCurrentUser.search).toHaveBeenCalledWith({ + index: ANALYTICS_COLLECTIONS_INDEX, + query: { + term: { + name: 'example', + }, + }, + }); + }); + + it('should call setup analytics collection index on index not found error', async () => { + mockClient.asCurrentUser.search.mockImplementationOnce(() => + Promise.reject({ + meta: { + body: { + error: { type: 'index_not_found_exception' }, + }, + }, + }) + ); + await expect( + fetchAnalyticsCollectionByName(mockClient as unknown as IScopedClusterClient, 'example') + ).resolves.toEqual(undefined); + expect(mockClient.asCurrentUser.search).toHaveBeenCalledWith({ + index: ANALYTICS_COLLECTIONS_INDEX, + query: { + term: { + name: 'example', + }, + }, + }); + expect(setupAnalyticsCollectionIndex as jest.Mock).toHaveBeenCalledWith( + mockClient.asCurrentUser + ); + }); + + it('should not call setup connectors on other errors', async () => { + mockClient.asCurrentUser.search.mockImplementationOnce(() => + Promise.reject({ + meta: { + body: { + error: { + type: 'other error', + }, + }, + }, + }) + ); + await expect(fetchAnalyticsCollectionByName(mockClient as any, 'example')).resolves.toEqual( + undefined + ); + expect(mockClient.asCurrentUser.search).toHaveBeenCalledWith({ + index: ANALYTICS_COLLECTIONS_INDEX, + query: { + term: { + name: 'example', + }, + }, + }); + expect(setupAnalyticsCollectionIndex as jest.Mock).not.toHaveBeenCalled(); + }); + }); +}); diff --git a/x-pack/plugins/enterprise_search/server/lib/analytics/fetch_analytics_collection.ts b/x-pack/plugins/enterprise_search/server/lib/analytics/fetch_analytics_collection.ts new file mode 100644 index 00000000000000..ef356ae2bca2cc --- /dev/null +++ b/x-pack/plugins/enterprise_search/server/lib/analytics/fetch_analytics_collection.ts @@ -0,0 +1,56 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { QueryDslQueryContainer } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; +import { IScopedClusterClient } from '@kbn/core-elasticsearch-server'; + +import { ANALYTICS_COLLECTIONS_INDEX } from '../..'; +import { AnalyticsCollection } from '../../../common/types/analytics'; + +import { isIndexNotFoundException } from '../../utils/identify_exceptions'; +import { fetchAll } from '../fetch_all'; + +import { setupAnalyticsCollectionIndex } from './setup_indices'; + +export const fetchAnalyticsCollectionByName = async ( + client: IScopedClusterClient, + name: string +): Promise => { + try { + const searchResults = await client.asCurrentUser.search({ + index: ANALYTICS_COLLECTIONS_INDEX, + query: { term: { name } }, + }); + + const result = searchResults.hits.hits[0]?._source + ? { ...searchResults.hits.hits[0]._source, id: searchResults.hits.hits[0]._id } + : undefined; + + return result; + } catch (error) { + if (isIndexNotFoundException(error)) { + await setupAnalyticsCollectionIndex(client.asCurrentUser); + } + return undefined; + } +}; + +export const fetchAnalyticsCollections = async ( + client: IScopedClusterClient +): Promise => { + const query: QueryDslQueryContainer = { match_all: {} }; + + try { + return await fetchAll(client, ANALYTICS_COLLECTIONS_INDEX, query); + } catch (error) { + if (isIndexNotFoundException(error)) { + await setupAnalyticsCollectionIndex(client.asCurrentUser); + return []; + } + throw error; + } +}; diff --git a/x-pack/plugins/enterprise_search/server/lib/analytics/setup_indices.test.ts b/x-pack/plugins/enterprise_search/server/lib/analytics/setup_indices.test.ts new file mode 100644 index 00000000000000..ec72d7562b44ea --- /dev/null +++ b/x-pack/plugins/enterprise_search/server/lib/analytics/setup_indices.test.ts @@ -0,0 +1,77 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { ANALYTICS_VERSION } from '../..'; + +import { setupAnalyticsCollectionIndex } from './setup_indices'; + +describe('setup analytics collection index', () => { + const mockClient = { + asCurrentUser: { + indices: { + create: jest.fn(), + updateAliases: jest.fn(), + }, + }, + asInternalUser: {}, + }; + + beforeEach(() => { + jest.clearAllMocks(); + }); + + it("should create the analytics collection index when it doesn't exist", async () => { + const indexName = '.elastic-analytics-collections'; + const analyticCollectionsMappings = { + _meta: { + version: ANALYTICS_VERSION, + }, + properties: { + event_retention_day_length: { + type: 'long', + }, + name: { + type: 'keyword', + }, + }, + }; + + mockClient.asCurrentUser.indices.create.mockImplementation(() => Promise.resolve()); + mockClient.asCurrentUser.indices.updateAliases.mockImplementation(() => Promise.resolve()); + await expect(setupAnalyticsCollectionIndex(mockClient.asCurrentUser as any)).resolves.toEqual( + undefined + ); + expect(mockClient.asCurrentUser.indices.create).toHaveBeenCalledWith({ + index: `${indexName}-v${1}`, + mappings: analyticCollectionsMappings, + settings: { auto_expand_replicas: '0-3', hidden: true, number_of_replicas: 0 }, + }); + expect(mockClient.asCurrentUser.indices.updateAliases).toHaveBeenCalledWith({ + actions: [ + { + add: { + aliases: [indexName], + index: `${indexName}-v${1}`, + is_hidden: true, + is_write_index: true, + }, + }, + ], + }); + }); + + it('should do nothing if it hits that resource already exists', async () => { + mockClient.asCurrentUser.indices.create.mockImplementation(() => + Promise.reject({ meta: { body: { error: { type: 'resource_already_exists_exception' } } } }) + ); + await expect(setupAnalyticsCollectionIndex(mockClient.asCurrentUser as any)).resolves.toEqual( + undefined + ); + expect(mockClient.asCurrentUser.indices.updateAliases).not.toHaveBeenCalled(); + expect(mockClient.asCurrentUser.indices.create).toHaveBeenCalled(); + }); +}); diff --git a/x-pack/plugins/enterprise_search/server/lib/analytics/setup_indices.ts b/x-pack/plugins/enterprise_search/server/lib/analytics/setup_indices.ts new file mode 100644 index 00000000000000..49a8aaca6f50f5 --- /dev/null +++ b/x-pack/plugins/enterprise_search/server/lib/analytics/setup_indices.ts @@ -0,0 +1,79 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { + IndicesIndexSettings, + MappingProperty, + MappingTypeMapping, +} from '@elastic/elasticsearch/lib/api/types'; +import { ElasticsearchClient } from '@kbn/core-elasticsearch-server'; + +import { ANALYTICS_COLLECTIONS_INDEX, ANALYTICS_VERSION } from '../..'; +import { isResourceAlreadyExistsException } from '../../utils/identify_exceptions'; + +const analyticsCollectionMappingsProperties: Record = { + event_retention_day_length: { + type: 'long', + }, + name: { + type: 'keyword', + }, +}; + +const defaultSettings: IndicesIndexSettings = { + auto_expand_replicas: '0-3', + hidden: true, + number_of_replicas: 0, +}; + +interface IndexDefinition { + aliases: string[]; + mappings: MappingTypeMapping; + name: string; + settings: IndicesIndexSettings; +} + +export const setupAnalyticsCollectionIndex = async (client: ElasticsearchClient) => { + const indexConfiguration: IndexDefinition = { + aliases: [ANALYTICS_COLLECTIONS_INDEX], + mappings: { + _meta: { + version: ANALYTICS_VERSION, + }, + properties: analyticsCollectionMappingsProperties, + }, + name: `${ANALYTICS_COLLECTIONS_INDEX}-v${ANALYTICS_VERSION}`, + settings: defaultSettings, + }; + + try { + const { mappings, aliases, name: index, settings } = indexConfiguration; + await client.indices.create({ + index, + mappings, + settings, + }); + await client.indices.updateAliases({ + actions: [ + { + add: { + aliases, + index, + is_hidden: true, + is_write_index: true, + }, + }, + ], + }); + } catch (error) { + if (isResourceAlreadyExistsException(error)) { + // index already exists, swallow error + return; + } + return error; + } +}; diff --git a/x-pack/plugins/enterprise_search/server/lib/connectors/add_connector.test.ts b/x-pack/plugins/enterprise_search/server/lib/connectors/add_connector.test.ts index ac20e09284185c..adb99b98a42269 100644 --- a/x-pack/plugins/enterprise_search/server/lib/connectors/add_connector.test.ts +++ b/x-pack/plugins/enterprise_search/server/lib/connectors/add_connector.test.ts @@ -40,13 +40,20 @@ describe('addConnector lib function', () => { asInternalUser: {}, }; + const createConnectorsIndexExistsFn = + (connectorsIndexExists: boolean, defaultValue: boolean) => + ({ index }: { index: string }) => + index === CONNECTORS_INDEX ? connectorsIndexExists : defaultValue; + beforeEach(() => { jest.clearAllMocks(); }); it('should add connector', async () => { mockClient.asCurrentUser.index.mockImplementation(() => ({ _id: 'fakeId' })); - mockClient.asCurrentUser.indices.exists.mockImplementation(() => false); + mockClient.asCurrentUser.indices.exists.mockImplementation( + createConnectorsIndexExistsFn(true, false) + ); (fetchConnectorByIndexName as jest.Mock).mockImplementation(() => undefined); (fetchCrawlerByIndexName as jest.Mock).mockImplementation(() => undefined); @@ -82,7 +89,9 @@ describe('addConnector lib function', () => { it('should reject if index already exists', async () => { mockClient.asCurrentUser.index.mockImplementation(() => ({ _id: 'fakeId' })); - mockClient.asCurrentUser.indices.exists.mockImplementation(() => true); + mockClient.asCurrentUser.indices.exists.mockImplementation( + createConnectorsIndexExistsFn(true, true) + ); (fetchConnectorByIndexName as jest.Mock).mockImplementation(() => undefined); (fetchCrawlerByIndexName as jest.Mock).mockImplementation(() => undefined); @@ -97,7 +106,9 @@ describe('addConnector lib function', () => { it('should reject if connector already exists', async () => { mockClient.asCurrentUser.index.mockImplementation(() => ({ _id: 'fakeId' })); - mockClient.asCurrentUser.indices.exists.mockImplementation(() => false); + mockClient.asCurrentUser.indices.exists.mockImplementation( + createConnectorsIndexExistsFn(true, false) + ); (fetchConnectorByIndexName as jest.Mock).mockImplementation(() => true); (fetchCrawlerByIndexName as jest.Mock).mockImplementation(() => undefined); @@ -110,9 +121,28 @@ describe('addConnector lib function', () => { expect(mockClient.asCurrentUser.indices.create).not.toHaveBeenCalled(); }); + it('should reject if crawler already exists', async () => { + mockClient.asCurrentUser.index.mockImplementation(() => ({ _id: 'fakeId' })); + mockClient.asCurrentUser.indices.exists.mockImplementation( + createConnectorsIndexExistsFn(true, false) + ); + (fetchConnectorByIndexName as jest.Mock).mockImplementation(() => undefined); + (fetchCrawlerByIndexName as jest.Mock).mockImplementation(() => true); + + await expect( + addConnector(mockClient as unknown as IScopedClusterClient, { + index_name: 'index_name', + language: 'en', + }) + ).rejects.toEqual(new Error(ErrorCode.CRAWLER_ALREADY_EXISTS)); + expect(mockClient.asCurrentUser.indices.create).not.toHaveBeenCalled(); + }); + it('should reject with index already exists if connector and index already exist', async () => { mockClient.asCurrentUser.index.mockImplementation(() => ({ _id: 'fakeId' })); - mockClient.asCurrentUser.indices.exists.mockImplementation(() => true); + mockClient.asCurrentUser.indices.exists.mockImplementation( + createConnectorsIndexExistsFn(true, true) + ); (fetchConnectorByIndexName as jest.Mock).mockImplementation(() => true); (fetchCrawlerByIndexName as jest.Mock).mockImplementation(() => undefined); @@ -127,7 +157,9 @@ describe('addConnector lib function', () => { it('should replace connector if deleteExistingConnector flag is true', async () => { mockClient.asCurrentUser.index.mockImplementation(() => ({ _id: 'fakeId' })); - mockClient.asCurrentUser.indices.exists.mockImplementation(() => false); + mockClient.asCurrentUser.indices.exists.mockImplementation( + createConnectorsIndexExistsFn(true, false) + ); (fetchConnectorByIndexName as jest.Mock).mockImplementation(() => ({ id: 'connectorId' })); (fetchCrawlerByIndexName as jest.Mock).mockImplementation(() => undefined); @@ -167,13 +199,9 @@ describe('addConnector lib function', () => { }); it('should create index if no connectors index exists', async () => { - mockClient.asCurrentUser.index.mockImplementationOnce(() => { - return Promise.reject({ - meta: { body: { error: { type: 'index_not_found_exception' } } }, - statusCode: 404, - }); - }); - mockClient.asCurrentUser.indices.exists.mockImplementation(() => false); + mockClient.asCurrentUser.indices.exists.mockImplementation( + createConnectorsIndexExistsFn(false, false) + ); (fetchConnectorByIndexName as jest.Mock).mockImplementation(() => false); (fetchCrawlerByIndexName as jest.Mock).mockImplementation(() => undefined); await expect( @@ -206,36 +234,4 @@ describe('addConnector lib function', () => { settings: textAnalysisSettings('en'), }); }); - it('should not create index if status code is not 404', async () => { - mockClient.asCurrentUser.index.mockImplementationOnce(() => { - return Promise.reject({ statusCode: 500 }); - }); - mockClient.asCurrentUser.indices.exists.mockImplementation(() => false); - (fetchConnectorByIndexName as jest.Mock).mockImplementation(() => false); - (fetchCrawlerByIndexName as jest.Mock).mockImplementation(() => undefined); - await expect( - addConnector(mockClient as unknown as IScopedClusterClient, { - index_name: 'index_name', - language: 'en', - }) - ).rejects.toEqual({ statusCode: 500 }); - expect(setupConnectorsIndices).not.toHaveBeenCalled(); - expect(mockClient.asCurrentUser.index).toHaveBeenCalledTimes(1); - }); - it('should not create index if crawler exists', async () => { - mockClient.asCurrentUser.index.mockImplementationOnce(() => { - return 'connector '; - }); - mockClient.asCurrentUser.indices.exists.mockImplementation(() => false); - (fetchConnectorByIndexName as jest.Mock).mockImplementation(() => false); - (fetchCrawlerByIndexName as jest.Mock).mockImplementation(() => 'crawler'); - await expect( - addConnector(mockClient as unknown as IScopedClusterClient, { - index_name: 'index_name', - language: 'en', - }) - ).rejects.toEqual(new Error(ErrorCode.CRAWLER_ALREADY_EXISTS)); - expect(setupConnectorsIndices).not.toHaveBeenCalled(); - expect(mockClient.asCurrentUser.index).not.toHaveBeenCalled(); - }); }); diff --git a/x-pack/plugins/enterprise_search/server/lib/connectors/add_connector.ts b/x-pack/plugins/enterprise_search/server/lib/connectors/add_connector.ts index 8528b28582bf02..39a9d562106d0b 100644 --- a/x-pack/plugins/enterprise_search/server/lib/connectors/add_connector.ts +++ b/x-pack/plugins/enterprise_search/server/lib/connectors/add_connector.ts @@ -11,7 +11,6 @@ import { CONNECTORS_INDEX } from '../..'; import { ConnectorDocument, ConnectorStatus } from '../../../common/types/connectors'; import { ErrorCode } from '../../../common/types/error_codes'; import { setupConnectorsIndices } from '../../index_management/setup_indices'; -import { isIndexNotFoundException } from '../../utils/identify_exceptions'; import { fetchCrawlerByIndexName } from '../crawler/fetch_crawlers'; import { textAnalysisSettings } from '../indices/text_analysis'; @@ -80,21 +79,11 @@ export const addConnector = async ( status: ConnectorStatus.CREATED, sync_now: false, }; - try { - return await createConnector( - document, - client, - input.language, - !!input.delete_existing_connector - ); - } catch (error) { - if (isIndexNotFoundException(error)) { - // This means .ent-search-connectors index doesn't exist yet - // So we first have to create it, and then try inserting the document again - await setupConnectorsIndices(client.asCurrentUser); - return await createConnector(document, client, input.language, false); - } else { - throw error; - } + const connectorsIndexExists = await client.asCurrentUser.indices.exists({ + index: CONNECTORS_INDEX, + }); + if (!connectorsIndexExists) { + await setupConnectorsIndices(client.asCurrentUser); } + return await createConnector(document, client, input.language, !!input.delete_existing_connector); }; diff --git a/x-pack/plugins/enterprise_search/server/lib/indices/fetch_index.test.ts b/x-pack/plugins/enterprise_search/server/lib/indices/fetch_index.test.ts index 9bf9f2b2d2f1d3..49384f564a9885 100644 --- a/x-pack/plugins/enterprise_search/server/lib/indices/fetch_index.test.ts +++ b/x-pack/plugins/enterprise_search/server/lib/indices/fetch_index.test.ts @@ -43,6 +43,7 @@ describe('fetchIndex lib function', () => { indices: { index_name: { health: 'green', + hidden: false, size: new ByteSizeValue(108000).toString(), status: 'open', total: { @@ -63,6 +64,7 @@ describe('fetchIndex lib function', () => { aliases: [], count: 100, health: 'green', + hidden: false, name: 'index_name', status: 'open', total: { diff --git a/x-pack/plugins/enterprise_search/server/lib/indices/fetch_indices.test.ts b/x-pack/plugins/enterprise_search/server/lib/indices/fetch_indices.test.ts index 1fc8f4cc071864..4a01295fbeaa86 100644 --- a/x-pack/plugins/enterprise_search/server/lib/indices/fetch_indices.test.ts +++ b/x-pack/plugins/enterprise_search/server/lib/indices/fetch_indices.test.ts @@ -86,6 +86,7 @@ describe('fetchIndices lib function', () => { alias: false, count: 100, health: 'green', + hidden: false, name: 'search-regular-index', privileges: { manage: true, read: true }, status: 'open', @@ -135,6 +136,7 @@ describe('fetchIndices lib function', () => { alias: false, count: 100, health: 'green', + hidden: false, name: 'search-regular-index', privileges: { manage: true, read: true }, status: 'open', @@ -195,6 +197,7 @@ describe('fetchIndices lib function', () => { { count: 100, health: 'green', + hidden: false, name: 'index-without-prefix', status: 'open', alias: false, @@ -213,6 +216,7 @@ describe('fetchIndices lib function', () => { { count: 100, health: 'green', + hidden: false, name: 'search-aliased', status: 'open', alias: true, @@ -231,6 +235,7 @@ describe('fetchIndices lib function', () => { { count: 100, health: 'green', + hidden: false, name: 'search-double-aliased', status: 'open', alias: true, @@ -249,6 +254,7 @@ describe('fetchIndices lib function', () => { { count: 100, health: 'green', + hidden: false, name: 'second-index', status: 'open', alias: false, @@ -298,6 +304,7 @@ describe('fetchIndices lib function', () => { { count: 100, health: 'green', + hidden: false, name: 'index-without-prefix', status: 'open', alias: false, @@ -316,6 +323,7 @@ describe('fetchIndices lib function', () => { { count: 100, health: 'green', + hidden: false, name: 'second-index', status: 'open', alias: false, @@ -350,6 +358,7 @@ describe('fetchIndices lib function', () => { { count: 100, health: undefined, + hidden: false, name: 'search-regular-index', status: undefined, alias: false, diff --git a/x-pack/plugins/enterprise_search/server/lib/indices/fetch_indices.ts b/x-pack/plugins/enterprise_search/server/lib/indices/fetch_indices.ts index 28a5373d50ac56..5a1bfec87b9b71 100644 --- a/x-pack/plugins/enterprise_search/server/lib/indices/fetch_indices.ts +++ b/x-pack/plugins/enterprise_search/server/lib/indices/fetch_indices.ts @@ -13,13 +13,16 @@ import { import { ByteSizeValue } from '@kbn/config-schema'; import { IScopedClusterClient } from '@kbn/core/server'; -import { ElasticsearchIndexWithPrivileges } from '../../../common/types'; +import { + ElasticsearchIndex, + ElasticsearchIndexWithPrivileges, +} from '../../../common/types/indices'; export const mapIndexStats = ( indexData: IndicesIndexState, indexStats: IndicesStatsIndicesStats, indexName: string -) => { +): Omit & { aliases: string[] } => { const aliases = Object.keys(indexData.aliases!); const sizeInBytes = new ByteSizeValue(indexStats?.total?.store?.size_in_bytes ?? 0).toString(); @@ -38,6 +41,7 @@ export const mapIndexStats = ( return { aliases, health: indexStats?.health, + hidden: Boolean(indexData.settings?.index?.hidden), name: indexName, status: indexStats?.status, total, @@ -132,17 +136,17 @@ export const fetchIndices = async ( return mapIndexStats(indexData, indexStats, indexName); }) .flatMap(({ name, aliases, ...indexData }) => { - const indicesAndAliases = [] as ElasticsearchIndexWithPrivileges[]; + const indicesAndAliases: ElasticsearchIndexWithPrivileges[] = []; if (includeAliases) { aliases.forEach((alias) => { if (alias.startsWith(alwaysShowSearchPattern)) { indicesAndAliases.push({ + ...indexData, alias: true, count: indexCounts[alias] ?? 0, name: alias, privileges: { manage: false, read: false, ...indexPrivileges[name] }, - ...indexData, }); } }); @@ -160,23 +164,23 @@ export const fetchIndices = async ( }) .flatMap(({ name, aliases, ...indexData }) => { // expand aliases and add to results - const indicesAndAliases = [] as ElasticsearchIndexWithPrivileges[]; + const indicesAndAliases: ElasticsearchIndexWithPrivileges[] = []; indicesAndAliases.push({ + ...indexData, alias: false, count: indexCounts[name] ?? 0, name, privileges: { manage: false, read: false, ...indexPrivileges[name] }, - ...indexData, }); if (includeAliases) { aliases.forEach((alias) => { indicesAndAliases.push({ + ...indexData, alias: true, count: indexCounts[alias] ?? 0, name: alias, privileges: { manage: false, read: false, ...indexPrivileges[name] }, - ...indexData, }); }); } @@ -191,7 +195,7 @@ export const fetchIndices = async ( const itemsToInclude = alwaysShowIndices.filter(({ name }) => indexNamesToInclude.includes(name)); const indicesData = alwaysShowSearchPattern - ? ([...regularIndexData, ...itemsToInclude] as ElasticsearchIndexWithPrivileges[]) + ? [...regularIndexData, ...itemsToInclude] : regularIndexData; return indicesData.filter( diff --git a/x-pack/plugins/enterprise_search/server/plugin.ts b/x-pack/plugins/enterprise_search/server/plugin.ts index cfc3d8d196fd93..f9d23af1411191 100644 --- a/x-pack/plugins/enterprise_search/server/plugin.ts +++ b/x-pack/plugins/enterprise_search/server/plugin.ts @@ -46,6 +46,7 @@ import { import { registerAppSearchRoutes } from './routes/app_search'; import { registerEnterpriseSearchRoutes } from './routes/enterprise_search'; +import { registerAnalyticsRoutes } from './routes/enterprise_search/analytics'; import { registerConfigDataRoute } from './routes/enterprise_search/config_data'; import { registerConnectorRoutes } from './routes/enterprise_search/connectors'; import { registerCrawlerRoutes } from './routes/enterprise_search/crawler/crawler'; @@ -168,6 +169,7 @@ export class EnterpriseSearchPlugin implements Plugin { // Enterprise Search Routes registerConnectorRoutes(dependencies); registerCrawlerRoutes(dependencies); + registerAnalyticsRoutes(dependencies); getStartServices().then(([, { security: securityStart }]) => { registerCreateAPIKeyRoute(dependencies, securityStart); diff --git a/x-pack/plugins/enterprise_search/server/routes/enterprise_search/analytics.ts b/x-pack/plugins/enterprise_search/server/routes/enterprise_search/analytics.ts new file mode 100644 index 00000000000000..7035329e4d3141 --- /dev/null +++ b/x-pack/plugins/enterprise_search/server/routes/enterprise_search/analytics.ts @@ -0,0 +1,64 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { schema } from '@kbn/config-schema'; + +import { i18n } from '@kbn/i18n'; + +import { ErrorCode } from '../../../common/types/error_codes'; +import { addAnalyticsCollection } from '../../lib/analytics/add_analytics_collection'; +import { fetchAnalyticsCollections } from '../../lib/analytics/fetch_analytics_collection'; +import { RouteDependencies } from '../../plugin'; +import { createError } from '../../utils/create_error'; +import { elasticsearchErrorHandler } from '../../utils/elasticsearch_error_handler'; + +export function registerAnalyticsRoutes({ router, log }: RouteDependencies) { + router.get( + { + path: '/internal/enterprise_search/analytics/collections', + validate: {}, + }, + elasticsearchErrorHandler(log, async (context, request, response) => { + const { client } = (await context.core).elasticsearch; + const collections = await fetchAnalyticsCollections(client); + return response.ok({ body: collections }); + }) + ); + + router.post( + { + path: '/internal/enterprise_search/analytics/collections', + validate: { + body: schema.object({ + name: schema.string(), + }), + }, + }, + elasticsearchErrorHandler(log, async (context, request, response) => { + const { client } = (await context.core).elasticsearch; + try { + const body = await addAnalyticsCollection(client, request.body); + return response.ok({ body }); + } catch (error) { + if ((error as Error).message === ErrorCode.ANALYTICS_COLLECTION_ALREADY_EXISTS) { + return createError({ + errorCode: (error as Error).message as ErrorCode, + message: i18n.translate( + 'xpack.enterpriseSearch.server.routes.addAnalyticsCollection.analyticsCollectionExistsError', + { + defaultMessage: 'Analytics collection already exists', + } + ), + response, + statusCode: 409, + }); + } + throw error; + } + }) + ); +} diff --git a/x-pack/plugins/enterprise_search/server/routes/enterprise_search/indices.ts b/x-pack/plugins/enterprise_search/server/routes/enterprise_search/indices.ts index 5d5f72c2977270..6741721053b863 100644 --- a/x-pack/plugins/enterprise_search/server/routes/enterprise_search/indices.ts +++ b/x-pack/plugins/enterprise_search/server/routes/enterprise_search/indices.ts @@ -9,6 +9,7 @@ import { schema } from '@kbn/config-schema'; import { i18n } from '@kbn/i18n'; import { ErrorCode } from '../../../common/types/error_codes'; +import { deleteConnectorById } from '../../lib/connectors/delete_connector'; import { fetchConnectorByIndexName, fetchConnectors } from '../../lib/connectors/fetch_connectors'; import { fetchCrawlerByIndexName, fetchCrawlers } from '../../lib/crawler/fetch_crawlers'; @@ -124,6 +125,52 @@ export function registerIndexRoutes({ router, log }: RouteDependencies) { }) ); + router.delete( + { + path: '/internal/enterprise_search/indices/{indexName}', + validate: { + params: schema.object({ + indexName: schema.string(), + }), + }, + }, + elasticsearchErrorHandler(log, async (context, request, response) => { + const indexName = decodeURIComponent(request.params.indexName); + const { client } = (await context.core).elasticsearch; + + try { + const connector = await fetchConnectorByIndexName(client, indexName); + const crawler = await fetchCrawlerByIndexName(client, indexName); + + if (connector) { + await deleteConnectorById(client, connector.id); + } + + if (crawler) { + // do nothing for now because we don't have a way to delete a crawler yet + } + + await client.asCurrentUser.indices.delete({ index: indexName }); + + return response.ok({ + body: {}, + headers: { 'content-type': 'application/json' }, + }); + } catch (error) { + if (isIndexNotFoundException(error)) { + return createError({ + errorCode: ErrorCode.INDEX_NOT_FOUND, + message: 'Could not find index', + response, + statusCode: 404, + }); + } + + throw error; + } + }) + ); + router.get( { path: '/internal/enterprise_search/indices/{indexName}/exists', diff --git a/x-pack/plugins/event_log/scripts/create_schemas.js b/x-pack/plugins/event_log/scripts/create_schemas.js index 1a775b44add8d8..dc4eeb01c89579 100755 --- a/x-pack/plugins/event_log/scripts/create_schemas.js +++ b/x-pack/plugins/event_log/scripts/create_schemas.js @@ -9,7 +9,7 @@ const fs = require('fs'); const path = require('path'); -const { set } = require('@elastic/safer-lodash-set'); +const { set } = require('@kbn/safer-lodash-set'); const lodash = require('lodash'); const LineWriter = require('./lib/line_writer'); diff --git a/x-pack/plugins/files/common/api_routes.ts b/x-pack/plugins/files/common/api_routes.ts index f3647edaf83f0d..9eb6671465799d 100644 --- a/x-pack/plugins/files/common/api_routes.ts +++ b/x-pack/plugins/files/common/api_routes.ts @@ -99,7 +99,7 @@ export type UpdateFileKindHttpEndpoint = HttpApiInterfaceEntryDefinition< export type UploadFileKindHttpEndpoint = HttpApiInterfaceEntryDefinition< { id: string }, unknown, - any, + { body: unknown }, { ok: true; size: number; diff --git a/x-pack/plugins/files/common/types.ts b/x-pack/plugins/files/common/types.ts index 2fef7ab3f17c4c..c0761b996cd73e 100644 --- a/x-pack/plugins/files/common/types.ts +++ b/x-pack/plugins/files/common/types.ts @@ -332,7 +332,16 @@ export interface FileUnshareOptions { * A class with set of properties and behaviors of the "smart" file object and adds * behaviours for interacting with files on top of the pure data. */ -export interface File extends FileJSON { +export interface File { + /** + * The file ID + */ + id: string; + + /** + * File metadata in camelCase form. + */ + data: FileJSON; /** * Update a file object's metadatathat can be updated. * @@ -345,7 +354,7 @@ export interface File extends FileJSON { * * @param content - The content to stream to storage. */ - uploadContent(content: Readable): Promise; + uploadContent(content: Readable): Promise>; /** * Stream file content from storage. @@ -431,6 +440,8 @@ export interface FileKind { id: string; /** * Maximum size, in bytes, a file of this kind can be. + * + * @default 4MiB */ maxSizeBytes?: number; @@ -448,35 +459,41 @@ export interface FileKind { blobStoreSettings?: BlobStorageSettings; /** - * Optionally specify which HTTP routes to create for the file kind + * Specify which HTTP routes to create for the file kind. + * + * You can always create your own HTTP routes for working with files but + * this interface allows you to expose basic CRUD operations, upload, download + * and sharing of files over a RESTful-like interface. + * + * @note The public {@link FileClient} uses these endpoints. */ http: { /** - * Enable creating this file type + * Expose file creation (and upload) over HTTP. */ create?: HttpEndpointDefinition; /** - * Enable the file metadata to updated + * Expose file updates over HTTP. */ update?: HttpEndpointDefinition; /** - * Enable the file to be deleted (metadata and contents) + * Expose file deletion over HTTP. */ delete?: HttpEndpointDefinition; /** - * Enable file to be retrieved by ID. + * Expose "get by ID" functionality over HTTP. */ getById?: HttpEndpointDefinition; /** - * Enable file to be listed + * Expose the ability to list all files of this kind over HTTP. */ list?: HttpEndpointDefinition; /** - * Enable the file to be downloaded + * Expose the ability to download a file's contents over HTTP. */ download?: HttpEndpointDefinition; /** - * Enable the file to be shared publicly + * Expose file share functionality over HTTP. */ share?: HttpEndpointDefinition; }; diff --git a/x-pack/plugins/files/public/files_client/files_client.ts b/x-pack/plugins/files/public/files_client/files_client.ts index 3abd6c935541cf..2f01405ee14923 100644 --- a/x-pack/plugins/files/public/files_client/files_client.ts +++ b/x-pack/plugins/files/public/files_client/files_client.ts @@ -77,7 +77,7 @@ const commonBodyHeaders = { }; export const createFilesClient = ({ http, fileKind }: Args): FilesClient => { - return { + const api: FilesClient = { create: (args) => { return http.post(apiRoutes.getCreateFileRoute(fileKind), { headers: commonBodyHeaders, @@ -88,13 +88,15 @@ export const createFilesClient = ({ http, fileKind }: Args): FilesClient => { return http.delete(apiRoutes.getDeleteRoute(fileKind, args.id)); }, download: (args) => { - return http.get(apiRoutes.getDownloadRoute(fileKind, args.id, args.fileName)); + return http.get(apiRoutes.getDownloadRoute(fileKind, args.id, args.fileName), { + headers: { Accept: '*/*' }, + }); }, getById: (args) => { return http.get(apiRoutes.getByIdRoute(fileKind, args.id)); }, - list: ({ page, perPage }) => { - return http.get(apiRoutes.getListRoute(fileKind, page, perPage)); + list(args = {}) { + return http.get(apiRoutes.getListRoute(fileKind, args.page, args.perPage)); }, update: ({ id, ...body }) => { return http.patch(apiRoutes.getUpdateRoute(fileKind, id), { @@ -105,9 +107,10 @@ export const createFilesClient = ({ http, fileKind }: Args): FilesClient => { upload: (args) => { return http.put(apiRoutes.getUploadRoute(fileKind, args.id), { headers: { - 'content-type': 'application/octet-stream', + 'Content-Type': 'application/octet-stream', }, - body: args.body, + + body: args.body as BodyInit, }); }, share: ({ fileId, name, validUntil }) => { @@ -137,5 +140,9 @@ export const createFilesClient = ({ http, fileKind }: Args): FilesClient => { publicDownload: ({ token, fileName }) => { return http.get(apiRoutes.getPublicDownloadRoute(token, fileName)); }, + getDownloadHref: ({ id }) => { + return `${http.basePath.prepend(apiRoutes.getDownloadRoute(fileKind, id))}`; + }, }; + return api; }; diff --git a/x-pack/plugins/files/public/index.ts b/x-pack/plugins/files/public/index.ts index 4b707aaa3b6a2a..36a570c2096834 100644 --- a/x-pack/plugins/files/public/index.ts +++ b/x-pack/plugins/files/public/index.ts @@ -6,8 +6,8 @@ */ import { FilesPlugin } from './plugin'; - -export type { FilesClient, FilesClientFactory } from './types'; +export type { FilesSetup, FilesStart } from './plugin'; +export type { FilesClient, FilesClientFactory, FilesClientResponses } from './types'; export function plugin() { return new FilesPlugin(); diff --git a/x-pack/plugins/files/public/types.ts b/x-pack/plugins/files/public/types.ts index 24a31252130204..3a52b863bc7e43 100644 --- a/x-pack/plugins/files/public/types.ts +++ b/x-pack/plugins/files/public/types.ts @@ -5,6 +5,7 @@ * 2.0. */ +import { FileJSON } from '../common'; import type { FindFilesHttpEndpoint, FileShareHttpEndpoint, @@ -30,6 +31,10 @@ type ClientMethodFrom = ( args: E['inputs']['body'] & E['inputs']['params'] & E['inputs']['query'] ) => Promise; +type ClientMethodOptionalArgsFrom = ( + args?: E['inputs']['body'] & E['inputs']['params'] & E['inputs']['query'] +) => Promise; + /** * A client that can be used to manage a specific {@link FileKind}. */ @@ -57,7 +62,7 @@ export interface FilesClient { * * @param args - list files args */ - list: ClientMethodFrom; + list: ClientMethodOptionalArgsFrom; /** * Find a set of files given some filters. * @@ -123,8 +128,18 @@ export interface FilesClient { * @param args - Get public download arguments. */ publicDownload: ClientMethodFrom; + + /** + * Get a string for downloading a file that can be passed to a button element's + * href for download. + */ + getDownloadHref: (file: FileJSON) => string; } +export type FilesClientResponses = { + [K in keyof FilesClient]: Awaited>; +}; + /** * A factory for creating a {@link FilesClient} */ diff --git a/x-pack/plugins/files/server/file/file.test.ts b/x-pack/plugins/files/server/file/file.test.ts index ebb1efe32422c1..1b86af89ba61c2 100644 --- a/x-pack/plugins/files/server/file/file.test.ts +++ b/x-pack/plugins/files/server/file/file.test.ts @@ -82,4 +82,14 @@ describe('File', () => { await setImmediate(); expect(blobStoreSpy.calledOnce).toBe(true); }); + + it('updates file data after upload', async () => { + const fileSO = { attributes: { Status: 'AWAITING_UPLOAD' } }; + (soClient.create as jest.Mock).mockResolvedValue(fileSO); + (soClient.update as jest.Mock).mockResolvedValue(fileSO); + + const file = await fileService.createFile({ name: 'test', fileKind }); + await file.uploadContent(Readable.from(['test'])); + expect(file.data.status).toBe('READY'); + }); }); diff --git a/x-pack/plugins/files/server/file/file.ts b/x-pack/plugins/files/server/file/file.ts index 00544a7e14f082..bdf85af1bec0ea 100644 --- a/x-pack/plugins/files/server/file/file.ts +++ b/x-pack/plugins/files/server/file/file.ts @@ -6,27 +6,11 @@ */ import { Logger } from '@kbn/core/server'; -import mimeType from 'mime'; import { Readable } from 'stream'; -import type { FileCompression, FileShareJSON, FileShareJSONWithToken } from '../../common/types'; -import type { - File as IFile, - FileKind, - FileMetadata, - FileStatus, - UpdatableFileMetadata, - FileJSON, -} from '../../common'; -import { - fileAttributesReducer, - Action, - createDefaultFileAttributes, -} from './file_attributes_reducer'; -import { createAuditEvent } from '../audit_events'; -import { InternalFileService } from '../file_service/internal_file_service'; -import { InternalFileShareService } from '../file_share_service'; +import type { FileShareJSON, FileShareJSONWithToken } from '../../common/types'; +import type { File as IFile, UpdatableFileMetadata, FileJSON } from '../../common'; +import { fileAttributesReducer, Action } from './file_attributes_reducer'; import type { FileClientImpl } from '../file_client/file_client'; -import { toJSON } from './to_json'; import { AlreadyDeletedError, ContentAlreadyUploadedError, @@ -35,46 +19,37 @@ import { } from './errors'; /** - * Public class that provides all data and functionality consumers will need at the - * individual file level + * Scopes file actions to an ID and set of attributes. * - * @note Instantiation should not happen outside of this plugin + * Also exposes the upload and download functionality. */ export class File implements IFile { - private readonly logAuditEvent: InternalFileService['writeAuditLog']; - constructor( public readonly id: string, - private fileMetadata: FileMetadata, + private metadata: FileJSON, private readonly fileClient: FileClientImpl, - private readonly internalFileService: InternalFileService, - private readonly fileShareService: InternalFileShareService, private readonly logger: Logger - ) { - this.logAuditEvent = this.internalFileService.writeAuditLog.bind(this.internalFileService); - } + ) {} - private async updateFileState(action: Action) { - const { metadata } = await this.fileClient.update({ - id: this.id, - metadata: fileAttributesReducer(this.metadata, action), - }); - this.fileMetadata = metadata; + private async updateFileState(action: Action): Promise { + const metadata = fileAttributesReducer(this.data, action); + await this.fileClient.internalUpdate(this.id, metadata); + this.data = metadata as FileJSON; } private isReady(): boolean { - return this.status === 'READY'; + return this.data.status === 'READY'; } private isDeleted(): boolean { - return this.status === 'DELETED'; + return this.data.status === 'DELETED'; } private uploadInProgress(): boolean { - return this.status === 'UPLOADING'; + return this.data.status === 'UPLOADING'; } - public async update(attrs: Partial): Promise { + public async update(attrs: Partial): Promise> { await this.updateFileState({ action: 'updateFile', payload: attrs, @@ -82,14 +57,14 @@ export class File implements IFile { return this; } - public async uploadContent(content: Readable): Promise { + public async uploadContent(content: Readable): Promise> { if (this.uploadInProgress()) { throw new UploadInProgressError('Upload already in progress.'); } if (this.isReady()) { throw new ContentAlreadyUploadedError('Already uploaded file content.'); } - this.logger.debug(`Uploading file [id = ${this.id}][name = ${this.name}].`); + this.logger.debug(`Uploading file [id = ${this.id}][name = ${this.data.name}].`); await this.updateFileState({ action: 'uploading', }); @@ -100,6 +75,7 @@ export class File implements IFile { action: 'uploaded', payload: { size }, }); + return this; } catch (e) { await this.updateFileState({ action: 'uploadError' }); this.fileClient.deleteContent(this.id).catch(() => {}); // Best effort to remove any uploaded content @@ -108,7 +84,7 @@ export class File implements IFile { } public downloadContent(): Promise { - const { size } = this.metadata; + const { size } = this.data; if (!this.isReady()) { throw new NoDownloadAvailableError('This file content is not available for download.'); } @@ -126,142 +102,38 @@ export class File implements IFile { await this.updateFileState({ action: 'delete', }); - // Stop sharing this file - await this.fileShareService.deleteForFile({ file: this }); await this.fileClient.delete({ id: this.id, hasContent: this.isReady() }); - this.logAuditEvent( - createAuditEvent({ - action: 'delete', - outcome: 'success', - message: `Deleted file "${this.name}" of kind "${this.fileKind}" with id "${this.id}"`, - }) - ); } public async share({ name, validUntil, }: { - name?: string; + name: string; validUntil?: number; }): Promise { - const shareObject = await this.fileShareService.share({ file: this, name, validUntil }); - this.internalFileService.writeAuditLog( - createAuditEvent({ - action: 'create', - message: `Shared file "${this.name}" with id "${this.id}"`, - }) - ); - return shareObject; + return this.fileClient.share({ name, validUntil, file: this }); } async listShares(): Promise { - const { shares } = await this.fileShareService.list({ fileId: this.id }); + const { shares } = await this.fileClient.listShares({ + fileId: this.id, + }); return shares; } async unshare(opts: { shareId: string }): Promise { - await this.fileShareService.delete({ id: opts.shareId }); - this.internalFileService.writeAuditLog( - createAuditEvent({ - action: 'delete', - message: `Removed share for "${this.name}" with id "${this.id}"`, - }) - ); + await this.fileClient.unshare({ id: opts.shareId }); } public toJSON(): FileJSON { - return toJSON(this.id, this.metadata); - } - - private get metadata(): FileMetadata { - return this.fileMetadata; - } - - public get created(): string { - return this.metadata.created; - } - - public get updated(): string { - return this.metadata.Updated; - } - - public get chunkSize(): number | undefined { - return this.metadata.ChunkSize; - } - - public get fileKind(): string { - return this.fileClient.fileKind; - } - - public get name(): string { - return this.metadata.name; + return this.data; } - public get status(): FileStatus { - return this.metadata.Status; + public get data(): FileJSON { + return this.metadata; } - - public get compression(): undefined | FileCompression { - return this.metadata.Compression; - } - - public get size(): undefined | number { - return this.metadata.size; - } - - public get meta(): M { - return this.metadata.Meta as M; - } - - public get alt(): undefined | string { - return this.metadata.Alt; - } - - public get mimeType(): undefined | string { - return this.metadata.mime_type; - } - - public get extension(): undefined | string { - return this.metadata.extension; - } - - /** - * Static method for creating files so that we can keep all of the audit logging for files - * in the same place. - */ - public static async create( - { - name, - fileKind, - alt, - meta, - mime, - }: { name: string; fileKind: FileKind; alt?: string; meta?: unknown; mime?: string }, - internalFileService: InternalFileService, - fileClient: FileClientImpl - ) { - const fileMeta = await fileClient.create({ - metadata: { - ...createDefaultFileAttributes(), - name, - mime_type: mime, - Alt: alt, - Meta: meta, - FileKind: fileKind.id, - extension: (mime && mimeType.getExtension(mime)) ?? undefined, - }, - }); - - const file = internalFileService.toFile(fileMeta.id, fileMeta.metadata, fileKind, fileClient); - - internalFileService.writeAuditLog( - createAuditEvent({ - action: 'create', - message: `Created file "${file.name}" of kind "${file.fileKind}" and id "${file.id}"`, - }) - ); - - return file; + private set data(v: FileJSON) { + this.metadata = v; } } diff --git a/x-pack/plugins/files/server/file/file_attributes_reducer.ts b/x-pack/plugins/files/server/file/file_attributes_reducer.ts index 93bf2f74545d97..fdb2768408af5d 100644 --- a/x-pack/plugins/files/server/file/file_attributes_reducer.ts +++ b/x-pack/plugins/files/server/file/file_attributes_reducer.ts @@ -4,8 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import moment from 'moment'; -import { FileMetadata, UpdatableFileMetadata } from '../../common'; +import { FileJSON, UpdatableFileMetadata } from '../../common'; export type Action = | { @@ -20,51 +19,32 @@ export type Action = | { action: 'uploadError'; payload?: undefined } | { action: 'updateFile'; payload: Partial }; -export function createDefaultFileAttributes(): Pick< - FileMetadata, - 'created' | 'Updated' | 'Status' -> { - const dateString = new Date().toISOString(); - return { - created: dateString, - Status: 'AWAITING_UPLOAD', - Updated: dateString, - }; -} - -export function fileAttributesReducer( - state: FileMetadata, - { action, payload }: Action -): FileMetadata { +export function fileAttributesReducer(state: FileJSON, { action, payload }: Action): FileJSON { switch (action) { case 'delete': - return { ...state, Status: 'DELETED' }; + return { ...state, status: 'DELETED' }; case 'uploading': return { ...state, - Status: 'UPLOADING', - Updated: moment().toISOString(), + status: 'UPLOADING', }; case 'uploaded': return { ...state, ...payload, - Status: 'READY', - Updated: moment().toISOString(), + status: 'READY', }; case 'uploadError': return { ...state, - Status: 'UPLOAD_ERROR', - Updated: moment().toISOString(), + status: 'UPLOAD_ERROR', }; case 'updateFile': return { ...state, name: payload.name ?? state.name, - Alt: payload.alt ?? state.Alt, - Meta: payload.meta ?? state.Meta, - Updated: moment().toISOString(), + alt: payload.alt ?? state.alt, + meta: payload.meta ?? state.meta, }; default: return state; diff --git a/x-pack/plugins/files/server/file/index.ts b/x-pack/plugins/files/server/file/index.ts index 02740d7eaab6d4..2b584945cb71f2 100644 --- a/x-pack/plugins/files/server/file/index.ts +++ b/x-pack/plugins/files/server/file/index.ts @@ -9,6 +9,6 @@ import * as fileErrors from './errors'; export { File } from './file'; export { toJSON } from './to_json'; -export { createDefaultFileAttributes, fileAttributesReducer } from './file_attributes_reducer'; +export { fileAttributesReducer } from './file_attributes_reducer'; export type { Action } from './file_attributes_reducer'; export { fileErrors }; diff --git a/x-pack/plugins/files/server/file/to_json.ts b/x-pack/plugins/files/server/file/to_json.ts index 390aa1672e06ec..98096940fe75f0 100644 --- a/x-pack/plugins/files/server/file/to_json.ts +++ b/x-pack/plugins/files/server/file/to_json.ts @@ -5,8 +5,28 @@ * 2.0. */ +import { pickBy } from 'lodash'; import type { FileMetadata, FileJSON } from '../../common/types'; +export function serializeJSON(attrs: Partial): Partial { + const { name, mimeType, size, created, updated, fileKind, status, alt, extension, meta } = attrs; + return pickBy( + { + name, + mime_type: mimeType, + size, + created, + extension, + Alt: alt, + Status: status, + Meta: meta as M, + Updated: updated, + FileKind: fileKind, + }, + (v) => v != null + ); +} + export function toJSON(id: string, attrs: FileMetadata): FileJSON { const { name, @@ -20,17 +40,20 @@ export function toJSON(id: string, attrs: FileMetadata): FileJSON>( + { + id, + name, + mimeType, + size, + created, + extension, + alt: Alt, + status: Status, + meta: Meta as M, + updated: Updated, + fileKind: FileKind, + }, + (v) => v != null + ) as FileJSON; } diff --git a/x-pack/plugins/files/server/file_client/create_es_file_client.ts b/x-pack/plugins/files/server/file_client/create_es_file_client.ts index 2ffb9bd458c6d3..9f453a6a25bfcd 100644 --- a/x-pack/plugins/files/server/file_client/create_es_file_client.ts +++ b/x-pack/plugins/files/server/file_client/create_es_file_client.ts @@ -7,7 +7,8 @@ import type { Logger, ElasticsearchClient } from '@kbn/core/server'; import { ElasticsearchBlobStorageClient } from '../blob_storage_service'; -import { FileClientImpl, FileClient } from './file_client'; +import { FileClientImpl } from './file_client'; +import type { FileClient } from './types'; import { EsIndexFilesMetadataClient } from './file_metadata_client'; const NO_FILE_KIND = 'none'; @@ -55,6 +56,9 @@ export function createEsFileClient(arg: CreateEsFileClientArgs): FileClient { maxSizeBytes, }, new EsIndexFilesMetadataClient(metadataIndex, elasticsearchClient, logger), - new ElasticsearchBlobStorageClient(elasticsearchClient, blobStorageIndex, undefined, logger) + new ElasticsearchBlobStorageClient(elasticsearchClient, blobStorageIndex, undefined, logger), + undefined, + undefined, + logger ); } diff --git a/x-pack/plugins/files/server/file_client/file_client.ts b/x-pack/plugins/files/server/file_client/file_client.ts index cc9a4a6de29946..595d0095a6625c 100644 --- a/x-pack/plugins/files/server/file_client/file_client.ts +++ b/x-pack/plugins/files/server/file_client/file_client.ts @@ -4,165 +4,170 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ +import moment from 'moment'; import { Readable } from 'stream'; +import mimeType from 'mime'; import cuid from 'cuid'; -import { FileKind, FileMetadata } from '../../common/types'; +import type { Logger } from '@kbn/core/server'; +import type { AuditLogger } from '@kbn/security-plugin/server'; +import type { + File, + FileJSON, + FileKind, + FileMetadata, + FileShareJSONWithToken, + UpdatableFileMetadata, +} from '../../common/types'; import type { FileMetadataClient } from './file_metadata_client'; import type { BlobStorageClient, UploadOptions as BlobUploadOptions, } from '../blob_storage_service'; +import { File as FileImpl } from '../file'; +import { FileShareServiceStart, InternalFileShareService } from '../file_share_service'; import { enforceMaxByteSizeTransform } from './stream_transforms'; - -export interface DeleteArgs { - /** ID of the file to delete */ - id: string; - /** - * If `true`, the file will be deleted from the blob storage. - * - * @default true - */ - hasContent?: boolean; -} - -/** - * Args to create a file - */ -export interface CreateArgs { - /** - * Unique file ID - */ - id?: string; - /** - * The file's metadata - */ - metadata: Omit & { FileKind?: string }; -} +import { createAuditEvent } from '../audit_events'; +import type { FileClient, CreateArgs, DeleteArgs, P1, ShareArgs } from './types'; +import { serializeJSON, toJSON } from '../file/to_json'; +import { createDefaultFileAttributes } from './utils'; export type UploadOptions = Omit; -/** - * Wraps the {@link FileMetadataClient} and {@link BlobStorageClient} client - * to provide basic file CRUD functionality. - * - * For now this is just a shallow type of the implementation for export purposes. - */ -export interface FileClient { - /** See {@link FileMetadata.FileKind}. */ - fileKind: string; - - /** - * See {@link FileMetadataClient.create}. - * - * @param arg - Arg to create a file. - * */ - create(arg: CreateArgs): ReturnType; - - /** - * See {@link FileMetadataClient.get} - * - * @param arg - Argument to get a file - */ - get: FileMetadataClient['get']; - - /** - * {@link FileMetadataClient.update} - * - * @param arg - Argument to get a file - */ - update: FileMetadataClient['update']; - - /** - * Delete a file. - * @param arg - Argument to delete a file - */ - delete(arg: DeleteArgs): Promise; - - /** - * See {@link BlobStorageClient.delete} - * - * @param id - Argument to delete a file - */ - deleteContent: BlobStorageClient['delete']; - - /** - * See {@link FileMetadataClient.list} - * - * @param arg - Argument to list files - */ - list: FileMetadataClient['list']; - - /** - * See {@link FileMetadataClient.find}. - * - * @param arg - Argument to find files - */ - find: FileMetadataClient['find']; - - /** - * See {@link BlobStorageClient.upload} - * - * @param id - Readable stream to upload - * @param rs - Readable stream to upload - * @param opts - Argument for uploads - */ - upload(id: string, rs: Readable, opts?: UploadOptions): ReturnType; - - /** - * See {@link BlobStorageClient.download} - * - * @param args - to download a file - */ - download: BlobStorageClient['download']; +export function createFileClient({ + fileKindDescriptor, + auditLogger, + blobStorageClient, + internalFileShareService, + logger, + metadataClient, +}: { + fileKindDescriptor: FileKind; + metadataClient: FileMetadataClient; + blobStorageClient: BlobStorageClient; + internalFileShareService: undefined | InternalFileShareService; + auditLogger: undefined | AuditLogger; + logger: Logger; +}) { + return new FileClientImpl( + fileKindDescriptor, + metadataClient, + blobStorageClient, + internalFileShareService, + auditLogger, + logger + ); } + export class FileClientImpl implements FileClient { + private readonly logAuditEvent: AuditLogger['log']; + constructor( private fileKindDescriptor: FileKind, private readonly metadataClient: FileMetadataClient, - private readonly blobStorageClient: BlobStorageClient - ) {} + private readonly blobStorageClient: BlobStorageClient, + private readonly internalFileShareService: undefined | InternalFileShareService, + auditLogger: undefined | AuditLogger, + private readonly logger: Logger + ) { + this.logAuditEvent = (e) => { + if (auditLogger) { + auditLogger.log(e); + } else if (e) { + this.logger.info(JSON.stringify(e.event, null, 2)); + } + }; + } + + private instantiateFile(id: string, metadata: FileMetadata): File { + return new FileImpl( + id, + toJSON(id, { + ...createDefaultFileAttributes(), + ...metadata, + }), + this, + this.logger + ); + } public get fileKind(): string { return this.fileKindDescriptor.id; } - public create = async ({ - id, - metadata, - }: CreateArgs): ReturnType => { - return this.metadataClient.create({ + public async create({ id, metadata }: CreateArgs): Promise> { + const serializedMetadata = serializeJSON({ ...metadata, mimeType: metadata.mime }); + const result = await this.metadataClient.create({ id: id || cuid(), metadata: { + ...createDefaultFileAttributes(), + ...serializedMetadata, + name: serializedMetadata.name!, + extension: + (serializedMetadata.mime_type && mimeType.getExtension(serializedMetadata.mime_type)) ?? + undefined, FileKind: this.fileKind, - ...metadata, }, }); - }; + this.logAuditEvent( + createAuditEvent({ + action: 'create', + message: `Created file "${result.metadata.name}" of kind "${this.fileKind}" and id "${result.id}"`, + }) + ); + return this.instantiateFile(result.id, { + ...result.metadata, + FileKind: this.fileKind, + }) as File; + } - public get: FileMetadataClient['get'] = async (arg) => { - return this.metadataClient.get(arg); - }; + public async get(arg: P1): Promise> { + const { id, metadata } = await this.metadataClient.get(arg); + return this.instantiateFile(id, metadata as FileMetadata); + } - public update: FileMetadataClient['update'] = (arg) => { - return this.metadataClient.update(arg); - }; + public async internalUpdate(id: string, metadata: Partial): Promise { + await this.metadataClient.update({ id, metadata: serializeJSON(metadata) }); + } - public find: FileMetadataClient['find'] = (arg) => { - return this.metadataClient.find(arg); - }; + public async update(id: string, metadata: UpdatableFileMetadata): Promise { + const { alt, meta, name } = metadata; + const payload = { name, alt, meta, updated: moment().toISOString() }; + await this.internalUpdate(id, payload); + } + + public async find(arg: P1): Promise>> { + return this.metadataClient + .find(arg) + .then((r) => + r.map(({ id, metadata }) => this.instantiateFile(id, metadata as FileMetadata)) + ); + } public async delete({ id, hasContent = true }: DeleteArgs) { + if (this.internalFileShareService) { + // Stop sharing this file + await this.internalFileShareService.deleteForFile({ id }); + } if (hasContent) await this.blobStorageClient.delete(id); - return this.metadataClient.delete({ id }); + await this.metadataClient.delete({ id }); + this.logAuditEvent( + createAuditEvent({ + action: 'delete', + outcome: 'success', + message: `Deleted file with "${id}"`, + }) + ); } public deleteContent: BlobStorageClient['delete'] = (arg) => { return this.blobStorageClient.delete(arg); }; - public list: FileMetadataClient['list'] = (arg) => { - return this.metadataClient.list(arg); - }; + public async list(arg?: P1): Promise { + return this.metadataClient + .list(arg) + .then((r) => r.map(({ id, metadata }) => this.instantiateFile(id, metadata))); + } /** * Upload a blob @@ -188,4 +193,45 @@ export class FileClientImpl implements FileClient { public download: BlobStorageClient['download'] = (args) => { return this.blobStorageClient.download(args); }; + + async share({ file, name, validUntil }: ShareArgs): Promise { + if (!this.internalFileShareService) { + throw new Error('#share not implemented'); + } + const shareObject = await this.internalFileShareService.share({ + file, + name, + validUntil, + }); + this.logAuditEvent( + createAuditEvent({ + action: 'create', + message: `Shared file "${file.data.name}" with id "${file.data.id}"`, + }) + ); + return shareObject; + } + + unshare: FileShareServiceStart['delete'] = async (arg) => { + if (!this.internalFileShareService) { + throw new Error('#delete shares is not implemented'); + } + const result = await this.internalFileShareService.delete(arg); + + this.logAuditEvent( + createAuditEvent({ + action: 'delete', + message: `Removed share with id "${arg.id}"`, + }) + ); + + return result; + }; + + listShares: FileShareServiceStart['list'] = (args) => { + if (!this.internalFileShareService) { + throw new Error('#list shares not implemented'); + } + return this.internalFileShareService.list(args); + }; } diff --git a/x-pack/plugins/files/server/file_client/index.ts b/x-pack/plugins/files/server/file_client/index.ts index 2f764a53224e4d..cb9c2187bc9965 100644 --- a/x-pack/plugins/files/server/file_client/index.ts +++ b/x-pack/plugins/files/server/file_client/index.ts @@ -17,6 +17,12 @@ export type { UpdateMetadataArg, } from './file_metadata_client'; export { FileClientImpl } from './file_client'; -export type { FileClient } from './file_client'; +export type { FileClient } from './types'; export { createEsFileClient } from './create_es_file_client'; export type { CreateEsFileClientArgs } from './create_es_file_client'; +export { + AlreadyDeletedError, + ContentAlreadyUploadedError, + NoDownloadAvailableError, + UploadInProgressError, +} from '../file/errors'; diff --git a/x-pack/plugins/files/server/file_client/integration_tests/es_file_client.test.ts b/x-pack/plugins/files/server/file_client/integration_tests/es_file_client.test.ts index 3ab200533c6dad..19abeafa786dc7 100644 --- a/x-pack/plugins/files/server/file_client/integration_tests/es_file_client.test.ts +++ b/x-pack/plugins/files/server/file_client/integration_tests/es_file_client.test.ts @@ -8,7 +8,8 @@ import { Readable } from 'stream'; import { loggingSystemMock } from '@kbn/core/server/mocks'; import { TestEnvironmentUtils, setupIntegrationEnvironment } from '../../test_utils'; import { createEsFileClient } from '../create_es_file_client'; -import { FileClient } from '../file_client'; +import { FileClient } from '../types'; +import { FileMetadata } from '../../../common'; /** * This file client is using Elasticsearch interfaces directly to manage files. @@ -17,6 +18,8 @@ describe('ES-index-backed file client', () => { let esClient: TestEnvironmentUtils['esClient']; let fileClient: FileClient; let testHarness: TestEnvironmentUtils; + const blobStorageIndex = '.kibana-test-blob'; + const metadataIndex = '.kibana-test-metadata'; beforeAll(async () => { testHarness = await setupIntegrationEnvironment(); @@ -25,8 +28,8 @@ describe('ES-index-backed file client', () => { beforeEach(() => { fileClient = createEsFileClient({ - blobStorageIndex: '.kibana-test-blob', - metadataIndex: '.kibana-test-metadata', + blobStorageIndex, + metadataIndex, elasticsearchClient: esClient, logger: loggingSystemMock.create().get(), }); @@ -40,64 +43,46 @@ describe('ES-index-backed file client', () => { const file = await fileClient.create({ id: '123', metadata: { - Status: 'AWAITING_UPLOAD', - created: new Date().toISOString(), - Updated: new Date().toISOString(), name: 'cool name', }, }); - expect(file).toEqual( + expect(file.toJSON()).toEqual( expect.objectContaining({ id: '123', - metadata: { - FileKind: 'none', - Status: 'AWAITING_UPLOAD', - Updated: expect.any(String), - created: expect.any(String), - name: 'cool name', - }, + fileKind: 'none', + status: 'AWAITING_UPLOAD', + updated: expect.any(String), + created: expect.any(String), + name: 'cool name', }) ); await fileClient.delete({ id: file.id, hasContent: false }); }); test('uploads and downloads file content', async () => { - let { id, metadata } = await fileClient.create({ + const file = await fileClient.create({ id: '123', metadata: { - Status: 'AWAITING_UPLOAD', - created: new Date().toISOString(), - Updated: new Date().toISOString(), name: 'cool name', }, }); - - const { size } = await fileClient.upload(id, Readable.from([Buffer.from('test')])); - ({ id, metadata } = await fileClient.update({ - id, - metadata: { ...metadata, size, Status: 'READY' }, - })); - - const file = await fileClient.get({ id }); - const rs = await fileClient.download({ id: file.id, size: file.metadata.size }); + await file.uploadContent(Readable.from([Buffer.from('test')])); + const rs = await file.downloadContent(); const chunks: Buffer[] = []; for await (const chunk of rs) { chunks.push(chunk); } expect(Buffer.concat(chunks).toString('utf-8')).toBe('test'); - await fileClient.delete({ id, hasContent: true }); + await fileClient.delete({ id: file.id, hasContent: true }); }); test('searches across files', async () => { const { id: id1 } = await fileClient.create({ id: '123', metadata: { - Status: 'AWAITING_UPLOAD', - created: new Date().toISOString(), - Updated: new Date().toISOString(), name: 'cool name 1', - Meta: { + meta: { test: '1', }, }, @@ -105,28 +90,24 @@ describe('ES-index-backed file client', () => { const { id: id2 } = await fileClient.create({ id: '1234', metadata: { - Status: 'UPLOADING', - created: new Date().toISOString(), - Updated: new Date().toISOString(), name: 'cool name 2', - Meta: { + meta: { test: '2', }, }, }); - const { id: id3 } = await fileClient.create({ + const file3 = await fileClient.create({ id: '12345', metadata: { - Status: 'READY', - created: new Date().toISOString(), - Updated: new Date().toISOString(), name: 'cool name 3', - Meta: { + meta: { test: '3', }, }, }); + await file3.uploadContent(Readable.from(['test'])); + { const results = await fileClient.find({ status: ['READY'], @@ -137,7 +118,7 @@ describe('ES-index-backed file client', () => { expect(results[0]).toEqual( expect.objectContaining({ - id: id3, + id: file3.id, }) ); } @@ -147,7 +128,7 @@ describe('ES-index-backed file client', () => { status: ['READY', 'AWAITING_UPLOAD'], }); - expect(results).toHaveLength(2); + expect(results).toHaveLength(3); expect(results[0]).toEqual( expect.objectContaining({ @@ -157,7 +138,13 @@ describe('ES-index-backed file client', () => { expect(results[1]).toEqual( expect.objectContaining({ - id: id3, + id: id2, + }) + ); + + expect(results[2]).toEqual( + expect.objectContaining({ + id: file3.id, }) ); } @@ -165,7 +152,7 @@ describe('ES-index-backed file client', () => { await Promise.all([ fileClient.delete({ id: id1 }), fileClient.delete({ id: id2 }), - fileClient.delete({ id: id3 }), + fileClient.delete({ id: file3.id }), ]); }); @@ -173,24 +160,23 @@ describe('ES-index-backed file client', () => { const { id: id1 } = await fileClient.create({ id: '123', metadata: { - Status: 'AWAITING_UPLOAD', - created: new Date().toISOString(), - Updated: new Date().toISOString(), name: 'cool name 1', - Meta: { + meta: { test: '1', }, }, }); - const { id: id2 } = await fileClient.create({ - id: '1234', - metadata: { - Status: 'DELETED', - created: new Date().toISOString(), - Updated: new Date().toISOString(), - name: 'cool name 2', - Meta: { - test: '2', + const id2 = '1234'; + await esClient.index<{ file: FileMetadata }>({ + id: id2, + index: metadataIndex, + document: { + file: { + FileKind: 'none', + Status: 'DELETED', + Updated: new Date().toISOString(), + created: new Date().toISOString(), + name: 'coolname', }, }, }); @@ -198,17 +184,15 @@ describe('ES-index-backed file client', () => { const list = await fileClient.list(); expect(list).toHaveLength(1); - expect(list[0]).toEqual( + expect(list[0].toJSON()).toEqual( expect.objectContaining({ id: '123', - metadata: { - FileKind: 'none', - Meta: { test: '1' }, - Status: 'AWAITING_UPLOAD', - Updated: expect.any(String), - created: expect.any(String), - name: 'cool name 1', - }, + fileKind: 'none', + meta: { test: '1' }, + status: 'AWAITING_UPLOAD', + updated: expect.any(String), + created: expect.any(String), + name: 'cool name 1', }) ); diff --git a/x-pack/plugins/files/server/file_client/types.ts b/x-pack/plugins/files/server/file_client/types.ts new file mode 100644 index 00000000000000..bbab0066cf3f0f --- /dev/null +++ b/x-pack/plugins/files/server/file_client/types.ts @@ -0,0 +1,134 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { File, FileShareJSONWithToken, UpdatableFileMetadata } from '../../common/types'; +import { CreateFileArgs } from '../file_service'; +import { FileShareServiceStart } from '../file_share_service'; +import { FileMetadataClient } from './file_metadata_client'; + +export type P1 any> = Parameters[0]; + +export interface DeleteArgs { + /** ID of the file to delete */ + id: string; + /** + * If `true`, the file will be deleted from the blob storage. + * + * @default true + */ + hasContent?: boolean; +} + +/** + * Args to create a file + */ +export interface CreateArgs { + /** + * Unique file ID + */ + id?: string; + /** + * The file's metadata + */ + metadata: Omit; +} + +/** + * File share args + */ +export interface ShareArgs { + /** + * Name of the file share + */ + name?: string; + /** + * Unix timestamp (in milliseconds) when the file share will expire + */ + validUntil?: number; + /** + * The file to share + */ + file: File; +} + +/** + * Wraps the {@link FileMetadataClient} and {@link BlobStorageClient} client + * to provide basic file CRUD functionality. + * + * For now this is just a shallow type of the implementation for export purposes. + */ +export interface FileClient { + /** See {@link FileMetadata.FileKind}. */ + fileKind: string; + + /** + * See {@link FileMetadataClient.create}. + * + * @param arg - Arg to create a file. + * */ + create(arg: CreateArgs): Promise>; + + /** + * See {@link FileMetadataClient.get} + * + * @param arg - Argument to get a file + */ + get(arg: P1): Promise>; + + /** + * {@link FileMetadataClient.update} + * + * @param id - File id + * @param metadata - new file metadata + */ + update(id: string, metadata: UpdatableFileMetadata): Promise; + + /** + * Delete a file. + * @param arg - Argument to delete a file + */ + delete(arg: DeleteArgs): Promise; + + /** + * See {@link FileMetadataClient.list} + * + * @param arg - Argument to list files + */ + list(arg?: P1): Promise; + + /** + * See {@link FileMetadataClient.find}. + * + * @param arg - Argument to find files + */ + find: (arg: P1) => Promise; + + /** + * Create a file share instance for this file. + * + * @note this will only work for files that are share capable. + * + * @param args - Arguments to create a file share + */ + share(args: ShareArgs): Promise; + /** + * Create a file share instance for this file. + * + * @note this will only work for files that are share capable. + * + * @param args - Arguments to remove a file share + */ + unshare: FileShareServiceStart['delete']; + /** + * Create a file share instance for this file. + * + * @note this will only work for files that are share capable. + * + * @param arg - Arguments to remove a file share + */ + listShares: FileShareServiceStart['list']; +} diff --git a/x-pack/plugins/files/server/file_client/utils.ts b/x-pack/plugins/files/server/file_client/utils.ts new file mode 100644 index 00000000000000..b8b51117e8ac1f --- /dev/null +++ b/x-pack/plugins/files/server/file_client/utils.ts @@ -0,0 +1,20 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { FileMetadata } from '../../common'; + +export function createDefaultFileAttributes(): Pick< + FileMetadata, + 'created' | 'Updated' | 'Status' +> { + const dateString = new Date().toISOString(); + return { + created: dateString, + Status: 'AWAITING_UPLOAD', + Updated: dateString, + }; +} diff --git a/x-pack/plugins/files/server/file_service/file_service.ts b/x-pack/plugins/files/server/file_service/file_service.ts index 90303ac715437d..f8d8534b7a635b 100644 --- a/x-pack/plugins/files/server/file_service/file_service.ts +++ b/x-pack/plugins/files/server/file_service/file_service.ts @@ -5,7 +5,7 @@ * 2.0. */ -import type { File, FileJSON, FilesMetrics } from '../../common'; +import type { FileJSON, FilesMetrics, File } from '../../common'; import type { FileShareServiceStart } from '../file_share_service/types'; import type { CreateFileArgs, @@ -34,7 +34,7 @@ export interface FileServiceStart { * * @param args - update file args */ - update(args: UpdateFileArgs): Promise>; + update(args: UpdateFileArgs): Promise; /** * Delete a file. diff --git a/x-pack/plugins/files/server/file_service/file_service_factory.ts b/x-pack/plugins/files/server/file_service/file_service_factory.ts index bed007b00e5071..b6603a43f8720c 100644 --- a/x-pack/plugins/files/server/file_service/file_service_factory.ts +++ b/x-pack/plugins/files/server/file_service/file_service_factory.ts @@ -95,7 +95,7 @@ export class FileServiceFactoryImpl implements FileServiceFactory { return internalFileService.createFile(args) as Promise>; }, async update(args: UpdateFileArgs) { - return internalFileService.updateFile(args) as Promise>; + await internalFileService.updateFile(args); }, async delete(args) { return internalFileService.deleteFile(args); diff --git a/x-pack/plugins/files/server/file_service/internal_file_service.ts b/x-pack/plugins/files/server/file_service/internal_file_service.ts index 567df3e1378485..a7ba92db9b2e8c 100644 --- a/x-pack/plugins/files/server/file_service/internal_file_service.ts +++ b/x-pack/plugins/files/server/file_service/internal_file_service.ts @@ -23,7 +23,7 @@ import type { GetByIdArgs, ListFilesArgs, } from './file_action_types'; -import { FileClientImpl } from '../file_client/file_client'; +import { createFileClient, FileClientImpl } from '../file_client/file_client'; /** * Service containing methods for working with files. * @@ -42,16 +42,7 @@ export class InternalFileService { ) {} public async createFile(args: CreateFileArgs): Promise { - const fileKind = this.getFileKind(args.fileKind); - return await File.create( - { ...args, fileKind }, - this, - new FileClientImpl( - fileKind, - this.metadataClient, - this.blobStorageService.createBlobStorageClient(fileKind.blobStoreSettings) - ) - ); + return this.createFileClient(args.fileKind).create({ metadata: { ...args } }); } public writeAuditLog(event: AuditEvent) { @@ -79,7 +70,7 @@ export class InternalFileService { if (metadata.Status === 'DELETED') { throw new FileNotFoundError('File has been deleted'); } - return this.toFile(id, metadata, this.getFileKind(metadata.FileKind)); + return this.toFile(id, metadata, metadata.FileKind); } catch (e) { if (SavedObjectsErrorHelpers.isNotFoundError(e)) { throw new FileNotFoundError('File not found'); @@ -91,8 +82,8 @@ export class InternalFileService { public async getById({ fileKind, id }: GetByIdArgs): Promise { const file = await this.get(id); - if (file.fileKind !== fileKind) { - throw new Error(`Unexpected file kind "${file.fileKind}", expected "${fileKind}".`); + if (file.data.fileKind !== fileKind) { + throw new Error(`Unexpected file kind "${file.data.fileKind}", expected "${fileKind}".`); } return file; } @@ -108,28 +99,8 @@ export class InternalFileService { page, perPage, }); - return result.map((file) => this.toFile(file.id, file.metadata, fileKind)); - } - - public toFile( - id: string, - fileMetadata: FileMetadata, - fileKind: FileKind, - fileClient?: FileClientImpl - ): IFile { - return new File( - id, - fileMetadata, - fileClient ?? - new FileClientImpl( - fileKind, - this.metadataClient, - this.blobStorageService.createBlobStorageClient(fileKind.blobStoreSettings) - ), - this, - this.fileShareService, - this.logger.get(`file-${id}`) - ); + const fileClient = this.createFileClient(fileKind.id); + return result.map((file) => this.toFile(file.id, file.metadata, fileKind.id, fileClient)); } public getFileKind(id: string): FileKind { @@ -153,4 +124,32 @@ export class InternalFileService { const { fileId } = await this.fileShareService.getByToken(token); return this.get(fileId); } + + private toFile( + id: string, + fileMetadata: FileMetadata, + fileKind: string, + fileClient?: FileClientImpl + ): IFile { + return new File( + id, + toJSON(id, fileMetadata), + fileClient ?? this.createFileClient(fileKind), + this.logger.get(`file-${id}`) + ); + } + + private createFileClient(fileKindId: string) { + const fileKind = this.fileKindRegistry.get(fileKindId); + return createFileClient({ + auditLogger: this.auditLogger, + blobStorageClient: this.blobStorageService.createBlobStorageClient( + fileKind.blobStoreSettings + ), + fileKindDescriptor: fileKind, + internalFileShareService: this.fileShareService, + logger: this.logger, + metadataClient: this.metadataClient, + }); + } } diff --git a/x-pack/plugins/files/server/file_share_service/internal_file_share_service.ts b/x-pack/plugins/files/server/file_share_service/internal_file_share_service.ts index 7b6f8498b0e3ec..6c9e09e5173b40 100644 --- a/x-pack/plugins/files/server/file_share_service/internal_file_share_service.ts +++ b/x-pack/plugins/files/server/file_share_service/internal_file_share_service.ts @@ -85,9 +85,9 @@ export type GetArgs = IdArg; */ export interface DeleteForFileArgs { /** - * The file object to delete the shares for. + * The file id to delete the shares for. */ - file: File; + id: string; } /** @@ -144,7 +144,7 @@ export class InternalFileShareService implements FileShareServiceStart { token: generateShareToken(), }, { - references: [{ name: file.name, id: file.id, type: FILE_SO_TYPE }], + references: [{ name: file.data.name, id: file.data.id, type: FILE_SO_TYPE }], } ); @@ -183,8 +183,8 @@ export class InternalFileShareService implements FileShareServiceStart { return result.saved_objects; } - public async deleteForFile({ file }: DeleteForFileArgs): Promise { - const savedObjects = await this.internalList({ fileId: file.id }); + public async deleteForFile({ id: fileId }: DeleteForFileArgs): Promise { + const savedObjects = await this.internalList({ fileId }); await Promise.all(savedObjects.map(({ id }) => this.delete({ id }))); } diff --git a/x-pack/plugins/files/server/integration_tests/file_service.test.ts b/x-pack/plugins/files/server/integration_tests/file_service.test.ts index 0547fe0ed30fbc..61196597cc5f97 100644 --- a/x-pack/plugins/files/server/integration_tests/file_service.test.ts +++ b/x-pack/plugins/files/server/integration_tests/file_service.test.ts @@ -107,9 +107,9 @@ describe('FileService', () => { it('creates file metadata awaiting upload', async () => { const file = await createDisposableFile({ fileKind, name: 'test' }); - expect(file.name).toEqual('test'); - expect(file.fileKind).toEqual(fileKind); - expect(file.status).toBe('AWAITING_UPLOAD' as FileStatus); + expect(file.data.name).toEqual('test'); + expect(file.data.fileKind).toEqual(fileKind); + expect(file.data.status).toBe('AWAITING_UPLOAD' as FileStatus); expect(auditLogger.log).toHaveBeenCalledTimes(1); expect(auditLogger.log).toHaveBeenCalledWith({ error: undefined, @@ -123,9 +123,9 @@ describe('FileService', () => { it('uploads file content', async () => { const file = await createDisposableFile({ fileKind, name: 'test' }); - expect(file.status).toBe('AWAITING_UPLOAD' as FileStatus); + expect(file.data.status).toBe('AWAITING_UPLOAD' as FileStatus); await file.uploadContent(Readable.from(['upload this'])); - expect(file.status).toBe('READY' as FileStatus); + expect(file.data.status).toBe('READY' as FileStatus); const rs = await file.downloadContent(); const chunks: string[] = []; for await (const chunk of rs) { @@ -170,17 +170,17 @@ describe('FileService', () => { meta: { some: 'data' }, }; const updatedFile1 = await file.update(updatableFields); - expect(updatedFile1.meta).toEqual(expect.objectContaining(updatableFields.meta)); - expect(updatedFile1.name).toBe(updatableFields.name); - expect(updatedFile1.alt).toBe(updatableFields.alt); + expect(updatedFile1.data.meta).toEqual(expect.objectContaining(updatableFields.meta)); + expect(updatedFile1.data.name).toBe(updatableFields.name); + expect(updatedFile1.data.alt).toBe(updatableFields.alt); // Fetch the file anew to be doubly sure const updatedFile2 = await fileService.getById({ fileKind, id: file.id }); - expect(updatedFile2.meta).toEqual(expect.objectContaining(updatableFields.meta)); + expect(updatedFile2.data.meta).toEqual(expect.objectContaining(updatableFields.meta)); // Below also tests that our meta type is work as expected by using `some` field. - expect(updatedFile2.meta?.some).toBe(updatableFields.meta.some); - expect(updatedFile2.name).toBe(updatableFields.name); - expect(updatedFile2.alt).toBe(updatableFields.alt); + expect(updatedFile2.data.meta?.some).toBe(updatableFields.meta.some); + expect(updatedFile2.data.name).toBe(updatableFields.name); + expect(updatedFile2.data.alt).toBe(updatableFields.alt); }); it('enforces max size settings', async () => { @@ -339,7 +339,7 @@ describe('FileService', () => { action: 'delete', outcome: 'success', }, - message: expect.stringContaining('Removed share for "myfile"'), + message: expect.stringContaining('Removed share with'), }); }); }); diff --git a/x-pack/plugins/files/server/routes/common.test.ts b/x-pack/plugins/files/server/routes/common.test.ts index cda57b5b6bf135..cc22b0d8afb01c 100644 --- a/x-pack/plugins/files/server/routes/common.test.ts +++ b/x-pack/plugins/files/server/routes/common.test.ts @@ -16,7 +16,7 @@ describe('getDownloadHeadersForFile', () => { }; } - const file = { name: 'test', mimeType: undefined } as unknown as File; + const file = { data: { name: 'test', mimeType: undefined } } as unknown as File; test('no mime type and name from file object', () => { expect(getDownloadHeadersForFile(file, undefined)).toEqual( t({ ct: 'application/octet-stream', cd: 'test' }) @@ -34,13 +34,13 @@ describe('getDownloadHeadersForFile', () => { ); }); test('mime type and no name', () => { - const fileWithMime = { ...file, mimeType: 'application/pdf' } as File; + const fileWithMime = { data: { ...file.data, mimeType: 'application/pdf' } } as File; expect(getDownloadHeadersForFile(fileWithMime, undefined)).toEqual( t({ ct: 'application/pdf', cd: 'test' }) ); }); test('mime type and name', () => { - const fileWithMime = { ...file, mimeType: 'application/pdf' } as File; + const fileWithMime = { data: { ...file.data, mimeType: 'application/pdf' } } as File; expect(getDownloadHeadersForFile(fileWithMime, 'a cool file.pdf')).toEqual( t({ ct: 'application/pdf', cd: 'a cool file.pdf' }) ); diff --git a/x-pack/plugins/files/server/routes/common.ts b/x-pack/plugins/files/server/routes/common.ts index 23f702493c92d2..f8a3a1965267b5 100644 --- a/x-pack/plugins/files/server/routes/common.ts +++ b/x-pack/plugins/files/server/routes/common.ts @@ -11,7 +11,7 @@ import type { File } from '../../common/types'; export function getDownloadHeadersForFile(file: File, fileName?: string): ResponseHeaders { return { 'content-type': - (fileName && mime.getType(fileName)) ?? file.mimeType ?? 'application/octet-stream', + (fileName && mime.getType(fileName)) ?? file.data.mimeType ?? 'application/octet-stream', // Note, this name can be overridden by the client if set via a "download" attribute on the HTML tag. 'content-disposition': `attachment; filename="${fileName || getDownloadedFileName(file)}"`, }; @@ -20,8 +20,8 @@ export function getDownloadHeadersForFile(file: File, fileName?: string): Respon export function getDownloadedFileName(file: File): string { // When creating a file we also calculate the extension so the `file.extension` // check is not really necessary except for type checking. - if (file.mimeType && file.extension) { - return `${file.name}.${file.extension}`; + if (file.data.mimeType && file.data.extension) { + return `${file.data.name}.${file.data.extension}`; } - return file.name; + return file.data.name; } diff --git a/x-pack/plugins/files/server/routes/file_kind/upload.ts b/x-pack/plugins/files/server/routes/file_kind/upload.ts index 7b3db76ad38ad6..c563cddad48779 100644 --- a/x-pack/plugins/files/server/routes/file_kind/upload.ts +++ b/x-pack/plugins/files/server/routes/file_kind/upload.ts @@ -50,10 +50,12 @@ export const handler: FileKindsRequestHandler = async ( } throw e; } - const body: Response = { ok: true, size: file.size! }; + const body: Response = { ok: true, size: file.data.size! }; return res.ok({ body }); }; +const fourMiB = 4 * 1024 * 1024; + export function register(fileKindRouter: FileKindRouter, fileKind: FileKind) { if (fileKind.http.create) { fileKindRouter[method]( @@ -69,6 +71,7 @@ export function register(fileKindRouter: FileKindRouter, fileKind: FileKind) { output: 'stream', parse: false, accepts: fileKind.allowedMimeTypes ?? 'application/octet-stream', + maxBytes: fileKind.maxSizeBytes ?? fourMiB, }, }, }, diff --git a/x-pack/plugins/fleet/common/constants/routes.ts b/x-pack/plugins/fleet/common/constants/routes.ts index d46a5f23ddf086..b415328a303d3c 100644 --- a/x-pack/plugins/fleet/common/constants/routes.ts +++ b/x-pack/plugins/fleet/common/constants/routes.ts @@ -49,6 +49,7 @@ export const DATA_STREAM_API_ROUTES = { // Package policy API routes export const PACKAGE_POLICY_API_ROUTES = { LIST_PATTERN: `${PACKAGE_POLICY_API_ROOT}`, + BULK_GET_PATTERN: `${PACKAGE_POLICY_API_ROOT}/_bulk_get`, INFO_PATTERN: `${PACKAGE_POLICY_API_ROOT}/{packagePolicyId}`, CREATE_PATTERN: `${PACKAGE_POLICY_API_ROOT}`, UPDATE_PATTERN: `${PACKAGE_POLICY_API_ROOT}/{packagePolicyId}`, @@ -61,6 +62,7 @@ export const PACKAGE_POLICY_API_ROUTES = { // Agent policy API routes export const AGENT_POLICY_API_ROUTES = { LIST_PATTERN: `${AGENT_POLICY_API_ROOT}`, + BULK_GET_PATTERN: `${AGENT_POLICY_API_ROOT}/_bulk_get`, INFO_PATTERN: `${AGENT_POLICY_API_ROOT}/{agentPolicyId}`, CREATE_PATTERN: `${AGENT_POLICY_API_ROOT}`, UPDATE_PATTERN: `${AGENT_POLICY_API_ROOT}/{agentPolicyId}`, diff --git a/x-pack/plugins/fleet/common/index.ts b/x-pack/plugins/fleet/common/index.ts index ced5c17f55f6ff..d514d5b5646901 100644 --- a/x-pack/plugins/fleet/common/index.ts +++ b/x-pack/plugins/fleet/common/index.ts @@ -101,6 +101,8 @@ export type { UpgradePackagePolicyResponseItem, UpgradePackagePolicyBaseResponse, UpgradePackagePolicyDryRunResponseItem, + BulkGetPackagePoliciesResponse, + BulkGetAgentPoliciesResponse, // Models Agent, AgentStatus, diff --git a/x-pack/plugins/fleet/common/openapi/bundled.json b/x-pack/plugins/fleet/common/openapi/bundled.json index f7d5054f532245..adb49b25782cdb 100644 --- a/x-pack/plugins/fleet/common/openapi/bundled.json +++ b/x-pack/plugins/fleet/common/openapi/bundled.json @@ -2215,6 +2215,66 @@ } } }, + "/agent_policies/_bulk_get": { + "post": { + "summary": "Agent policies - Bulk Get", + "tags": [], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "ids": { + "type": "array", + "items": { + "type": "string" + }, + "description": "list of agent policy ids" + }, + "full": { + "type": "boolean", + "description": "get full policies with package policies populated" + }, + "ignoreMissing": { + "type": "boolean" + } + }, + "required": [ + "ids" + ] + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/agent_policy" + } + } + }, + "required": [ + "items" + ] + } + } + } + } + }, + "operationId": "bulk-get-agent-policies", + "security": [], + "parameters": [] + } + }, "/agent_policies/delete": { "post": { "summary": "Agent policy - Delete", @@ -2706,6 +2766,62 @@ ] } }, + "/package_policies/_bulk_get": { + "post": { + "summary": "Package policies - Bulk Get", + "tags": [], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "ids": { + "type": "array", + "items": { + "type": "string" + }, + "description": "list of package policy ids" + }, + "ignoreMissing": { + "type": "boolean" + } + }, + "required": [ + "ids" + ] + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/package_policy" + } + } + }, + "required": [ + "items" + ] + } + } + } + } + }, + "operationId": "bulk-get-package-policies", + "security": [], + "parameters": [] + } + }, "/package_policies/delete": { "post": { "summary": "Package policy - Delete", diff --git a/x-pack/plugins/fleet/common/openapi/bundled.yaml b/x-pack/plugins/fleet/common/openapi/bundled.yaml index 60827666ca5e87..3cc16afc3f4105 100644 --- a/x-pack/plugins/fleet/common/openapi/bundled.yaml +++ b/x-pack/plugins/fleet/common/openapi/bundled.yaml @@ -1355,6 +1355,45 @@ paths: required: - name description: '' + /agent_policies/_bulk_get: + post: + summary: Agent policies - Bulk Get + tags: [] + requestBody: + content: + application/json: + schema: + type: object + properties: + ids: + type: array + items: + type: string + description: list of agent policy ids + full: + type: boolean + description: get full policies with package policies populated + ignoreMissing: + type: boolean + required: + - ids + responses: + '200': + description: OK + content: + application/json: + schema: + type: object + properties: + items: + type: array + items: + $ref: '#/components/schemas/agent_policy' + required: + - items + operationId: bulk-get-agent-policies + security: [] + parameters: [] /agent_policies/delete: post: summary: Agent policy - Delete @@ -1662,6 +1701,42 @@ paths: type: boolean parameters: - $ref: '#/components/parameters/kbn_xsrf' + /package_policies/_bulk_get: + post: + summary: Package policies - Bulk Get + tags: [] + requestBody: + content: + application/json: + schema: + type: object + properties: + ids: + type: array + items: + type: string + description: list of package policy ids + ignoreMissing: + type: boolean + required: + - ids + responses: + '200': + description: OK + content: + application/json: + schema: + type: object + properties: + items: + type: array + items: + $ref: '#/components/schemas/package_policy' + required: + - items + operationId: bulk-get-package-policies + security: [] + parameters: [] /package_policies/delete: post: summary: Package policy - Delete diff --git a/x-pack/plugins/fleet/common/openapi/entrypoint.yaml b/x-pack/plugins/fleet/common/openapi/entrypoint.yaml index 316ffa6e5679a9..2756656e189f2a 100644 --- a/x-pack/plugins/fleet/common/openapi/entrypoint.yaml +++ b/x-pack/plugins/fleet/common/openapi/entrypoint.yaml @@ -82,6 +82,8 @@ paths: $ref: 'paths/agent_policies@{agent_policy_id}.yaml' '/agent_policies/{agentPolicyId}/copy': $ref: 'paths/agent_policies@{agent_policy_id}@copy.yaml' + /agent_policies/_bulk_get: + $ref: paths/agent_policies@_bulk_get.yaml /agent_policies/delete: $ref: paths/agent_policies@delete.yaml # Data streams endpoints @@ -99,6 +101,8 @@ paths: # Package policies endpoints /package_policies: $ref: paths/package_policies.yaml + /package_policies/_bulk_get: + $ref: paths/package_policies@_bulk_get.yaml /package_policies/delete: $ref: paths/package_policies@delete.yaml /package_policies/upgrade: diff --git a/x-pack/plugins/fleet/common/openapi/paths/agent_policies@_bulk_get.yaml b/x-pack/plugins/fleet/common/openapi/paths/agent_policies@_bulk_get.yaml new file mode 100644 index 00000000000000..0ac58fffba167a --- /dev/null +++ b/x-pack/plugins/fleet/common/openapi/paths/agent_policies@_bulk_get.yaml @@ -0,0 +1,38 @@ +post: + summary: Agent policies - Bulk Get + tags: [] + requestBody: + content: + application/json: + schema: + type: object + properties: + ids: + type: array + items: + type: string + description: list of agent policy ids + full: + type: boolean + description: get full policies with package policies populated + ignoreMissing: + type: boolean + required: + - ids + responses: + '200': + description: OK + content: + application/json: + schema: + type: object + properties: + items: + type: array + items: + $ref: ../components/schemas/agent_policy.yaml + required: + - items + operationId: bulk-get-agent-policies + security: [] + parameters: [] diff --git a/x-pack/plugins/fleet/common/openapi/paths/package_policies@_bulk_get.yaml b/x-pack/plugins/fleet/common/openapi/paths/package_policies@_bulk_get.yaml new file mode 100644 index 00000000000000..70d54b12e47eb7 --- /dev/null +++ b/x-pack/plugins/fleet/common/openapi/paths/package_policies@_bulk_get.yaml @@ -0,0 +1,35 @@ +post: + summary: Package policies - Bulk Get + tags: [] + requestBody: + content: + application/json: + schema: + type: object + properties: + ids: + type: array + items: + type: string + description: list of package policy ids + ignoreMissing: + type: boolean + required: + - ids + responses: + '200': + description: OK + content: + application/json: + schema: + type: object + properties: + items: + type: array + items: + $ref: ../components/schemas/package_policy.yaml + required: + - items + operationId: bulk-get-package-policies + security: [] + parameters: [] diff --git a/x-pack/plugins/fleet/common/services/limited_package.ts b/x-pack/plugins/fleet/common/services/limited_package.ts index 601f680c8bf039..e4e9dd090941d7 100644 --- a/x-pack/plugins/fleet/common/services/limited_package.ts +++ b/x-pack/plugins/fleet/common/services/limited_package.ts @@ -5,7 +5,7 @@ * 2.0. */ -import type { PackageInfo, AgentPolicy, PackagePolicy } from '../types'; +import type { PackageInfo, AgentPolicy } from '../types'; export const isPackageLimited = (packageInfo: PackageInfo): boolean => { return (packageInfo.policy_templates || []).some( @@ -17,10 +17,10 @@ export const doesAgentPolicyAlreadyIncludePackage = ( agentPolicy: AgentPolicy, packageName: string ): boolean => { - if (agentPolicy.package_policies.length && typeof agentPolicy.package_policies[0] === 'string') { + if (!agentPolicy.package_policies) { throw new Error('Unable to read full package policy information'); } - return (agentPolicy.package_policies as PackagePolicy[]) + return agentPolicy.package_policies .map((packagePolicy) => packagePolicy.package?.name || '') .includes(packageName); }; diff --git a/x-pack/plugins/fleet/common/services/routes.ts b/x-pack/plugins/fleet/common/services/routes.ts index 95551ddeea7c0f..323d7d1f8b3786 100644 --- a/x-pack/plugins/fleet/common/services/routes.ts +++ b/x-pack/plugins/fleet/common/services/routes.ts @@ -118,6 +118,10 @@ export const agentPolicyRouteService = { return AGENT_POLICY_API_ROUTES.LIST_PATTERN; }, + getBulkGetPath: () => { + return AGENT_POLICY_API_ROUTES.BULK_GET_PATTERN; + }, + getInfoPath: (agentPolicyId: string) => { return AGENT_POLICY_API_ROUTES.INFO_PATTERN.replace('{agentPolicyId}', agentPolicyId); }, diff --git a/x-pack/plugins/fleet/common/types/models/agent_policy.ts b/x-pack/plugins/fleet/common/types/models/agent_policy.ts index 44e6b35c02eec5..ea22f73a2e5f97 100644 --- a/x-pack/plugins/fleet/common/types/models/agent_policy.ts +++ b/x-pack/plugins/fleet/common/types/models/agent_policy.ts @@ -35,7 +35,7 @@ export interface NewAgentPolicy { export interface AgentPolicy extends Omit { id: string; status: ValueOf; - package_policies: string[] | PackagePolicy[]; + package_policies?: PackagePolicy[]; is_managed: boolean; // required for created policy updated_at: string; updated_by: string; diff --git a/x-pack/plugins/fleet/common/types/rest_spec/agent_policy.ts b/x-pack/plugins/fleet/common/types/rest_spec/agent_policy.ts index d53da769c754b6..a62b1a1b9e4e65 100644 --- a/x-pack/plugins/fleet/common/types/rest_spec/agent_policy.ts +++ b/x-pack/plugins/fleet/common/types/rest_spec/agent_policy.ts @@ -7,7 +7,7 @@ import type { AgentPolicy, NewAgentPolicy, FullAgentPolicy } from '../models'; -import type { ListResult, ListWithKuery } from './common'; +import type { ListResult, ListWithKuery, BulkGetResult } from './common'; export interface GetAgentPoliciesRequest { query: ListWithKuery & { @@ -17,6 +17,7 @@ export interface GetAgentPoliciesRequest { export type GetAgentPoliciesResponseItem = AgentPolicy & { agents?: number }; +export type BulkGetAgentPoliciesResponse = BulkGetResult; export type GetAgentPoliciesResponse = ListResult; export interface GetOneAgentPolicyRequest { diff --git a/x-pack/plugins/fleet/common/types/rest_spec/common.ts b/x-pack/plugins/fleet/common/types/rest_spec/common.ts index 7a0390d830de3e..07bd3c7019c168 100644 --- a/x-pack/plugins/fleet/common/types/rest_spec/common.ts +++ b/x-pack/plugins/fleet/common/types/rest_spec/common.ts @@ -21,3 +21,7 @@ export interface ListResult { page: number; perPage: number; } + +export interface BulkGetResult { + items: T[]; +} diff --git a/x-pack/plugins/fleet/common/types/rest_spec/package_policy.ts b/x-pack/plugins/fleet/common/types/rest_spec/package_policy.ts index 260c8ebc8142f2..c7de1bd489b475 100644 --- a/x-pack/plugins/fleet/common/types/rest_spec/package_policy.ts +++ b/x-pack/plugins/fleet/common/types/rest_spec/package_policy.ts @@ -14,13 +14,14 @@ import type { FullAgentPolicyInput, } from '../models'; -import type { ListResult, ListWithKuery } from './common'; +import type { BulkGetResult, ListResult, ListWithKuery } from './common'; export interface GetPackagePoliciesRequest { query: ListWithKuery; } export type GetPackagePoliciesResponse = ListResult; +export type BulkGetPackagePoliciesResponse = BulkGetResult; export interface GetOnePackagePolicyRequest { params: { diff --git a/x-pack/plugins/fleet/cypress/downloads/downloads.html b/x-pack/plugins/fleet/cypress/downloads/downloads.html new file mode 100644 index 00000000000000..772778ea352e58 Binary files /dev/null and b/x-pack/plugins/fleet/cypress/downloads/downloads.html differ diff --git a/x-pack/plugins/fleet/cypress/tasks/fleet.ts b/x-pack/plugins/fleet/cypress/tasks/fleet.ts index 53f2846b3a981b..4a23daf7a83809 100644 --- a/x-pack/plugins/fleet/cypress/tasks/fleet.ts +++ b/x-pack/plugins/fleet/cypress/tasks/fleet.ts @@ -15,9 +15,15 @@ import { } from '../screens/fleet'; export function createAgentPolicy() { + cy.intercept({ + url: '/api/fleet/agent_policies?sys_monitoring=true', + method: 'POST', + }).as('postAgentPolicy'); cy.getBySel(ADD_AGENT_BUTTON_TOP).click(); cy.getBySel(STANDALONE_TAB).click(); cy.getBySel(CREATE_POLICY_BUTTON).click(); + + cy.wait('@postAgentPolicy'); cy.getBySel(AGENT_FLYOUT_CLOSE_BUTTON).click(); } diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/components/steps/components/package_policy_input_stream.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/components/steps/components/package_policy_input_stream.tsx index 77734feb67e21f..1662f6d0c72140 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/components/steps/components/package_policy_input_stream.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/components/steps/components/package_policy_input_stream.tsx @@ -132,7 +132,7 @@ export const PackagePolicyInputStreamConfig: React.FunctionComponent<{ - + {packageInputStream.description} ) : null} diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/components/steps/components/package_policy_input_var_field.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/components/steps/components/package_policy_input_var_field.tsx index 327037a6f27456..812d5fc2233de4 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/components/steps/components/package_policy_input_var_field.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/components/steps/components/package_policy_input_var_field.tsx @@ -155,7 +155,7 @@ export const PackagePolicyInputVarField: React.FunctionComponent<{ ) : null } - helpText={} + helpText={description && } > {field} diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/details_page/components/package_policies/index.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/details_page/components/package_policies/index.tsx index c51a7415cd1a69..19ff6a5d00d277 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/details_page/components/package_policies/index.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/details_page/components/package_policies/index.tsx @@ -7,7 +7,7 @@ import React, { memo } from 'react'; -import type { AgentPolicy, PackagePolicy } from '../../../../../types'; +import type { AgentPolicy } from '../../../../../types'; import { useBreadcrumbs } from '../../../../../hooks'; import { NoPackagePolicies } from './no_package_policies'; @@ -16,14 +16,14 @@ import { PackagePoliciesTable } from './package_policies_table'; export const PackagePoliciesView = memo<{ agentPolicy: AgentPolicy }>(({ agentPolicy }) => { useBreadcrumbs('policy_details', { policyName: agentPolicy.name }); - if (agentPolicy.package_policies.length === 0) { + if (!agentPolicy.package_policies || agentPolicy.package_policies.length === 0) { return ; } return ( ); }); diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/list_page/index.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/list_page/index.tsx index ba6b7f4ad31c4b..9b0d9051a32ed8 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/list_page/index.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/list_page/index.tsx @@ -89,6 +89,7 @@ export const AgentPolicyListPage: React.FunctionComponent<{}> = () => { sortField: sorting?.field, sortOrder: sorting?.direction, kuery: search, + full: true, }); // Some policies retrieved, set up table props diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/index.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/index.tsx index a9e3429732b3cd..6bf9506d6ba28b 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/index.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/index.tsx @@ -19,7 +19,7 @@ import { import { i18n } from '@kbn/i18n'; import { FormattedMessage, FormattedRelative } from '@kbn/i18n-react'; -import type { Agent, AgentPolicy, PackagePolicy, SimplifiedAgentStatus } from '../../../types'; +import type { Agent, AgentPolicy, SimplifiedAgentStatus } from '../../../types'; import { usePagination, useAuthz, @@ -35,8 +35,12 @@ import { sendGetAgentTags, } from '../../../hooks'; import { AgentEnrollmentFlyout, AgentPolicySummaryLine } from '../../../components'; -import { AgentStatusKueryHelper, isAgentUpgradeable } from '../../../services'; -import { AGENTS_PREFIX, FLEET_SERVER_PACKAGE, SO_SEARCH_LIMIT } from '../../../constants'; +import { + AgentStatusKueryHelper, + isAgentUpgradeable, + policyHasFleetServer, +} from '../../../services'; +import { AGENTS_PREFIX, SO_SEARCH_LIMIT } from '../../../constants'; import { AgentReassignAgentPolicyModal, AgentHealth, @@ -389,10 +393,7 @@ export const AgentListPage: React.FunctionComponent<{}> = () => { return false; } - return agentPolicy.package_policies.some( - (ap: string | PackagePolicy) => - typeof ap !== 'string' && ap.package?.name === FLEET_SERVER_PACKAGE - ); + return policyHasFleetServer(agentPolicy); }, [agentToUnenroll, agentPoliciesIndexedById]); // Fleet server unhealthy status diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/debug/components/agent_policy_debugger.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/debug/components/agent_policy_debugger.tsx index 71ee096f1e4fac..78be94ef07048f 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/debug/components/agent_policy_debugger.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/debug/components/agent_policy_debugger.tsx @@ -16,7 +16,7 @@ import { EuiSpacer, EuiText, } from '@elastic/eui'; -import { useQuery } from 'react-query'; +import { useQuery } from '@tanstack/react-query'; import { FormattedMessage } from '@kbn/i18n-react'; import { i18n } from '@kbn/i18n'; @@ -52,7 +52,7 @@ export const AgentPolicyDebugger: React.FunctionComponent = () => { // TODO: Depending on the number of agent policies, this might need to be switched to // `useInfinite` query with an infinite scrolling approach in the dropdown options. - const { data, status } = useQuery('debug-agent-policies', fetchAgentPolicies); + const { data, status } = useQuery(['debug-agent-policies'], fetchAgentPolicies); const agentPolicies = data?.data?.items ?? []; const comboBoxOptions = agentPolicies.map((policy) => ({ @@ -68,7 +68,7 @@ export const AgentPolicyDebugger: React.FunctionComponent = () => { const onDelete = () => { setSelectedPolicyId(undefined); - queryClient.invalidateQueries('debug-agent-policies'); + queryClient.invalidateQueries(['debug-agent-policies']); }; if (status === 'error') { diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/debug/components/fleet_index_debugger.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/debug/components/fleet_index_debugger.tsx index 7c0c81858414a7..3f678d4463480b 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/debug/components/fleet_index_debugger.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/debug/components/fleet_index_debugger.tsx @@ -15,7 +15,7 @@ import { EuiSpacer, EuiText, } from '@elastic/eui'; -import { useQuery } from 'react-query'; +import { useQuery } from '@tanstack/react-query'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/debug/components/integration_debugger.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/debug/components/integration_debugger.tsx index 7140a582980cf5..9c3fa21c752f81 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/debug/components/integration_debugger.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/debug/components/integration_debugger.tsx @@ -20,7 +20,7 @@ import { EuiSpacer, EuiText, } from '@elastic/eui'; -import { useMutation, useQuery } from 'react-query'; +import { useMutation, useQuery } from '@tanstack/react-query'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; @@ -58,7 +58,7 @@ export const IntegrationDebugger: React.FunctionComponent = () => { const [isReinstallModalVisible, setIsReinstallModalVisible] = useState(false); const [isUninstallModalVisible, setIsUninstallModalVisible] = useState(false); - const integrations = useQuery('debug-integrations', fetchInstalledIntegrations); + const integrations = useQuery(['debug-integrations'], fetchInstalledIntegrations); const uninstallMutation = useMutation(async (integration: PackageListItem) => { const response = await sendRemovePackage(integration.name, integration.version, true); @@ -86,7 +86,7 @@ export const IntegrationDebugger: React.FunctionComponent = () => { setSelectedIntegrationId(undefined); setIsUninstallModalVisible(false); - queryClient.invalidateQueries('debug-integrations'); + queryClient.invalidateQueries(['debug-integrations']); return response.data; }); @@ -132,7 +132,7 @@ export const IntegrationDebugger: React.FunctionComponent = () => { setSelectedIntegrationId(undefined); setIsReinstallModalVisible(false); - queryClient.invalidateQueries('debug-integrations'); + queryClient.invalidateQueries(['debug-integrations']); return installResponse.data; }); diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/debug/components/orphaned_integration_policy_debugger.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/debug/components/orphaned_integration_policy_debugger.tsx index abc84ad4259009..3febbe36c56f77 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/debug/components/orphaned_integration_policy_debugger.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/debug/components/orphaned_integration_policy_debugger.tsx @@ -15,7 +15,7 @@ import { EuiButton, EuiConfirmModal, } from '@elastic/eui'; -import { useMutation, useQuery } from 'react-query'; +import { useMutation, useQuery } from '@tanstack/react-query'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; @@ -46,7 +46,7 @@ export const OrphanedIntegrationPolicyDebugger: React.FunctionComponent = () => const [isDeleteModalVisible, setIsDeleteModalVisible] = useState(false); const [isDeleteAllModalVisible, setIsDeleteAllModalVisible] = useState(false); - const { data: orphanedPolicies } = useQuery('debug-orphaned-policies', fetchOrphanedPolicies); + const { data: orphanedPolicies } = useQuery(['debug-orphaned-policies'], fetchOrphanedPolicies); const comboBoxOptions = orphanedPolicies?.map((policy: { id: string; name: string }) => ({ @@ -83,7 +83,7 @@ export const OrphanedIntegrationPolicyDebugger: React.FunctionComponent = () => defaultMessage: 'Successfully deleted orphaned policy', }) ); - queryClient.invalidateQueries('debug-orphaned-policies'); + queryClient.invalidateQueries(['debug-orphaned-policies']); setSelectedPolicyId(undefined); setIsDeleteModalVisible(false); @@ -112,7 +112,7 @@ export const OrphanedIntegrationPolicyDebugger: React.FunctionComponent = () => defaultMessage: 'Successfully deleted all orphaned policies', }) ); - queryClient.invalidateQueries('debug-orphaned-policies'); + queryClient.invalidateQueries(['debug-orphaned-policies']); setSelectedPolicyId(undefined); setIsDeleteAllModalVisible(false); diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/debug/components/preconfiguration_debugger.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/debug/components/preconfiguration_debugger.tsx index 35e9bcba754926..8184242f99e8d9 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/debug/components/preconfiguration_debugger.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/debug/components/preconfiguration_debugger.tsx @@ -17,7 +17,7 @@ import { EuiLink, EuiConfirmModal, } from '@elastic/eui'; -import { useMutation, useQuery } from 'react-query'; +import { useMutation, useQuery } from '@tanstack/react-query'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; @@ -55,7 +55,7 @@ export const PreconfigurationDebugger: React.FunctionComponent = () => { const [isResetAllModalVisible, setIsResetAllModalVisible] = useState(false); const preconfiguredPolicies = useQuery( - 'debug-preconfigured-policies', + ['debug-preconfigured-policies'], fetchPreconfiguredPolicies ); @@ -91,7 +91,7 @@ export const PreconfigurationDebugger: React.FunctionComponent = () => { defaultMessage: 'Successfully reset policy', }) ); - queryClient.invalidateQueries('debug-preconfigured-policies'); + queryClient.invalidateQueries(['debug-preconfigured-policies']); setSelectedPolicyId(undefined); setIsResetModalVisible(false); @@ -116,7 +116,7 @@ export const PreconfigurationDebugger: React.FunctionComponent = () => { defaultMessage: 'Successfully reset policies', }) ); - queryClient.invalidateQueries('debug-preconfigured-policies'); + queryClient.invalidateQueries(['debug-preconfigured-policies']); setSelectedPolicyId(undefined); setIsResetAllModalVisible(false); diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/debug/components/saved_object_debugger.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/debug/components/saved_object_debugger.tsx index c23b383d96f9d0..de95b08a4dfb6f 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/debug/components/saved_object_debugger.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/debug/components/saved_object_debugger.tsx @@ -6,7 +6,7 @@ */ import React, { useState, useRef } from 'react'; -import { useQuery } from 'react-query'; +import { useQuery } from '@tanstack/react-query'; import { EuiFlexGroup, EuiFlexItem, diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/debug/components/saved_object_names_combo.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/debug/components/saved_object_names_combo.tsx index 9458bca298b9af..aa9d7cb011e83b 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/debug/components/saved_object_names_combo.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/debug/components/saved_object_names_combo.tsx @@ -6,7 +6,7 @@ */ import React, { forwardRef, useImperativeHandle } from 'react'; -import { useQuery } from 'react-query'; +import { useQuery } from '@tanstack/react-query'; import { EuiComboBox } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/debug/index.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/debug/index.tsx index b54a97d3b270cb..89c61a78eb61cd 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/debug/index.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/debug/index.tsx @@ -18,8 +18,8 @@ import { EuiText, EuiTitle, } from '@elastic/eui'; -import { QueryClient, QueryClientProvider } from 'react-query'; -import { ReactQueryDevtools } from 'react-query/devtools'; +import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; +import { ReactQueryDevtools } from '@tanstack/react-query-devtools'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; diff --git a/x-pack/plugins/fleet/public/applications/integrations/components/header/header_portal.tsx b/x-pack/plugins/fleet/public/applications/integrations/components/header/header_portal.tsx index 190a6e1ba49c72..8b0671f0a9a45c 100644 --- a/x-pack/plugins/fleet/public/applications/integrations/components/header/header_portal.tsx +++ b/x-pack/plugins/fleet/public/applications/integrations/components/header/header_portal.tsx @@ -8,7 +8,7 @@ import type { AppMountParameters } from '@kbn/core/public'; import type { FC } from 'react'; import React, { useEffect, useMemo } from 'react'; -import { createPortalNode, InPortal, OutPortal } from 'react-reverse-portal'; +import { createHtmlPortalNode, InPortal, OutPortal } from 'react-reverse-portal'; import { toMountPoint } from '@kbn/kibana-react-plugin/public'; @@ -18,7 +18,7 @@ export interface Props { } export const HeaderPortal: FC = ({ children, setHeaderActionMenu, theme$ }) => { - const portalNode = useMemo(() => createPortalNode(), []); + const portalNode = useMemo(() => createHtmlPortalNode(), []); useEffect(() => { setHeaderActionMenu((element) => { diff --git a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/index.test.tsx b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/index.test.tsx index a77c45a6b5110a..693dee99ebf69a 100644 --- a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/index.test.tsx +++ b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/index.test.tsx @@ -717,11 +717,7 @@ On Windows, the module was tested with Nginx installed from the Chocolatey repos namespace: 'default', description: 'Default agent policy created by Kibana', status: 'active', - package_policies: [ - '4d09bd78-b0ad-4238-9fa3-d87d3c887c73', - '2babac18-eb8e-4ce4-b53b-4b7c5f507019', - 'e8a37031-2907-44f6-89d2-98bd493f60dc', - ], + package_policies: [], is_managed: false, monitoring_enabled: ['logs', 'metrics'], revision: 6, @@ -735,7 +731,7 @@ On Windows, the module was tested with Nginx installed from the Chocolatey repos namespace: 'default', description: 'Protect EU from COVID', status: 'active', - package_policies: ['e8a37031-2907-44f6-89d2-98bd493f60cd'], + package_policies: [], is_managed: false, monitoring_enabled: ['logs', 'metrics'], revision: 2, diff --git a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/overview/markdown_renderers.tsx b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/overview/markdown_renderers.tsx index 2cbdfe3671c4e6..8734d051e0be7b 100644 --- a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/overview/markdown_renderers.tsx +++ b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/overview/markdown_renderers.tsx @@ -11,9 +11,9 @@ import { EuiTableHeaderCell, EuiTableRow, EuiTableRowCell, - EuiText, } from '@elastic/eui'; import React from 'react'; +import type { TransformOptions } from 'react-markdown'; /** prevents links to the new pages from accessing `window.opener` */ const REL_NOOPENER = 'noopener'; @@ -30,42 +30,25 @@ const CODE_LANGUAGE_OVERRIDES: Record = { $yml: 'yml', }; -export const markdownRenderers = { - root: ({ children }: { children: React.ReactNode[] }) => ( - {children} - ), - table: ({ children }: { children: React.ReactNode[] }) => ( - {children}
- ), - tableRow: ({ children }: { children: React.ReactNode[] }) => ( - {children} - ), - tableCell: ({ isHeader, children }: { isHeader: boolean; children: React.ReactNode[] }) => { - return isHeader ? ( - {children} - ) : ( - {children} - ); - }, +export const markdownRenderers: TransformOptions['components'] = { + table: ({ children }) => {children}
, + tr: ({ children }) => {children}, + th: ({ children }) => {children}, + td: ({ children }) => {children}, // the headings used in markdown don't match our page so mapping them to the appropriate one - heading: ({ level, children }: { level: number; children: React.ReactNode[] }) => { - switch (level) { - case 1: - return

{children}

; - case 2: - return

{children}

; - case 3: - return
{children}
; - default: - return
{children}
; - } - }, + h1: ({ children }) =>

{children}

, + h2: ({ children }) =>

{children}

, + h3: ({ children }) =>
{children}
, + h4: ({ children }) =>
{children}
, + h5: ({ children }) =>
{children}
, + h6: ({ children }) =>
{children}
, link: ({ children, href }: { children: React.ReactNode[]; href?: string }) => ( {children} ), - code: ({ language, value }: { language: string; value: string }) => { + // @ts-expect-error update types + code: ({ language, value }) => { let parsedLang = language; // Some integrations export code block content that includes language tags that have since diff --git a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/overview/readme.tsx b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/overview/readme.tsx index 240b3c7bf7442c..f7e9c2a5b4e8fe 100644 --- a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/overview/readme.tsx +++ b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/overview/readme.tsx @@ -43,11 +43,11 @@ export function Readme({ return ( {markdown !== undefined ? ( - + + + {markdown} + + ) : ( {/* simulates a long page of text loading */} diff --git a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/policies/use_package_policies_with_agent_policy.ts b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/policies/use_package_policies_with_agent_policy.ts index 4f6f456bf82cdf..399016ebf20426 100644 --- a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/policies/use_package_policies_with_agent_policy.ts +++ b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/policies/use_package_policies_with_agent_policy.ts @@ -14,7 +14,6 @@ import type { GetPackagePoliciesResponse, } from '../../../../../types'; import { agentPolicyRouteService } from '../../../../../services'; -import { AGENT_POLICY_SAVED_OBJECT_TYPE } from '../../../../../constants'; import { useGetPackagePolicies, useConditionalRequest } from '../../../../../hooks'; import type { SendConditionalRequestConfig } from '../../../../../hooks'; @@ -52,37 +51,31 @@ export const usePackagePoliciesWithAgentPolicy = ( resendRequest, } = useGetPackagePolicies(query); - const agentPoliciesFilter = useMemo(() => { + const agentPoliciesIds = useMemo(() => { if (!packagePoliciesData?.items.length) { - return ''; + return []; } // Build a list of package_policies for which we need Agent Policies for. Since some package // policies can exist within the same Agent Policy, we don't need to (in some cases) include // the entire list of package_policy ids. - const includedAgentPolicies = new Set(); - - return `${AGENT_POLICY_SAVED_OBJECT_TYPE}.package_policies: (${packagePoliciesData.items - .filter((packagePolicy) => { - if (includedAgentPolicies.has(packagePolicy.policy_id)) { - return false; - } - includedAgentPolicies.add(packagePolicy.policy_id); - return true; - }) - .map((packagePolicy) => packagePolicy.id) - .join(' or ')}) `; + return Array.from( + new Set( + packagePoliciesData.items.map((packagePolicy) => packagePolicy.policy_id) + ).values() + ); }, [packagePoliciesData]); const { data: agentPoliciesData, isLoading: isLoadingAgentPolicies } = useConditionalRequest({ - path: agentPolicyRouteService.getListPath(), - method: 'get', - query: { - perPage: 100, - kuery: agentPoliciesFilter, + path: agentPolicyRouteService.getBulkGetPath(), + method: 'post', + body: { + ids: agentPoliciesIds, + full: true, + ignoreMissing: true, }, - shouldSendRequest: !!packagePoliciesData?.items.length, + shouldSendRequest: agentPoliciesIds.length > 0, } as SendConditionalRequestConfig); const [enrichedData, setEnrichedData] = useState(); diff --git a/x-pack/plugins/fleet/public/hooks/use_package_installations.tsx b/x-pack/plugins/fleet/public/hooks/use_package_installations.tsx index 4789770b7046f3..5a0b6285c71db1 100644 --- a/x-pack/plugins/fleet/public/hooks/use_package_installations.tsx +++ b/x-pack/plugins/fleet/public/hooks/use_package_installations.tsx @@ -52,8 +52,8 @@ export const usePackageInstallations = () => { const updatableIntegrations = useMemo>( () => (agentPolicyData?.items || []).reduce((result, policy) => { - policy.package_policies.forEach((pkgPolicy: PackagePolicy | string) => { - if (typeof pkgPolicy === 'string' || !pkgPolicy.package) return false; + policy.package_policies?.forEach((pkgPolicy: PackagePolicy) => { + if (!pkgPolicy.package) return false; const { name, version } = pkgPolicy.package; const installedPackage = allInstalledPackages.find( (installedPkg) => diff --git a/x-pack/plugins/fleet/public/services/has_fleet_server.ts b/x-pack/plugins/fleet/public/services/has_fleet_server.ts index e1100d6447aa20..43724d121b90f3 100644 --- a/x-pack/plugins/fleet/public/services/has_fleet_server.ts +++ b/x-pack/plugins/fleet/public/services/has_fleet_server.ts @@ -9,8 +9,11 @@ import { FLEET_SERVER_PACKAGE } from '../constants'; import type { AgentPolicy, PackagePolicy } from '../types'; export function policyHasFleetServer(agentPolicy: AgentPolicy) { - return agentPolicy.package_policies?.some( - (ap: string | PackagePolicy) => - typeof ap !== 'string' && ap.package?.name === FLEET_SERVER_PACKAGE + if (!agentPolicy.package_policies) { + return false; + } + + return agentPolicy.package_policies.some( + (ap: PackagePolicy) => ap.package?.name === FLEET_SERVER_PACKAGE ); } diff --git a/x-pack/plugins/fleet/server/errors/index.ts b/x-pack/plugins/fleet/server/errors/index.ts index d0aca78fce5ef8..713804d8a36f79 100644 --- a/x-pack/plugins/fleet/server/errors/index.ts +++ b/x-pack/plugins/fleet/server/errors/index.ts @@ -54,6 +54,7 @@ export class ConcurrentInstallOperationError extends IngestManagerError {} export class AgentReassignmentError extends IngestManagerError {} export class PackagePolicyIneligibleForUpgradeError extends IngestManagerError {} export class PackagePolicyValidationError extends IngestManagerError {} +export class PackagePolicyNotFoundError extends IngestManagerError {} export class BundledPackageNotFoundError extends IngestManagerError {} export class HostedAgentPolicyRestrictionRelatedError extends IngestManagerError { constructor(message = 'Cannot perform that action') { diff --git a/x-pack/plugins/fleet/server/integration_tests/reset_preconfiguration.test.ts b/x-pack/plugins/fleet/server/integration_tests/reset_preconfiguration.test.ts index 30bdf452cde12d..b4afbec0678748 100644 --- a/x-pack/plugins/fleet/server/integration_tests/reset_preconfiguration.test.ts +++ b/x-pack/plugins/fleet/server/integration_tests/reset_preconfiguration.test.ts @@ -248,9 +248,7 @@ describe('Fleet preconfiguration reset', () => { it('Works if the preconfigured policies already exists with a missing package policy', async () => { const soClient = kbnServer.coreStart.savedObjects.createInternalRepository(); - await soClient.update('ingest-agent-policies', POLICY_ID, { - package_policies: [], - }); + await soClient.update('ingest-agent-policies', POLICY_ID, {}); const resetAPI = getSupertestWithAdminUser( kbnServer.root, @@ -268,7 +266,6 @@ describe('Fleet preconfiguration reset', () => { expect.arrayContaining([ expect.objectContaining({ name: 'Elastic Cloud agent policy 0001', - package_policies: expect.arrayContaining([expect.stringMatching(/.*/)]), }), expect.objectContaining({ name: 'Second preconfigured policy', diff --git a/x-pack/plugins/fleet/server/mocks/index.ts b/x-pack/plugins/fleet/server/mocks/index.ts index b4e5f83d2cb060..a76988506cad21 100644 --- a/x-pack/plugins/fleet/server/mocks/index.ts +++ b/x-pack/plugins/fleet/server/mocks/index.ts @@ -121,6 +121,7 @@ export const createPackagePolicyServiceMock = (): jest.Mocked + getAgentsByKuery(esClient, { + showInactive: false, + perPage: 0, + page: 1, + kuery: `${AGENTS_PREFIX}.policy_id:${agentPolicy.id}`, + }).then(({ total: agentTotal }) => (agentPolicy.agents = agentTotal)), + { concurrency: 10 } + ); +} + export const getAgentPoliciesHandler: FleetRequestHandler< undefined, TypeOf @@ -55,6 +75,7 @@ export const getAgentPoliciesHandler: FleetRequestHandler< withPackagePolicies, ...restOfQuery, }); + const body: GetAgentPoliciesResponse = { items, total, @@ -62,20 +83,45 @@ export const getAgentPoliciesHandler: FleetRequestHandler< perPage, }; - await pMap( + await populateAssignedAgentsCount(esClient, items); + + return response.ok({ body }); + } catch (error) { + return defaultIngestErrorHandler({ error, response }); + } +}; + +export const bulkGetAgentPoliciesHandler: FleetRequestHandler< + undefined, + undefined, + TypeOf +> = async (context, request, response) => { + const coreContext = await context.core; + const fleetContext = await context.fleet; + const soClient = fleetContext.epm.internalSoClient; + const esClient = coreContext.elasticsearch.client.asInternalUser; + const { full: withPackagePolicies = false, ignoreMissing = false, ids } = request.body; + try { + const items = await agentPolicyService.getByIDs(soClient, ids, { + withPackagePolicies, + ignoreMissing, + }); + const body: BulkGetAgentPoliciesResponse = { items, - (agentPolicy: GetAgentPoliciesResponseItem) => - getAgentsByKuery(esClient, { - showInactive: false, - perPage: 0, - page: 1, - kuery: `${AGENTS_PREFIX}.policy_id:${agentPolicy.id}`, - }).then(({ total: agentTotal }) => (agentPolicy.agents = agentTotal)), - { concurrency: 10 } - ); + }; + + await populateAssignedAgentsCount(esClient, items); return response.ok({ body }); } catch (error) { + if (error instanceof AgentPolicyNotFoundError) { + return response.notFound({ + body: { + message: error.message, + }, + }); + } + return defaultIngestErrorHandler({ error, response }); } }; diff --git a/x-pack/plugins/fleet/server/routes/agent_policy/index.ts b/x-pack/plugins/fleet/server/routes/agent_policy/index.ts index b42799d738d4c7..938d8b3332b719 100644 --- a/x-pack/plugins/fleet/server/routes/agent_policy/index.ts +++ b/x-pack/plugins/fleet/server/routes/agent_policy/index.ts @@ -15,6 +15,7 @@ import { DeleteAgentPolicyRequestSchema, GetFullAgentPolicyRequestSchema, GetK8sManifestRequestSchema, + BulkGetAgentPoliciesRequestSchema, } from '../../types'; import type { FleetAuthzRouter } from '../security'; @@ -31,6 +32,7 @@ import { downloadFullAgentPolicy, downloadK8sManifest, getK8sManifest, + bulkGetAgentPoliciesHandler, } from './handlers'; export const registerRoutes = (router: FleetAuthzRouter) => { @@ -46,6 +48,18 @@ export const registerRoutes = (router: FleetAuthzRouter) => { getAgentPoliciesHandler ); + // Bulk GET + router.post( + { + path: AGENT_POLICY_API_ROUTES.BULK_GET_PATTERN, + validate: BulkGetAgentPoliciesRequestSchema, + fleetAuthz: { + fleet: { readAgentPolicies: true }, + }, + }, + bulkGetAgentPoliciesHandler + ); + // Get one router.get( { diff --git a/x-pack/plugins/fleet/server/routes/package_policy/handlers.test.ts b/x-pack/plugins/fleet/server/routes/package_policy/handlers.test.ts index 222408c6e05247..5e67857540143b 100644 --- a/x-pack/plugins/fleet/server/routes/package_policy/handlers.test.ts +++ b/x-pack/plugins/fleet/server/routes/package_policy/handlers.test.ts @@ -138,8 +138,8 @@ describe('When calling package policy', () => { // Set the routeConfig and routeHandler to the Create API beforeEach(() => { - [routeConfig, routeHandler] = routerMock.post.mock.calls.find(([{ path }]) => - path.startsWith(PACKAGE_POLICY_API_ROUTES.CREATE_PATTERN) + [routeConfig, routeHandler] = routerMock.post.mock.calls.find( + ([{ path }]) => path === PACKAGE_POLICY_API_ROUTES.CREATE_PATTERN )!; }); diff --git a/x-pack/plugins/fleet/server/routes/package_policy/handlers.ts b/x-pack/plugins/fleet/server/routes/package_policy/handlers.ts index 8ecbd11ec59866..0b5f71910cfa98 100644 --- a/x-pack/plugins/fleet/server/routes/package_policy/handlers.ts +++ b/x-pack/plugins/fleet/server/routes/package_policy/handlers.ts @@ -25,8 +25,10 @@ import type { FleetRequestHandler, PackagePolicy, DeleteOnePackagePolicyRequestSchema, + BulkGetPackagePoliciesRequestSchema, } from '../../types'; import type { + BulkGetPackagePoliciesResponse, CreatePackagePolicyResponse, DeletePackagePoliciesResponse, NewPackagePolicy, @@ -34,7 +36,7 @@ import type { UpgradePackagePolicyResponse, } from '../../../common/types'; import { installationStatuses } from '../../../common/constants'; -import { defaultIngestErrorHandler } from '../../errors'; +import { defaultIngestErrorHandler, PackagePolicyNotFoundError } from '../../errors'; import { getInstallations } from '../../services/epm/packages'; import { PACKAGES_SAVED_OBJECT_TYPE, SO_SEARCH_LIMIT } from '../../constants'; @@ -61,6 +63,34 @@ export const getPackagePoliciesHandler: RequestHandler< } }; +export const bulkGetPackagePoliciesHandler: RequestHandler< + undefined, + undefined, + TypeOf +> = async (context, request, response) => { + const soClient = (await context.core).savedObjects.client; + const { ids, ignoreMissing } = request.body; + try { + const items = await packagePolicyService.getByIDs(soClient, ids, { + ignoreMissing, + }); + + const body: BulkGetPackagePoliciesResponse = { items: items ?? [] }; + + return response.ok({ + body, + }); + } catch (error) { + if (error instanceof PackagePolicyNotFoundError) { + return response.notFound({ + body: { message: error.message }, + }); + } + + return defaultIngestErrorHandler({ error, response }); + } +}; + export const getOnePackagePolicyHandler: RequestHandler< TypeOf > = async (context, request, response) => { diff --git a/x-pack/plugins/fleet/server/routes/package_policy/index.ts b/x-pack/plugins/fleet/server/routes/package_policy/index.ts index cf52b740245f85..004037623bb0dd 100644 --- a/x-pack/plugins/fleet/server/routes/package_policy/index.ts +++ b/x-pack/plugins/fleet/server/routes/package_policy/index.ts @@ -15,6 +15,7 @@ import { UpgradePackagePoliciesRequestSchema, DryRunPackagePoliciesRequestSchema, DeleteOnePackagePolicyRequestSchema, + BulkGetPackagePoliciesRequestSchema, } from '../../types'; import type { FleetAuthzRouter } from '../security'; @@ -28,6 +29,7 @@ import { dryRunUpgradePackagePolicyHandler, getOrphanedPackagePolicies, deleteOnePackagePolicyHandler, + bulkGetPackagePoliciesHandler, } from './handlers'; export const registerRoutes = (router: FleetAuthzRouter) => { @@ -43,6 +45,17 @@ export const registerRoutes = (router: FleetAuthzRouter) => { getPackagePoliciesHandler ); + router.post( + { + path: PACKAGE_POLICY_API_ROUTES.BULK_GET_PATTERN, + validate: BulkGetPackagePoliciesRequestSchema, + fleetAuthz: { + integrations: { readIntegrationPolicies: true }, + }, + }, + bulkGetPackagePoliciesHandler + ); + // Get one router.get( { diff --git a/x-pack/plugins/fleet/server/saved_objects/index.ts b/x-pack/plugins/fleet/server/saved_objects/index.ts index 652a30d174190a..71134a67ca6d10 100644 --- a/x-pack/plugins/fleet/server/saved_objects/index.ts +++ b/x-pack/plugins/fleet/server/saved_objects/index.ts @@ -45,6 +45,7 @@ import { migrateAgentPolicyToV840, migratePackagePolicyToV840, } from './migrations/to_v8_4_0'; +import { migrateAgentPolicyToV850 } from './migrations/to_v8_5_0'; /* * Saved object types and mappings @@ -91,7 +92,6 @@ const getSavedObjectTypes = ( is_default: { type: 'boolean' }, is_default_fleet_server: { type: 'boolean' }, status: { type: 'keyword' }, - package_policies: { type: 'keyword' }, unenroll_timeout: { type: 'integer' }, updated_at: { type: 'date' }, updated_by: { type: 'keyword' }, @@ -107,6 +107,7 @@ const getSavedObjectTypes = ( '7.10.0': migrateAgentPolicyToV7100, '7.12.0': migrateAgentPolicyToV7120, '8.4.0': migrateAgentPolicyToV840, + '8.5.0': migrateAgentPolicyToV850, }, }, [OUTPUT_SAVED_OBJECT_TYPE]: { diff --git a/x-pack/plugins/fleet/server/saved_objects/migrations/to_v7_10_0.ts b/x-pack/plugins/fleet/server/saved_objects/migrations/to_v7_10_0.ts index 7c5c3c6fb4cf1e..feb592a652633a 100644 --- a/x-pack/plugins/fleet/server/saved_objects/migrations/to_v7_10_0.ts +++ b/x-pack/plugins/fleet/server/saved_objects/migrations/to_v7_10_0.ts @@ -10,10 +10,13 @@ import type { SavedObjectMigrationFn } from '@kbn/core/server'; import type { AgentPolicy, PackagePolicy, Settings } from '../../types'; export const migrateAgentPolicyToV7100: SavedObjectMigrationFn< - Exclude & { - package_configs: string[] | PackagePolicy[]; + Omit & { + package_configs: string[]; + package_policies?: string[]; }, - AgentPolicy + Omit & { + package_policies?: string[]; + } > = (agentPolicyDoc) => { agentPolicyDoc.attributes.package_policies = agentPolicyDoc.attributes.package_configs; // @ts-expect-error diff --git a/x-pack/plugins/fleet/server/saved_objects/migrations/to_v8_5_0.ts b/x-pack/plugins/fleet/server/saved_objects/migrations/to_v8_5_0.ts new file mode 100644 index 00000000000000..9cbcc85c46936f --- /dev/null +++ b/x-pack/plugins/fleet/server/saved_objects/migrations/to_v8_5_0.ts @@ -0,0 +1,22 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { SavedObjectMigrationFn } from '@kbn/core/server'; + +import type { AgentPolicy } from '../../types'; + +export const migrateAgentPolicyToV850: SavedObjectMigrationFn< + Exclude & { + package_policies: string[]; + }, + AgentPolicy +> = (agentPolicyDoc) => { + // @ts-expect-error + delete agentPolicyDoc.attributes.package_policies; + + return agentPolicyDoc; +}; diff --git a/x-pack/plugins/fleet/server/services/agent_policies/package_policies_to_agent_permissions.test.ts b/x-pack/plugins/fleet/server/services/agent_policies/package_policies_to_agent_permissions.test.ts index 0db543e4357a46..a60b5c68d05a9e 100644 --- a/x-pack/plugins/fleet/server/services/agent_policies/package_policies_to_agent_permissions.test.ts +++ b/x-pack/plugins/fleet/server/services/agent_policies/package_policies_to_agent_permissions.test.ts @@ -31,8 +31,10 @@ describe('storedPackagePoliciesToAgentPermissions()', () => { expect(permissions).toBeUndefined(); }); - it('Throw an error for string package policies', async () => { - await expect(() => storedPackagePoliciesToAgentPermissions(soClient, ['foo'])).rejects.toThrow( + it('Throw an error if package policies is not an array', async () => { + await expect(() => + storedPackagePoliciesToAgentPermissions(soClient, undefined) + ).rejects.toThrow( /storedPackagePoliciesToAgentPermissions should be called with a PackagePolicy/ ); }); diff --git a/x-pack/plugins/fleet/server/services/agent_policies/package_policies_to_agent_permissions.ts b/x-pack/plugins/fleet/server/services/agent_policies/package_policies_to_agent_permissions.ts index ee17494ca64547..b961eb8691f888 100644 --- a/x-pack/plugins/fleet/server/services/agent_policies/package_policies_to_agent_permissions.ts +++ b/x-pack/plugins/fleet/server/services/agent_policies/package_policies_to_agent_permissions.ts @@ -20,19 +20,19 @@ export const DEFAULT_CLUSTER_PERMISSIONS = ['monitor']; export async function storedPackagePoliciesToAgentPermissions( soClient: SavedObjectsClientContract, - packagePolicies: string[] | PackagePolicy[] + packagePolicies?: PackagePolicy[] ): Promise { - if (packagePolicies.length === 0) { - return; - } - // I'm not sure what permissions to return for this case, so let's return the defaults - if (typeof packagePolicies[0] === 'string') { + if (!packagePolicies) { throw new Error( 'storedPackagePoliciesToAgentPermissions should be called with a PackagePolicy' ); } + if (packagePolicies.length === 0) { + return; + } + const permissionEntries = (packagePolicies as PackagePolicy[]).map>( async (packagePolicy) => { if (!packagePolicy.package) { diff --git a/x-pack/plugins/fleet/server/services/agent_policy.test.ts b/x-pack/plugins/fleet/server/services/agent_policy.test.ts index 4d348af471772e..8dd8c885af3e42 100644 --- a/x-pack/plugins/fleet/server/services/agent_policy.test.ts +++ b/x-pack/plugins/fleet/server/services/agent_policy.test.ts @@ -75,6 +75,8 @@ const mockedOutputService = outputService as jest.Mocked; const mockedDownloadSourceService = downloadSourceService as jest.Mocked< typeof downloadSourceService >; +const mockedPackagePolicyService = packagePolicyService as jest.Mocked; + const mockedGetFullAgentPolicy = getFullAgentPolicy as jest.Mock< ReturnType >; @@ -144,6 +146,11 @@ describe('agent policy', () => { beforeEach(() => { soClient = getSavedObjectMock({ revision: 1, package_policies: ['package-1'] }); + mockedPackagePolicyService.findAllForAgentPolicy.mockReturnValue([ + { + id: 'package-1', + }, + ] as any); esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; (getAgentsByKuery as jest.Mock).mockResolvedValue({ @@ -153,10 +160,10 @@ describe('agent policy', () => { perPage: 10, }); - (packagePolicyService.delete as jest.Mock).mockResolvedValue([ + mockedPackagePolicyService.delete.mockResolvedValue([ { id: 'package-1', - }, + } as any, ]); }); diff --git a/x-pack/plugins/fleet/server/services/agent_policy.ts b/x-pack/plugins/fleet/server/services/agent_policy.ts index 7eb59ade87f0b4..9c70e4a58c388e 100644 --- a/x-pack/plugins/fleet/server/services/agent_policy.ts +++ b/x-pack/plugins/fleet/server/services/agent_policy.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { uniq, omit, isEqual, keyBy } from 'lodash'; +import { omit, isEqual, keyBy } from 'lodash'; import uuidv5 from 'uuid/v5'; import { safeDump } from 'js-yaml'; import pMap from 'p-map'; @@ -53,7 +53,11 @@ import type { Output, DeletePackagePoliciesResponse, } from '../../common/types'; -import { AgentPolicyNameExistsError, HostedAgentPolicyRestrictionRelatedError } from '../errors'; +import { + AgentPolicyNameExistsError, + HostedAgentPolicyRestrictionRelatedError, + AgentPolicyNotFoundError, +} from '../errors'; import type { FullAgentConfigMap } from '../../common/types/models/agent_cm'; @@ -182,8 +186,9 @@ class AgentPolicyService { } public hasAPMIntegration(agentPolicy: AgentPolicy) { - return agentPolicy.package_policies.some( - (p) => typeof p !== 'string' && p.package?.name === FLEET_APM_PACKAGE + return ( + agentPolicy.package_policies && + agentPolicy.package_policies.some((p) => p.package?.name === FLEET_APM_PACKAGE) ); } @@ -257,10 +262,7 @@ class AgentPolicyService { if (withPackagePolicies) { agentPolicy.package_policies = - (await packagePolicyService.getByIDs( - soClient, - (agentPolicySO.attributes.package_policies as string[]) || [] - )) || []; + (await packagePolicyService.findAllForAgentPolicy(soClient, id)) || []; } return agentPolicy; @@ -269,16 +271,44 @@ class AgentPolicyService { public async getByIDs( soClient: SavedObjectsClientContract, ids: string[], - options: { fields?: string[] } = {} + options: { fields?: string[]; withPackagePolicies?: boolean; ignoreMissing?: boolean } = {} ): Promise { const objects = ids.map((id) => ({ ...options, id, type: SAVED_OBJECT_TYPE })); - const agentPolicySO = await soClient.bulkGet(objects); + const bulkGetResponse = await soClient.bulkGet(objects); - return agentPolicySO.saved_objects.map((so) => ({ - id: so.id, - version: so.version, - ...so.attributes, - })); + const agentPolicies = await pMap( + bulkGetResponse.saved_objects, + async (agentPolicySO) => { + if (agentPolicySO.error) { + if (options.ignoreMissing && agentPolicySO.error.statusCode === 404) { + return null; + } else if (agentPolicySO.error.statusCode === 404) { + throw new AgentPolicyNotFoundError(`Agent policy ${agentPolicySO.id} not found`); + } else { + throw new Error(agentPolicySO.error.message); + } + } + + const agentPolicy = { + id: agentPolicySO.id, + ...agentPolicySO.attributes, + }; + if (options.withPackagePolicies) { + const agentPolicyWithPackagePolicies = await this.get( + soClient, + agentPolicySO.id, + options.withPackagePolicies + ); + if (agentPolicyWithPackagePolicies) { + agentPolicy.package_policies = agentPolicyWithPackagePolicies.package_policies; + } + } + return agentPolicy; + }, + { concurrency: 50 } + ); + + return agentPolicies.filter((agentPolicy): agentPolicy is AgentPolicy => agentPolicy !== null); } public async list( @@ -423,7 +453,7 @@ class AgentPolicyService { ); // Copy all package policies and append (copy n) to their names - if (baseAgentPolicy.package_policies.length) { + if (baseAgentPolicy.package_policies) { const newPackagePolicies = await pMap( baseAgentPolicy.package_policies as PackagePolicy[], async (packagePolicy: PackagePolicy) => { @@ -575,75 +605,6 @@ class AgentPolicyService { return res; } - public async assignPackagePolicies( - soClient: SavedObjectsClientContract, - esClient: ElasticsearchClient, - id: string, - packagePolicyIds: string[], - options: { user?: AuthenticatedUser; bumpRevision: boolean; force?: boolean } = { - bumpRevision: true, - } - ): Promise { - const oldAgentPolicy = await this.get(soClient, id, false); - - if (!oldAgentPolicy) { - throw new Error('Agent policy not found'); - } - - if (oldAgentPolicy.is_managed && !options?.force) { - throw new HostedAgentPolicyRestrictionRelatedError( - `Cannot update integrations of hosted agent policy ${id}` - ); - } - - return await this._update( - soClient, - esClient, - id, - { - package_policies: uniq( - [...((oldAgentPolicy.package_policies || []) as string[])].concat(packagePolicyIds) - ), - }, - options?.user, - { bumpRevision: options.bumpRevision } - ); - } - - public async unassignPackagePolicies( - soClient: SavedObjectsClientContract, - esClient: ElasticsearchClient, - id: string, - packagePolicyIds: string[], - options?: { user?: AuthenticatedUser; force?: boolean } - ) { - const oldAgentPolicy = await this.get(soClient, id, false); - - if (!oldAgentPolicy) { - throw new Error('Agent policy not found'); - } - - if (oldAgentPolicy.is_managed && !options?.force) { - throw new HostedAgentPolicyRestrictionRelatedError( - `Cannot remove integrations of hosted agent policy ${id}` - ); - } - - return await this._update( - soClient, - esClient, - id, - { - package_policies: uniq( - [...((oldAgentPolicy.package_policies || []) as string[])].filter( - (packagePolicyId) => !packagePolicyIds.includes(packagePolicyId) - ) - ), - }, - options?.user - ); - } - public async delete( soClient: SavedObjectsClientContract, esClient: ElasticsearchClient, @@ -670,12 +631,14 @@ class AgentPolicyService { throw new Error('Cannot delete agent policy that is assigned to agent(s)'); } - if (agentPolicy.package_policies && agentPolicy.package_policies.length) { + const packagePolicies = await packagePolicyService.findAllForAgentPolicy(soClient, id); + + if (packagePolicies.length) { const deletedPackagePolicies: DeletePackagePoliciesResponse = await packagePolicyService.delete( soClient, esClient, - agentPolicy.package_policies as string[], + packagePolicies.map((p) => p.id), { force: options?.force, skipUnassignFromAgentPolicies: true, diff --git a/x-pack/plugins/fleet/server/services/agents/hosted_agent.ts b/x-pack/plugins/fleet/server/services/agents/hosted_agent.ts index 0c26e09575ac39..4acba8551e86d2 100644 --- a/x-pack/plugins/fleet/server/services/agents/hosted_agent.ts +++ b/x-pack/plugins/fleet/server/services/agents/hosted_agent.ts @@ -22,6 +22,7 @@ export async function getHostedPolicies( // get the agent policies for those ids const agentPolicies = await agentPolicyService.getByIDs(soClient, Array.from(policyIdsToGet), { fields: ['is_managed'], + ignoreMissing: true, }); const hostedPolicies = agentPolicies.reduce>((acc, policy) => { acc[policy.id] = policy.is_managed; diff --git a/x-pack/plugins/fleet/server/services/package_policy.ts b/x-pack/plugins/fleet/server/services/package_policy.ts index ecdff37854b27e..f7668f8fe19bf0 100644 --- a/x-pack/plugins/fleet/server/services/package_policy.ts +++ b/x-pack/plugins/fleet/server/services/package_policy.ts @@ -54,6 +54,8 @@ import { PackagePolicyIneligibleForUpgradeError, PackagePolicyValidationError, PackagePolicyRestrictionRelatedError, + PackagePolicyNotFoundError, + HostedAgentPolicyRestrictionRelatedError, } from '../errors'; import { NewPackagePolicySchema, PackagePolicySchema, UpdatePackagePolicySchema } from '../types'; import type { @@ -74,7 +76,7 @@ import { outputService } from './output'; import { getPackageInfo, getInstallation, ensureInstalledPackage } from './epm/packages'; import { getAssetsData } from './epm/packages/assets'; import { compileTemplate } from './epm/agent/agent'; -import { normalizeKuery } from './saved_object'; +import { escapeSearchQueryPhrase, normalizeKuery } from './saved_object'; import { appContextService } from '.'; import { removeOldAssets } from './epm/packages/cleanup'; import type { PackageUpdateEvent, UpdateEventType } from './upgrade_sender'; @@ -119,6 +121,7 @@ class PackagePolicyService implements PackagePolicyServiceInterface { throw new IngestManagerError('You cannot add APM to a policy using a logstash output'); } } + await validateIsNotHostedPolicy(soClient, packagePolicy.policy_id, options?.force); // trailing whitespace causes issues creating API keys packagePolicy.name = packagePolicy.name.trim(); @@ -195,18 +198,11 @@ class PackagePolicyService implements PackagePolicyServiceInterface { { ...options, id: packagePolicyId } ); - // Assign it to the given agent policy - await agentPolicyService.assignPackagePolicies( - soClient, - esClient, - packagePolicy.policy_id, - [newSo.id], - { + if (options?.bumpRevision ?? true) { + await agentPolicyService.bumpRevision(soClient, esClient, packagePolicy.policy_id, { user: options?.user, - bumpRevision: options?.bumpRevision ?? true, - force: options?.force, - } - ); + }); + } return { id: newSo.id, @@ -220,8 +216,9 @@ class PackagePolicyService implements PackagePolicyServiceInterface { esClient: ElasticsearchClient, packagePolicies: NewPackagePolicy[], agentPolicyId: string, - options?: { user?: AuthenticatedUser; bumpRevision?: boolean } + options?: { user?: AuthenticatedUser; bumpRevision?: boolean; force: true } ): Promise { + await validateIsNotHostedPolicy(soClient, agentPolicyId); const isoDate = new Date().toISOString(); // eslint-disable-next-line @typescript-eslint/naming-convention const { saved_objects } = await soClient.bulkCreate( @@ -253,16 +250,12 @@ class PackagePolicyService implements PackagePolicyServiceInterface { const newSos = saved_objects.filter((so) => !so.error && so.attributes); // Assign it to the given agent policy - await agentPolicyService.assignPackagePolicies( - soClient, - esClient, - agentPolicyId, - newSos.map((newSo) => newSo.id), - { + + if (options?.bumpRevision ?? true) { + await agentPolicyService.bumpRevision(soClient, esClient, agentPolicyId, { user: options?.user, - bumpRevision: options?.bumpRevision ?? true, - } - ); + }); + } return newSos.map((newSo) => ({ id: newSo.id, @@ -291,9 +284,30 @@ class PackagePolicyService implements PackagePolicyServiceInterface { }; } + public async findAllForAgentPolicy( + soClient: SavedObjectsClientContract, + agentPolicyId: string + ): Promise { + const packagePolicySO = await soClient.find({ + type: SAVED_OBJECT_TYPE, + filter: `${SAVED_OBJECT_TYPE}.attributes.policy_id:${escapeSearchQueryPhrase(agentPolicyId)}`, + perPage: SO_SEARCH_LIMIT, + }); + if (!packagePolicySO) { + return []; + } + + return packagePolicySO.saved_objects.map((so) => ({ + id: so.id, + version: so.version, + ...so.attributes, + })); + } + public async getByIDs( soClient: SavedObjectsClientContract, - ids: string[] + ids: string[], + options: { ignoreMissing?: boolean } = {} ): Promise { const packagePolicySO = await soClient.bulkGet( ids.map((id) => ({ @@ -305,11 +319,25 @@ class PackagePolicyService implements PackagePolicyServiceInterface { return null; } - return packagePolicySO.saved_objects.map((so) => ({ - id: so.id, - version: so.version, - ...so.attributes, - })); + return packagePolicySO.saved_objects + .map((so): PackagePolicy | null => { + if (so.error) { + if (options.ignoreMissing && so.error.statusCode === 404) { + return null; + } else if (so.error.statusCode === 404) { + throw new PackagePolicyNotFoundError(`Package policy ${so.id} not found`); + } else { + throw new Error(so.error.message); + } + } + + return { + id: so.id, + version: so.version, + ...so.attributes, + }; + }) + .filter((packagePolicy): packagePolicy is PackagePolicy => packagePolicy !== null); } public async list( @@ -485,6 +513,13 @@ class PackagePolicyService implements PackagePolicyServiceInterface { throw new PackagePolicyRestrictionRelatedError(`Cannot delete package policy ${id}`); } + await validateIsNotHostedPolicy( + soClient, + packagePolicy?.policy_id, + options?.force, + 'Cannot remove integrations of hosted agent policy' + ); + const agentPolicy = await agentPolicyService .get(soClient, packagePolicy.policy_id) .catch((err) => { @@ -497,19 +532,12 @@ class PackagePolicyService implements PackagePolicyServiceInterface { throw err; }); + await soClient.delete(SAVED_OBJECT_TYPE, id); if (agentPolicy && !options?.skipUnassignFromAgentPolicies) { - await agentPolicyService.unassignPackagePolicies( - soClient, - esClient, - packagePolicy.policy_id, - [packagePolicy.id], - { - user: options?.user, - force: options?.force, - } - ); + await agentPolicyService.bumpRevision(soClient, esClient, packagePolicy.policy_id, { + user: options?.user, + }); } - await soClient.delete(SAVED_OBJECT_TYPE, id); result.push({ id, name: packagePolicy.name, @@ -1265,7 +1293,16 @@ export interface PackagePolicyServiceInterface { get(soClient: SavedObjectsClientContract, id: string): Promise; - getByIDs(soClient: SavedObjectsClientContract, ids: string[]): Promise; + findAllForAgentPolicy( + soClient: SavedObjectsClientContract, + agentPolicyId: string + ): Promise; + + getByIDs( + soClient: SavedObjectsClientContract, + ids: string[], + options?: { ignoreMissing?: boolean } + ): Promise; list( soClient: SavedObjectsClientContract, @@ -1587,6 +1624,25 @@ export function preconfigurePackageInputs( return resultingPackagePolicy; } +async function validateIsNotHostedPolicy( + soClient: SavedObjectsClientContract, + id: string, + force = false, + errorMessage?: string +) { + const agentPolicy = await agentPolicyService.get(soClient, id, false); + + if (!agentPolicy) { + throw new Error('Agent policy not found'); + } + + if (agentPolicy.is_managed && !force) { + throw new HostedAgentPolicyRestrictionRelatedError( + errorMessage ?? `Cannot update integrations of hosted agent policy ${id}` + ); + } +} + function deepMergeVars(original: any, override: any, keepOriginalValue = false): any { if (!original.vars) { original.vars = { ...override.vars }; diff --git a/x-pack/plugins/fleet/server/services/preconfiguration.test.ts b/x-pack/plugins/fleet/server/services/preconfiguration.test.ts index c0b24f927d8488..245ab2316cb022 100644 --- a/x-pack/plugins/fleet/server/services/preconfiguration.test.ts +++ b/x-pack/plugins/fleet/server/services/preconfiguration.test.ts @@ -238,7 +238,8 @@ jest.mock('./epm/kibana/index_pattern/install'); jest.mock('./package_policy', () => ({ ...jest.requireActual('./package_policy'), packagePolicyService: { - getByIDs: jest.fn().mockReturnValue([]), + ...jest.requireActual('./package_policy').packagePolicyService, + findAllForAgentPolicy: jest.fn().mockReturnValue([]), listIds: jest.fn().mockReturnValue({ items: [] }), create: jest .fn() @@ -280,8 +281,8 @@ const spyAgentPolicyServicBumpAllAgentPoliciesForOutput = jest.spyOn( describe('policy preconfiguration', () => { beforeEach(() => { - mockedPackagePolicyService.getByIDs.mockReset(); mockedPackagePolicyService.create.mockReset(); + mockedPackagePolicyService.findAllForAgentPolicy.mockReset(); mockInstalledPackages.clear(); mockInstallPackageErrors.clear(); mockConfiguredPolicies.clear(); @@ -365,7 +366,7 @@ describe('policy preconfiguration', () => { it('should not add new package policy to existing non managed policies', async () => { const soClient = getPutPreconfiguredPackagesMock(); const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; - mockedPackagePolicyService.getByIDs.mockResolvedValue([ + mockedPackagePolicyService.findAllForAgentPolicy.mockResolvedValue([ { name: 'test_package1' } as PackagePolicy, ]); @@ -415,7 +416,7 @@ describe('policy preconfiguration', () => { it('should add new package policy to existing managed policies', async () => { const soClient = getPutPreconfiguredPackagesMock(); const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; - mockedPackagePolicyService.getByIDs.mockResolvedValue([ + mockedPackagePolicyService.findAllForAgentPolicy.mockResolvedValue([ { name: 'test_package1' } as PackagePolicy, ]); @@ -475,7 +476,7 @@ describe('policy preconfiguration', () => { const soClient = getPutPreconfiguredPackagesMock(); const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; - mockedPackagePolicyService.getByIDs.mockResolvedValue([ + mockedPackagePolicyService.findAllForAgentPolicy.mockResolvedValue([ { name: 'Renamed package policy', id: 'test_package1' } as PackagePolicy, ]); diff --git a/x-pack/plugins/fleet/server/types/rest_spec/agent_policy.ts b/x-pack/plugins/fleet/server/types/rest_spec/agent_policy.ts index 1f793445bf6309..c2599d79b33642 100644 --- a/x-pack/plugins/fleet/server/types/rest_spec/agent_policy.ts +++ b/x-pack/plugins/fleet/server/types/rest_spec/agent_policy.ts @@ -9,7 +9,7 @@ import { schema } from '@kbn/config-schema'; import { NewAgentPolicySchema } from '../models'; -import { ListWithKuerySchema } from '.'; +import { ListWithKuerySchema, BulkRequestBodySchema } from './common'; export const GetAgentPoliciesRequestSchema = { query: ListWithKuerySchema.extends({ @@ -17,6 +17,12 @@ export const GetAgentPoliciesRequestSchema = { }), }; +export const BulkGetAgentPoliciesRequestSchema = { + body: BulkRequestBodySchema.extends({ + full: schema.maybe(schema.boolean()), + }), +}; + export const GetOneAgentPolicyRequestSchema = { params: schema.object({ agentPolicyId: schema.string(), diff --git a/x-pack/plugins/fleet/server/types/rest_spec/common.ts b/x-pack/plugins/fleet/server/types/rest_spec/common.ts index 2d12bd5d7c9874..0c5f16ff87f90f 100644 --- a/x-pack/plugins/fleet/server/types/rest_spec/common.ts +++ b/x-pack/plugins/fleet/server/types/rest_spec/common.ts @@ -22,4 +22,9 @@ export const ListWithKuerySchema = schema.object({ ), }); +export const BulkRequestBodySchema = schema.object({ + ids: schema.arrayOf(schema.string(), { minSize: 1 }), + ignoreMissing: schema.maybe(schema.boolean()), +}); + export type ListWithKuery = TypeOf; diff --git a/x-pack/plugins/fleet/server/types/rest_spec/package_policy.ts b/x-pack/plugins/fleet/server/types/rest_spec/package_policy.ts index b085060286d05a..fa7cdce92400b1 100644 --- a/x-pack/plugins/fleet/server/types/rest_spec/package_policy.ts +++ b/x-pack/plugins/fleet/server/types/rest_spec/package_policy.ts @@ -12,12 +12,16 @@ import { UpdatePackagePolicyRequestBodySchema, } from '../models'; -import { ListWithKuerySchema } from '.'; +import { ListWithKuerySchema, BulkRequestBodySchema } from './common'; export const GetPackagePoliciesRequestSchema = { query: ListWithKuerySchema, }; +export const BulkGetPackagePoliciesRequestSchema = { + body: BulkRequestBodySchema, +}; + export const GetOnePackagePolicyRequestSchema = { params: schema.object({ packagePolicyId: schema.string(), diff --git a/x-pack/plugins/global_search_bar/public/components/search_bar.tsx b/x-pack/plugins/global_search_bar/public/components/search_bar.tsx index c85c6f74b16412..e4d87d26cbecc8 100644 --- a/x-pack/plugins/global_search_bar/public/components/search_bar.tsx +++ b/x-pack/plugins/global_search_bar/public/components/search_bar.tsx @@ -40,7 +40,9 @@ import './search_bar.scss'; const isMac = navigator.platform.toLowerCase().indexOf('mac') >= 0; -const blurEvent = new FocusEvent('blur'); +const blurEvent = new FocusEvent('focusout', { + bubbles: true, +}); const sortByScore = (a: GlobalSearchResult, b: GlobalSearchResult): number => { if (a.score < b.score) return 1; diff --git a/x-pack/plugins/infra/public/components/logging/log_text_stream/column_headers.tsx b/x-pack/plugins/infra/public/components/logging/log_text_stream/column_headers.tsx index d8c1fe071fe92e..30355ea1a9a232 100644 --- a/x-pack/plugins/infra/public/components/logging/log_text_stream/column_headers.tsx +++ b/x-pack/plugins/infra/public/components/logging/log_text_stream/column_headers.tsx @@ -6,7 +6,7 @@ */ import { i18n } from '@kbn/i18n'; -import React, { useContext } from 'react'; +import React from 'react'; import { transparentize } from 'polished'; import { euiStyled } from '@kbn/kibana-react-plugin/common'; @@ -17,7 +17,7 @@ import { LogEntryColumnWidths, } from './log_entry_column'; import { ASSUMED_SCROLLBAR_WIDTH } from './vertical_scroll_panel'; -import { LogPositionState } from '../../../containers/logs/log_position'; +import { useLogPositionStateContext } from '../../../containers/logs/log_position'; import { localizedDate } from '../../../../common/formatters/datetime'; import { LogColumnRenderConfiguration, @@ -30,7 +30,7 @@ export const LogColumnHeaders: React.FunctionComponent<{ columnConfigurations: LogColumnRenderConfiguration[]; columnWidths: LogEntryColumnWidths; }> = ({ columnConfigurations, columnWidths }) => { - const { firstVisiblePosition } = useContext(LogPositionState.Context); + const { firstVisiblePosition } = useLogPositionStateContext(); return ( {columnConfigurations.map((columnConfiguration) => { diff --git a/x-pack/plugins/infra/public/containers/logs/log_filter/log_filter_state.ts b/x-pack/plugins/infra/public/containers/logs/log_filter/log_filter_state.ts index 55b554560b743e..70d72c25158da8 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_filter/log_filter_state.ts +++ b/x-pack/plugins/infra/public/containers/logs/log_filter/log_filter_state.ts @@ -105,4 +105,5 @@ export const useLogFilterState = ({ indexPattern }: { indexPattern: DataViewBase }; }; -export const LogFilterState = createContainer(useLogFilterState); +export const [LogFilterStateProvider, useLogFilterStateContext] = + createContainer(useLogFilterState); diff --git a/x-pack/plugins/infra/public/containers/logs/log_filter/with_log_filter_url_state.tsx b/x-pack/plugins/infra/public/containers/logs/log_filter/with_log_filter_url_state.tsx index 5a62cb5e386778..2a5970721f5e5f 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_filter/with_log_filter_url_state.tsx +++ b/x-pack/plugins/infra/public/containers/logs/log_filter/with_log_filter_url_state.tsx @@ -6,13 +6,13 @@ */ import * as rt from 'io-ts'; -import React, { useContext } from 'react'; +import React from 'react'; import { Query } from '@kbn/es-query'; import { replaceStateKeyInQueryString, UrlStateContainer } from '../../../utils/url_state'; -import { LogFilterState } from './log_filter_state'; +import { useLogFilterStateContext } from './log_filter_state'; export const WithLogFilterUrlState: React.FC = () => { - const { filterQuery, applyLogFilterQuery } = useContext(LogFilterState.Context); + const { filterQuery, applyLogFilterQuery } = useLogFilterStateContext(); return ( { const [highlightTerms, setHighlightTerms] = useState([]); - const { visibleMidpoint, jumpToTargetPosition, startTimestamp, endTimestamp } = useContext( - LogPositionState.Context - ); + const { visibleMidpoint, jumpToTargetPosition, startTimestamp, endTimestamp } = + useLogPositionStateContext(); const throttledStartTimestamp = useThrottle(startTimestamp, FETCH_THROTTLE_INTERVAL); const throttledEndTimestamp = useThrottle(endTimestamp, FETCH_THROTTLE_INTERVAL); @@ -89,4 +88,5 @@ export const useLogHighlightsState = ({ }; }; -export const LogHighlightsState = createContainer(useLogHighlightsState); +export const [LogHighlightsStateProvider, useLogHighlightsStateContext] = + createContainer(useLogHighlightsState); diff --git a/x-pack/plugins/infra/public/containers/logs/log_position/log_position_state.ts b/x-pack/plugins/infra/public/containers/logs/log_position/log_position_state.ts index 59b7d004314593..521a5bf8562fc8 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_position/log_position_state.ts +++ b/x-pack/plugins/infra/public/containers/logs/log_position/log_position_state.ts @@ -249,4 +249,5 @@ export const useLogPositionState: () => LogPositionStateParams & LogPositionCall return { ...state, ...callbacks }; }; -export const LogPositionState = createContainer(useLogPositionState); +export const [LogPositionStateProvider, useLogPositionStateContext] = + createContainer(useLogPositionState); diff --git a/x-pack/plugins/infra/public/containers/logs/log_position/with_log_position_url_state.tsx b/x-pack/plugins/infra/public/containers/logs/log_position/with_log_position_url_state.tsx index c0da683568f398..d4d8075a2598fa 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_position/with_log_position_url_state.tsx +++ b/x-pack/plugins/infra/public/containers/logs/log_position/with_log_position_url_state.tsx @@ -5,11 +5,11 @@ * 2.0. */ -import React, { useContext, useMemo } from 'react'; +import React, { useMemo } from 'react'; import { pickTimeKey } from '../../../../common/time'; import { replaceStateKeyInQueryString, UrlStateContainer } from '../../../utils/url_state'; -import { LogPositionState, LogPositionStateParams } from './log_position_state'; +import { useLogPositionStateContext, LogPositionStateParams } from './log_position_state'; import { isValidDatemath, datemathToEpochMillis } from '../../../utils/datemath'; /** @@ -35,7 +35,7 @@ export const WithLogPositionUrlState = () => { endDateExpression, updateDateRange, initialize, - } = useContext(LogPositionState.Context); + } = useLogPositionStateContext(); const urlState = useMemo( () => ({ position: visibleMidpoint ? pickTimeKey(visibleMidpoint) : null, diff --git a/x-pack/plugins/infra/public/containers/logs/log_summary/with_summary.ts b/x-pack/plugins/infra/public/containers/logs/log_summary/with_summary.ts index 1b6d9f850187a8..e36ef1caa2c662 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_summary/with_summary.ts +++ b/x-pack/plugins/infra/public/containers/logs/log_summary/with_summary.ts @@ -5,12 +5,11 @@ * 2.0. */ -import { useContext } from 'react'; import useThrottle from 'react-use/lib/useThrottle'; import { useLogViewContext } from '../../../hooks/use_log_view'; import { RendererFunction } from '../../../utils/typed_react'; -import { LogFilterState } from '../log_filter'; -import { LogPositionState } from '../log_position'; +import { useLogFilterStateContext } from '../log_filter'; +import { useLogPositionStateContext } from '../log_position'; import { LogSummaryBuckets, useLogSummary } from './log_summary'; const FETCH_THROTTLE_INTERVAL = 3000; @@ -25,8 +24,8 @@ export const WithSummary = ({ }>; }) => { const { logViewId } = useLogViewContext(); - const { filterQuery } = useContext(LogFilterState.Context); - const { startTimestamp, endTimestamp } = useContext(LogPositionState.Context); + const { filterQuery } = useLogFilterStateContext(); + const { startTimestamp, endTimestamp } = useLogPositionStateContext(); // Keep it reasonably updated for the `now` case, but don't reload all the time when the user scrolls const throttledStartTimestamp = useThrottle(startTimestamp, FETCH_THROTTLE_INTERVAL); diff --git a/x-pack/plugins/infra/public/containers/logs/log_view_configuration.tsx b/x-pack/plugins/infra/public/containers/logs/log_view_configuration.tsx index 98672d6d14861e..543cc61d789773 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_view_configuration.tsx +++ b/x-pack/plugins/infra/public/containers/logs/log_view_configuration.tsx @@ -26,7 +26,8 @@ export const useLogViewConfiguration = () => { }; }; -export const LogViewConfiguration = createContainer(useLogViewConfiguration); +export const [LogViewConfigurationProvider, useLogViewConfigurationContext] = + createContainer(useLogViewConfiguration); /** * constants diff --git a/x-pack/plugins/infra/public/containers/logs/view_log_in_context/view_log_in_context.ts b/x-pack/plugins/infra/public/containers/logs/view_log_in_context/view_log_in_context.ts index a389589488d926..b22a73d77cc541 100644 --- a/x-pack/plugins/infra/public/containers/logs/view_log_in_context/view_log_in_context.ts +++ b/x-pack/plugins/infra/public/containers/logs/view_log_in_context/view_log_in_context.ts @@ -42,4 +42,5 @@ export const useViewLogInContext = ( ]; }; -export const ViewLogInContext = createContainer(useViewLogInContext); +export const [ViewLogInContextProvider, useViewLogInProviderContext] = + createContainer(useViewLogInContext); diff --git a/x-pack/plugins/infra/public/containers/logs/with_log_textview.tsx b/x-pack/plugins/infra/public/containers/logs/with_log_textview.tsx index c981a113bf2f4e..f57368709467da 100644 --- a/x-pack/plugins/infra/public/containers/logs/with_log_textview.tsx +++ b/x-pack/plugins/infra/public/containers/logs/with_log_textview.tsx @@ -5,10 +5,14 @@ * 2.0. */ -import React, { useContext, useMemo } from 'react'; +import React, { useMemo } from 'react'; import { UrlStateContainer } from '../../utils/url_state'; -import { availableTextScales, LogViewConfiguration, TextScale } from './log_view_configuration'; +import { + availableTextScales, + useLogViewConfigurationContext, + TextScale, +} from './log_view_configuration'; interface LogTextviewUrlState { textScale?: TextScale; @@ -16,9 +20,7 @@ interface LogTextviewUrlState { } export const WithLogTextviewUrlState = () => { - const { textScale, textWrap, setTextScale, setTextWrap } = useContext( - LogViewConfiguration.Context - ); + const { textScale, textWrap, setTextScale, setTextWrap } = useLogViewConfigurationContext(); const urlState = useMemo(() => ({ textScale, wrap: textWrap }), [textScale, textWrap]); diff --git a/x-pack/plugins/infra/public/containers/metrics_explorer/with_metrics_explorer_options_url_state.tsx b/x-pack/plugins/infra/public/containers/metrics_explorer/with_metrics_explorer_options_url_state.tsx index e66191923e39ac..b192bf54e48294 100644 --- a/x-pack/plugins/infra/public/containers/metrics_explorer/with_metrics_explorer_options_url_state.tsx +++ b/x-pack/plugins/infra/public/containers/metrics_explorer/with_metrics_explorer_options_url_state.tsx @@ -5,13 +5,13 @@ * 2.0. */ -import { set } from '@elastic/safer-lodash-set'; -import React, { useContext, useMemo } from 'react'; +import { set } from '@kbn/safer-lodash-set'; +import React, { useMemo } from 'react'; import { ThrowReporter } from 'io-ts/lib/ThrowReporter'; import { UrlStateContainer } from '../../utils/url_state'; import { MetricsExplorerOptions, - MetricsExplorerOptionsContainer, + useMetricsExplorerOptionsContainerContext, MetricsExplorerTimeOptions, MetricsExplorerChartOptions, metricExplorerOptionsRT, @@ -33,7 +33,7 @@ export const WithMetricsExplorerOptionsUrlState = () => { currentTimerange, setOptions: setRawOptions, setTimeRange, - } = useContext(MetricsExplorerOptionsContainer.Context); + } = useMetricsExplorerOptionsContainerContext(); const setOptions = (value: MetricsExplorerOptions) => { setRawOptions(value); diff --git a/x-pack/plugins/infra/public/containers/metrics_source/source.tsx b/x-pack/plugins/infra/public/containers/metrics_source/source.tsx index 393cad266a1230..6a7c7aedccc626 100644 --- a/x-pack/plugins/infra/public/containers/metrics_source/source.tsx +++ b/x-pack/plugins/infra/public/containers/metrics_source/source.tsx @@ -157,5 +157,4 @@ export const useSource = ({ sourceId }: { sourceId: string }) => { }; }; -export const Source = createContainer(useSource); -export const [SourceProvider, useSourceContext] = Source; +export const [SourceProvider, useSourceContext] = createContainer(useSource); diff --git a/x-pack/plugins/infra/public/containers/saved_view/saved_view.tsx b/x-pack/plugins/infra/public/containers/saved_view/saved_view.tsx index e2bb50e0dc2da2..8eb3d4c50de1a1 100644 --- a/x-pack/plugins/infra/public/containers/saved_view/saved_view.tsx +++ b/x-pack/plugins/infra/public/containers/saved_view/saved_view.tsx @@ -10,14 +10,14 @@ import * as rt from 'io-ts'; import { pipe } from 'fp-ts/lib/pipeable'; import { fold } from 'fp-ts/lib/Either'; import { constant, identity } from 'fp-ts/lib/function'; -import { useCallback, useMemo, useState, useEffect, useContext } from 'react'; +import { useCallback, useMemo, useState, useEffect } from 'react'; import { i18n } from '@kbn/i18n'; import { SimpleSavedObject, SavedObjectAttributes } from '@kbn/core/public'; import { useUrlState } from '../../utils/use_url_state'; import { useFindSavedObject } from '../../hooks/use_find_saved_object'; import { useCreateSavedObject } from '../../hooks/use_create_saved_object'; import { useDeleteSavedObject } from '../../hooks/use_delete_saved_object'; -import { Source } from '../metrics_source'; +import { useSourceContext } from '../metrics_source'; import { metricsExplorerViewSavedObjectName } from '../../../common/saved_objects/metrics_explorer_view'; import { inventoryViewSavedObjectName } from '../../../common/saved_objects/inventory_view'; import { useSourceConfigurationFormState } from '../../pages/metrics/settings/source_configuration_form_state'; @@ -59,7 +59,7 @@ export const useSavedView = (props: Props) => { sourceExists, createSourceConfiguration, updateSourceConfiguration, - } = useContext(Source.Context); + } = useSourceContext(); const { viewType, defaultViewState } = props; type ViewState = typeof defaultViewState; const { diff --git a/x-pack/plugins/infra/public/containers/with_source/with_source.tsx b/x-pack/plugins/infra/public/containers/with_source/with_source.tsx index 148b679018c7d1..b2730cbf2e8803 100644 --- a/x-pack/plugins/infra/public/containers/with_source/with_source.tsx +++ b/x-pack/plugins/infra/public/containers/with_source/with_source.tsx @@ -5,14 +5,14 @@ * 2.0. */ -import React, { useContext } from 'react'; +import React from 'react'; import { MetricsSourceConfigurationProperties, PartialMetricsSourceConfigurationProperties, } from '../../../common/metrics_sources'; import { RendererFunction } from '../../utils/typed_react'; -import { Source } from '../metrics_source'; +import { useSourceContext } from '../metrics_source'; import { CreateDerivedIndexPattern } from '../metrics_source'; interface WithSourceProps { @@ -52,7 +52,7 @@ export const WithSource: React.FunctionComponent = ({ children loadSourceFailureMessage, updateSourceConfiguration, version, - } = useContext(Source.Context); + } = useSourceContext(); return children({ create: createSourceConfiguration, diff --git a/x-pack/plugins/infra/public/pages/link_to/link_to_logs.test.tsx b/x-pack/plugins/infra/public/pages/link_to/link_to_logs.test.tsx index 6f4b0e73f0c33f..5ed7ab99b4a3e9 100644 --- a/x-pack/plugins/infra/public/pages/link_to/link_to_logs.test.tsx +++ b/x-pack/plugins/infra/public/pages/link_to/link_to_logs.test.tsx @@ -11,7 +11,7 @@ import React from 'react'; import { Route, Router, Switch } from 'react-router-dom'; import { httpServiceMock } from '@kbn/core/public/mocks'; import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public'; -import { KibanaPageTemplate } from '@kbn/shared-ux-components'; +import { KibanaPageTemplate } from '@kbn/shared-ux-page-kibana-template'; import { useLogView } from '../../hooks/use_log_view'; import { createLoadedUseLogViewMock, diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/page_results_content.tsx b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/page_results_content.tsx index 13dd004a1a5ce2..6dff4b41ecf534 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/page_results_content.tsx +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/page_results_content.tsx @@ -22,7 +22,7 @@ import { DatasetsSelector } from '../../../components/logging/log_analysis_resul import { RecreateJobButton } from '../../../components/logging/log_analysis_setup/create_job_button'; import { useLogAnalysisCapabilitiesContext } from '../../../containers/logs/log_analysis/log_analysis_capabilities'; import { useLogEntryCategoriesModuleContext } from '../../../containers/logs/log_analysis/modules/log_entry_categories'; -import { ViewLogInContext } from '../../../containers/logs/view_log_in_context'; +import { ViewLogInContextProvider } from '../../../containers/logs/view_log_in_context'; import { useKibanaContextForPlugin } from '../../../hooks/use_kibana'; import { useLogViewContext } from '../../../hooks/use_log_view'; import { LogsPageTemplate } from '../page_template'; @@ -205,7 +205,7 @@ export const LogEntryCategoriesResultsContent: React.FunctionComponent< }); return ( - - + ); }; diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/sections/top_categories/category_example_message.tsx b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/sections/top_categories/category_example_message.tsx index be5806d2b3064a..091cbb1ba07b7b 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/sections/top_categories/category_example_message.tsx +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/sections/top_categories/category_example_message.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React, { useState, useCallback, useContext } from 'react'; +import React, { useState, useCallback } from 'react'; import { i18n } from '@kbn/i18n'; import { encode } from 'rison-node'; import moment from 'moment'; @@ -17,7 +17,7 @@ import { getFriendlyNameForPartitionId, partitionField, } from '../../../../../../common/log_analysis'; -import { ViewLogInContext } from '../../../../../containers/logs/view_log_in_context'; +import { useViewLogInProviderContext } from '../../../../../containers/logs/view_log_in_context'; import { LogEntryColumn, LogEntryFieldColumn, @@ -41,7 +41,7 @@ export const CategoryExampleMessage: React.FunctionComponent<{ context: LogEntryContext; }> = ({ id, dataset, message, timestamp, timeRange, tiebreaker, context }) => { const trackMetric = useUiTracker({ app: 'infra_logs' }); - const [, { setContextEntry }] = useContext(ViewLogInContext.Context); + const [, { setContextEntry }] = useViewLogInProviderContext(); // handle special cases for the dataset value const humanFriendlyDataset = getFriendlyNameForPartitionId(dataset); diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/page_providers.tsx b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/page_providers.tsx index 53e74ecf543203..f944b089d5d7d5 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/page_providers.tsx +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/page_providers.tsx @@ -11,7 +11,7 @@ import { LogSourceErrorPage } from '../../../components/logging/log_source_error import { SourceLoadingPage } from '../../../components/source_loading_page'; import { LogEntryCategoriesModuleProvider } from '../../../containers/logs/log_analysis/modules/log_entry_categories'; import { LogEntryRateModuleProvider } from '../../../containers/logs/log_analysis/modules/log_entry_rate'; -import { LogFlyout } from '../../../containers/logs/log_flyout'; +import { LogEntryFlyoutProvider } from '../../../containers/logs/log_flyout'; import { useActiveKibanaSpace } from '../../../hooks/use_kibana_space'; import { useLogViewContext } from '../../../hooks/use_log_view'; @@ -38,7 +38,7 @@ export const LogEntryRatePageProviders: React.FunctionComponent = ({ children }) return ; } else if (resolvedLogView != null) { return ( - + {children} - + ); } else { return null; diff --git a/x-pack/plugins/infra/public/pages/logs/page_template.tsx b/x-pack/plugins/infra/public/pages/logs/page_template.tsx index 32a5be3e071c7b..3fb8884f963c4a 100644 --- a/x-pack/plugins/infra/public/pages/logs/page_template.tsx +++ b/x-pack/plugins/infra/public/pages/logs/page_template.tsx @@ -9,7 +9,7 @@ import React from 'react'; import { i18n } from '@kbn/i18n'; import type { LazyObservabilityPageTemplateProps } from '@kbn/observability-plugin/public'; import { useKibana } from '@kbn/kibana-react-plugin/public'; -import { KibanaPageTemplateProps } from '@kbn/shared-ux-components'; +import { NoDataConfig } from '@kbn/shared-ux-page-kibana-template'; import { useKibanaContextForPlugin } from '../../hooks/use_kibana'; interface LogsPageTemplateProps extends LazyObservabilityPageTemplateProps { @@ -35,7 +35,7 @@ export const LogsPageTemplate: React.FC = ({ const { http } = useKibana().services; const basePath = http!.basePath.get(); - const noDataConfig: KibanaPageTemplateProps['noDataConfig'] = hasData + const noDataConfig: NoDataConfig | undefined = hasData ? undefined : { solution: i18n.translate('xpack.infra.logs.noDataConfig.solutionName', { diff --git a/x-pack/plugins/infra/public/pages/logs/stream/page_logs_content.tsx b/x-pack/plugins/infra/public/pages/logs/stream/page_logs_content.tsx index 2cb7b2c6f5a7b9..18ac30bb35e145 100644 --- a/x-pack/plugins/infra/public/pages/logs/stream/page_logs_content.tsx +++ b/x-pack/plugins/infra/public/pages/logs/stream/page_logs_content.tsx @@ -7,7 +7,7 @@ import { EuiSpacer } from '@elastic/eui'; import type { Query } from '@kbn/es-query'; -import React, { useCallback, useContext, useEffect, useMemo } from 'react'; +import React, { useCallback, useEffect, useMemo } from 'react'; import usePrevious from 'react-use/lib/usePrevious'; import { euiStyled } from '@kbn/kibana-react-plugin/common'; import { LogEntry } from '../../../../common/log_entry'; @@ -18,17 +18,17 @@ import { LogMinimap } from '../../../components/logging/log_minimap'; import { ScrollableLogTextStreamView } from '../../../components/logging/log_text_stream'; import { LogEntryStreamItem } from '../../../components/logging/log_text_stream/item'; import { PageContent } from '../../../components/page'; -import { LogFilterState } from '../../../containers/logs/log_filter'; +import { useLogFilterStateContext } from '../../../containers/logs/log_filter'; import { useLogEntryFlyoutContext, WithFlyoutOptionsUrlState, } from '../../../containers/logs/log_flyout'; -import { LogHighlightsState } from '../../../containers/logs/log_highlights'; -import { LogPositionState } from '../../../containers/logs/log_position'; +import { useLogHighlightsStateContext } from '../../../containers/logs/log_highlights'; +import { useLogPositionStateContext } from '../../../containers/logs/log_position'; import { useLogStreamContext } from '../../../containers/logs/log_stream'; import { WithSummary } from '../../../containers/logs/log_summary'; -import { LogViewConfiguration } from '../../../containers/logs/log_view_configuration'; -import { ViewLogInContext } from '../../../containers/logs/view_log_in_context'; +import { useLogViewConfigurationContext } from '../../../containers/logs/log_view_configuration'; +import { useViewLogInProviderContext } from '../../../containers/logs/view_log_in_context'; import { WithLogTextviewUrlState } from '../../../containers/logs/with_log_textview'; import { useLogViewContext } from '../../../hooks/use_log_view'; import { datemathToEpochMillis, isValidDatemath } from '../../../utils/datemath'; @@ -39,7 +39,7 @@ const PAGE_THRESHOLD = 2; export const LogsPageLogsContent: React.FunctionComponent = () => { const { resolvedLogView, logView, logViewId } = useLogViewContext(); - const { textScale, textWrap } = useContext(LogViewConfiguration.Context); + const { textScale, textWrap } = useLogViewConfigurationContext(); const { surroundingLogsId, setSurroundingLogsId, @@ -64,8 +64,8 @@ export const LogsPageLogsContent: React.FunctionComponent = () => { endDateExpression, updateDateRange, lastCompleteDateRangeExpressionUpdate, - } = useContext(LogPositionState.Context); - const { filterQuery, applyLogFilterQuery } = useContext(LogFilterState.Context); + } = useLogPositionStateContext(); + const { filterQuery, applyLogFilterQuery } = useLogFilterStateContext(); const { isReloading, @@ -132,9 +132,8 @@ export const LogsPageLogsContent: React.FunctionComponent = () => { prevLastCompleteDateRangeExpressionUpdate, ]); - const { logSummaryHighlights, currentHighlightKey, logEntryHighlightsById } = useContext( - LogHighlightsState.Context - ); + const { logSummaryHighlights, currentHighlightKey, logEntryHighlightsById } = + useLogHighlightsStateContext(); const items = useMemo( () => @@ -147,7 +146,7 @@ export const LogsPageLogsContent: React.FunctionComponent = () => { [entries, isReloading, logEntryHighlightsById] ); - const [, { setContextEntry }] = useContext(ViewLogInContext.Context); + const [, { setContextEntry }] = useViewLogInProviderContext(); const handleDateRangeExtension = useCallback( (newDateRange) => { diff --git a/x-pack/plugins/infra/public/pages/logs/stream/page_providers.tsx b/x-pack/plugins/infra/public/pages/logs/stream/page_providers.tsx index 11aa74ca862ad6..ea2af542586a23 100644 --- a/x-pack/plugins/infra/public/pages/logs/stream/page_providers.tsx +++ b/x-pack/plugins/infra/public/pages/logs/stream/page_providers.tsx @@ -5,29 +5,37 @@ * 2.0. */ -import React, { useContext } from 'react'; -import { LogFilterState, WithLogFilterUrlState } from '../../../containers/logs/log_filter'; -import { LogFlyout } from '../../../containers/logs/log_flyout'; -import { LogHighlightsState } from '../../../containers/logs/log_highlights/log_highlights'; -import { LogPositionState, WithLogPositionUrlState } from '../../../containers/logs/log_position'; +import React from 'react'; +import { + LogFilterStateProvider, + useLogFilterStateContext, + WithLogFilterUrlState, +} from '../../../containers/logs/log_filter'; +import { LogEntryFlyoutProvider } from '../../../containers/logs/log_flyout'; +import { LogHighlightsStateProvider } from '../../../containers/logs/log_highlights/log_highlights'; +import { + LogPositionStateProvider, + useLogPositionStateContext, + WithLogPositionUrlState, +} from '../../../containers/logs/log_position'; import { LogStreamProvider, useLogStreamContext } from '../../../containers/logs/log_stream'; -import { LogViewConfiguration } from '../../../containers/logs/log_view_configuration'; -import { ViewLogInContext } from '../../../containers/logs/view_log_in_context'; +import { LogViewConfigurationProvider } from '../../../containers/logs/log_view_configuration'; +import { ViewLogInContextProvider } from '../../../containers/logs/view_log_in_context'; import { useLogViewContext } from '../../../hooks/use_log_view'; -const LogFilterStateProvider: React.FC = ({ children }) => { +const LogFilterState: React.FC = ({ children }) => { const { derivedDataView } = useLogViewContext(); return ( - + {children} - + ); }; -const ViewLogInContextProvider: React.FC = ({ children }) => { - const { startTimestamp, endTimestamp } = useContext(LogPositionState.Context); +const ViewLogInContext: React.FC = ({ children }) => { + const { startTimestamp, endTimestamp } = useLogPositionStateContext(); const { logViewId } = useLogViewContext(); if (!startTimestamp || !endTimestamp) { @@ -35,22 +43,21 @@ const ViewLogInContextProvider: React.FC = ({ children }) => { } return ( - {children} - + ); }; const LogEntriesStateProvider: React.FC = ({ children }) => { const { logViewId } = useLogViewContext(); - const { startTimestamp, endTimestamp, targetPosition, isInitialized } = useContext( - LogPositionState.Context - ); - const { filterQuery } = useContext(LogFilterState.Context); + const { startTimestamp, endTimestamp, targetPosition, isInitialized } = + useLogPositionStateContext(); + const { filterQuery } = useLogFilterStateContext(); // Don't render anything if the date range is incorrect. if (!startTimestamp || !endTimestamp) { @@ -76,10 +83,10 @@ const LogEntriesStateProvider: React.FC = ({ children }) => { ); }; -const LogHighlightsStateProvider: React.FC = ({ children }) => { +const LogHighlightsState: React.FC = ({ children }) => { const { logViewId, logView } = useLogViewContext(); const { topCursor, bottomCursor, entries } = useLogStreamContext(); - const { filterQuery } = useContext(LogFilterState.Context); + const { filterQuery } = useLogFilterStateContext(); const highlightsProps = { sourceId: logViewId, @@ -90,7 +97,7 @@ const LogHighlightsStateProvider: React.FC = ({ children }) => { size: entries.length, filterQuery: filterQuery?.serializedQuery ?? null, }; - return {children}; + return {children}; }; export const LogsPageProviders: React.FunctionComponent = ({ children }) => { @@ -102,19 +109,19 @@ export const LogsPageProviders: React.FunctionComponent = ({ children }) => { } return ( - - - + + + - - + + - {children} + {children} - - - - - + + + + + ); }; diff --git a/x-pack/plugins/infra/public/pages/logs/stream/page_toolbar.tsx b/x-pack/plugins/infra/public/pages/logs/stream/page_toolbar.tsx index e3b2f01b6712e7..6076849b79f129 100644 --- a/x-pack/plugins/infra/public/pages/logs/stream/page_toolbar.tsx +++ b/x-pack/plugins/infra/public/pages/logs/stream/page_toolbar.tsx @@ -8,7 +8,7 @@ import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import { Query } from '@kbn/es-query'; import { i18n } from '@kbn/i18n'; -import React, { useContext } from 'react'; +import React from 'react'; import { QueryStringInput } from '@kbn/unified-search-plugin/public'; import { DataView } from '@kbn/data-views-plugin/public'; import { euiStyled } from '@kbn/kibana-react-plugin/common'; @@ -17,21 +17,20 @@ import { LogDatepicker } from '../../../components/logging/log_datepicker'; import { LogHighlightsMenu } from '../../../components/logging/log_highlights_menu'; import { LogTextScaleControls } from '../../../components/logging/log_text_scale_controls'; import { LogTextWrapControls } from '../../../components/logging/log_text_wrap_controls'; -import { LogFilterState } from '../../../containers/logs/log_filter'; -import { LogFlyout } from '../../../containers/logs/log_flyout'; -import { LogHighlightsState } from '../../../containers/logs/log_highlights/log_highlights'; -import { LogPositionState } from '../../../containers/logs/log_position'; -import { LogViewConfiguration } from '../../../containers/logs/log_view_configuration'; +import { useLogFilterStateContext } from '../../../containers/logs/log_filter'; +import { useLogEntryFlyoutContext } from '../../../containers/logs/log_flyout'; +import { useLogHighlightsStateContext } from '../../../containers/logs/log_highlights/log_highlights'; +import { useLogPositionStateContext } from '../../../containers/logs/log_position'; +import { useLogViewConfigurationContext } from '../../../containers/logs/log_view_configuration'; import { useLogViewContext } from '../../../hooks/use_log_view'; export const LogsToolbar = () => { const { derivedDataView } = useLogViewContext(); - const { availableTextScales, setTextScale, setTextWrap, textScale, textWrap } = useContext( - LogViewConfiguration.Context - ); + const { availableTextScales, setTextScale, setTextWrap, textScale, textWrap } = + useLogViewConfigurationContext(); const { filterQueryDraft, isFilterQueryDraftValid, applyLogFilterQuery, setLogFilterQueryDraft } = - useContext(LogFilterState.Context); - const { setSurroundingLogsId } = useContext(LogFlyout.Context); + useLogFilterStateContext(); + const { setSurroundingLogsId } = useLogEntryFlyoutContext(); const { setHighlightTerms, @@ -41,7 +40,7 @@ export const LogsToolbar = () => { hasNextHighlight, goToPreviousHighlight, goToNextHighlight, - } = useContext(LogHighlightsState.Context); + } = useLogHighlightsStateContext(); const { isStreaming, startLiveStreaming, @@ -49,7 +48,7 @@ export const LogsToolbar = () => { startDateExpression, endDateExpression, updateDateRange, - } = useContext(LogPositionState.Context); + } = useLogPositionStateContext(); return (
diff --git a/x-pack/plugins/infra/public/pages/logs/stream/page_view_log_in_context.tsx b/x-pack/plugins/infra/public/pages/logs/stream/page_view_log_in_context.tsx index 7afc8e19c43ee3..9b4a2ffb4185b6 100644 --- a/x-pack/plugins/infra/public/pages/logs/stream/page_view_log_in_context.tsx +++ b/x-pack/plugins/infra/public/pages/logs/stream/page_view_log_in_context.tsx @@ -15,10 +15,10 @@ import { } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; import { isEmpty } from 'lodash'; -import React, { useCallback, useContext, useMemo } from 'react'; +import React, { useCallback, useMemo } from 'react'; import { euiStyled } from '@kbn/kibana-react-plugin/common'; import { LogEntry } from '../../../../common/log_entry'; -import { ViewLogInContext } from '../../../containers/logs/view_log_in_context'; +import { useViewLogInProviderContext } from '../../../containers/logs/view_log_in_context'; import { useViewportDimensions } from '../../../utils/use_viewport_dimensions'; import { LogStream } from '../../../components/log_stream'; @@ -26,7 +26,7 @@ const MODAL_MARGIN = 25; export const PageViewLogInContext: React.FC = () => { const [{ contextEntry, startTimestamp, endTimestamp, sourceId }, { setContextEntry }] = - useContext(ViewLogInContext.Context); + useViewLogInProviderContext(); const closeModal = useCallback(() => setContextEntry(undefined), [setContextEntry]); const { width: vw, height: vh } = useViewportDimensions(); diff --git a/x-pack/plugins/infra/public/pages/metrics/index.tsx b/x-pack/plugins/infra/public/pages/metrics/index.tsx index f4d42b5994eb5c..e2f4705f17b7d7 100644 --- a/x-pack/plugins/infra/public/pages/metrics/index.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/index.tsx @@ -20,11 +20,12 @@ import { HelpCenterContent } from '../../components/help_center_content'; import { useReadOnlyBadge } from '../../hooks/use_readonly_badge'; import { MetricsExplorerOptionsContainer, + useMetricsExplorerOptionsContainerContext, DEFAULT_METRICS_EXPLORER_VIEW_STATE, } from './metrics_explorer/hooks/use_metrics_explorer_options'; import { WithMetricsExplorerOptionsUrlState } from '../../containers/metrics_explorer/with_metrics_explorer_options_url_state'; import { WithSource } from '../../containers/with_source'; -import { Source } from '../../containers/metrics_source'; +import { SourceProvider } from '../../containers/metrics_source'; import { MetricsExplorerPage } from './metrics_explorer'; import { SnapshotPage } from './inventory_view'; import { MetricDetail } from './metric_detail'; @@ -65,7 +66,7 @@ export const InfrastructurePage = ({ match }: RouteComponentProps) => { return ( - + @@ -109,7 +110,7 @@ export const InfrastructurePage = ({ match }: RouteComponentProps) => { render={(props) => ( {({ configuration, createDerivedIndexPattern }) => ( - + {configuration ? ( { ) : ( )} - + )} )} @@ -132,7 +133,7 @@ export const InfrastructurePage = ({ match }: RouteComponentProps) => { - + ); }; @@ -142,7 +143,7 @@ const PageContent = (props: { createDerivedIndexPattern: CreateDerivedIndexPattern; }) => { const { createDerivedIndexPattern, configuration } = props; - const { options } = useContext(MetricsExplorerOptionsContainer.Context); + const { options } = useMetricsExplorerOptionsContainerContext(); return ( { const nodeId = props.node.id; const nodeType = props.nodeType as InventoryItemType; const inventoryModel = findInventoryModel(nodeType); - const { sourceId } = useContext(Source.Context); + const { sourceId } = useSourceContext(); const { currentTimeRange } = useWaffleTimeContext(); const { loading, metadata } = useMetadata( nodeId, diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/properties/index.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/properties/index.tsx index 22c2af5496a607..65fa3bcfd01645 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/properties/index.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/properties/index.tsx @@ -5,12 +5,12 @@ * 2.0. */ -import React, { useCallback, useContext, useMemo } from 'react'; +import React, { useCallback, useMemo } from 'react'; import { i18n } from '@kbn/i18n'; import { EuiLoadingChart } from '@elastic/eui'; import { euiStyled } from '@kbn/kibana-react-plugin/common'; import { TabContent, TabProps } from '../shared'; -import { Source } from '../../../../../../../containers/metrics_source'; +import { useSourceContext } from '../../../../../../../containers/metrics_source'; import { findInventoryModel } from '../../../../../../../../common/inventory_models'; import { InventoryItemType } from '../../../../../../../../common/inventory_models/types'; import { useMetadata } from '../../../../../metric_detail/hooks/use_metadata'; @@ -23,7 +23,7 @@ const TabComponent = (props: TabProps) => { const nodeId = props.node.id; const nodeType = props.nodeType as InventoryItemType; const inventoryModel = findInventoryModel(nodeType); - const { sourceId } = useContext(Source.Context); + const { sourceId } = useSourceContext(); const { currentTimeRange } = useWaffleTimeContext(); const { applyFilterQuery } = useWaffleFiltersContext(); const { loading: metadataLoading, metadata } = useMetadata( diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/search_bar.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/search_bar.tsx index 1b9e33a0c4dfba..7386322774442b 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/search_bar.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/search_bar.tsx @@ -5,15 +5,15 @@ * 2.0. */ -import React, { useContext } from 'react'; +import React from 'react'; import { i18n } from '@kbn/i18n'; -import { Source } from '../../../../containers/metrics_source'; +import { useSourceContext } from '../../../../containers/metrics_source'; import { AutocompleteField } from '../../../../components/autocomplete_field'; import { WithKueryAutocompletion } from '../../../../containers/with_kuery_autocompletion'; import { useWaffleFiltersContext } from '../hooks/use_waffle_filters'; export const SearchBar = () => { - const { createDerivedIndexPattern } = useContext(Source.Context); + const { createDerivedIndexPattern } = useSourceContext(); const { applyFilterQueryFromKueryExpression, filterQueryDraft, diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/index.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/index.tsx index 47e8d739d73e8b..0c00b87722c8c6 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/index.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/index.tsx @@ -7,7 +7,7 @@ import { EuiErrorBoundary } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import React, { useContext } from 'react'; +import React from 'react'; import { useTrackPageview } from '@kbn/observability-plugin/public'; import { euiStyled } from '@kbn/kibana-react-plugin/common'; import { APP_WRAPPER_CLASS } from '@kbn/core/public'; @@ -17,7 +17,7 @@ import { DocumentTitle } from '../../../components/document_title'; import { SourceErrorPage } from '../../../components/source_error_page'; import { SourceLoadingPage } from '../../../components/source_loading_page'; -import { Source } from '../../../containers/metrics_source'; +import { useSourceContext } from '../../../containers/metrics_source'; import { useMetricsBreadcrumbs } from '../../../hooks/use_metrics_breadcrumbs'; import { LayoutView } from './components/layout_view'; import { SavedViewProvider } from '../../../containers/saved_view/saved_view'; @@ -36,7 +36,7 @@ export const SnapshotPage = () => { loadSource, source, metricIndicesExist, - } = useContext(Source.Context); + } = useSourceContext(); useTrackPageview({ app: 'infra_metrics', path: 'inventory' }); useTrackPageview({ app: 'infra_metrics', path: 'inventory', delay: 15000 }); const { source: optionsSource } = useWaffleOptionsContext(); diff --git a/x-pack/plugins/infra/public/pages/metrics/metric_detail/components/node_details_page.tsx b/x-pack/plugins/infra/public/pages/metrics/metric_detail/components/node_details_page.tsx index cf766bdb104e53..339374678ab7fc 100644 --- a/x-pack/plugins/infra/public/pages/metrics/metric_detail/components/node_details_page.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/metric_detail/components/node_details_page.tsx @@ -5,11 +5,11 @@ * 2.0. */ -import React, { useCallback, useEffect, useState, useContext } from 'react'; +import React, { useCallback, useEffect, useState } from 'react'; import dateMath from '@kbn/datemath'; import moment from 'moment'; import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; -import { Source } from '../../../../containers/metrics_source'; +import { useSourceContext } from '../../../../containers/metrics_source'; import { InventoryMetric, InventoryItemType } from '../../../../../common/inventory_models/types'; import { useNodeDetails } from '../hooks/use_node_details'; import { MetricsSideNav } from './side_nav'; @@ -53,7 +53,7 @@ const parseRange = (range: MetricsTimeInput) => { }; export const NodeDetailsPage = (props: Props) => { - const { metricIndicesExist } = useContext(Source.Context); + const { metricIndicesExist } = useSourceContext(); const [parsedTimeRange, setParsedTimeRange] = useState(parseRange(props.timeRange)); const { metrics, loading, makeRequest, error } = useNodeDetails( props.requiredMetrics, diff --git a/x-pack/plugins/infra/public/pages/metrics/metric_detail/index.tsx b/x-pack/plugins/infra/public/pages/metrics/metric_detail/index.tsx index e6843b98cf701e..823b9d703f502b 100644 --- a/x-pack/plugins/infra/public/pages/metrics/metric_detail/index.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/metric_detail/index.tsx @@ -6,14 +6,14 @@ */ import { i18n } from '@kbn/i18n'; -import React, { useContext, useState } from 'react'; +import React, { useState } from 'react'; import { EuiTheme, withTheme } from '@kbn/kibana-react-plugin/common'; import { useLinkProps } from '@kbn/observability-plugin/public'; import { DocumentTitle } from '../../../components/document_title'; import { withMetricPageProviders } from './page_providers'; import { useMetadata } from './hooks/use_metadata'; import { useMetricsBreadcrumbs } from '../../../hooks/use_metrics_breadcrumbs'; -import { Source } from '../../../containers/metrics_source'; +import { useSourceContext } from '../../../containers/metrics_source'; import { InfraLoadingPanel } from '../../../components/loading'; import { findInventoryModel } from '../../../../common/inventory_models'; import { NavItem } from './lib/side_nav_context'; @@ -38,7 +38,7 @@ export const MetricDetail = withMetricPageProviders( const nodeId = match.params.node; const nodeType = match.params.type as InventoryItemType; const inventoryModel = findInventoryModel(nodeType); - const { sourceId, metricIndicesExist } = useContext(Source.Context); + const { sourceId, metricIndicesExist } = useSourceContext(); const { timeRange, diff --git a/x-pack/plugins/infra/public/pages/metrics/metric_detail/page_providers.tsx b/x-pack/plugins/infra/public/pages/metrics/metric_detail/page_providers.tsx index 6f44d49ddce903..eec4c7db0977b9 100644 --- a/x-pack/plugins/infra/public/pages/metrics/metric_detail/page_providers.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/metric_detail/page_providers.tsx @@ -7,7 +7,7 @@ import { EuiErrorBoundary } from '@elastic/eui'; import React from 'react'; -import { Source } from '../../../containers/metrics_source'; +import { SourceProvider } from '../../../containers/metrics_source'; import { MetricsTimeProvider } from './hooks/use_metrics_time'; export const withMetricPageProviders = @@ -15,10 +15,10 @@ export const withMetricPageProviders = (props: T) => ( - + - + ); diff --git a/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/helpers/create_tsvb_link.ts b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/helpers/create_tsvb_link.ts index 7db25ae6898f11..a4e5cc4b92791e 100644 --- a/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/helpers/create_tsvb_link.ts +++ b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/helpers/create_tsvb_link.ts @@ -7,7 +7,7 @@ import { encode } from 'rison-node'; import uuid from 'uuid'; -import { set } from '@elastic/safer-lodash-set'; +import { set } from '@kbn/safer-lodash-set'; import { LinkDescriptor } from '@kbn/observability-plugin/public'; import { TIMESTAMP_FIELD } from '../../../../../../common/constants'; import { MetricsSourceConfigurationProperties } from '../../../../../../common/metrics_sources'; diff --git a/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/hooks/use_metric_explorer_state.test.tsx b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/hooks/use_metric_explorer_state.test.tsx index 67d3a71b6c1d40..3cd74c3560aa2d 100644 --- a/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/hooks/use_metric_explorer_state.test.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/hooks/use_metric_explorer_state.test.tsx @@ -25,9 +25,7 @@ const renderUseMetricsExplorerStateHook = () => renderHook((props) => useMetricsExplorerState(props.source, props.derivedIndexPattern), { initialProps: { source, derivedIndexPattern }, wrapper: ({ children }) => ( - - {children} - + {children} ), }); diff --git a/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/hooks/use_metric_explorer_state.ts b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/hooks/use_metric_explorer_state.ts index 39eb7c928997b0..4842125a6ff0cc 100644 --- a/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/hooks/use_metric_explorer_state.ts +++ b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/hooks/use_metric_explorer_state.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { useState, useCallback, useContext } from 'react'; +import { useState, useCallback } from 'react'; import { DataViewBase } from '@kbn/es-query'; import { MetricsSourceConfigurationProperties } from '../../../../../common/metrics_sources'; import { @@ -14,7 +14,7 @@ import { } from '../../../../../common/http_api/metrics_explorer'; import { useMetricsExplorerData } from './use_metrics_explorer_data'; import { - MetricsExplorerOptionsContainer, + useMetricsExplorerOptionsContainerContext, MetricsExplorerChartOptions, MetricsExplorerTimeOptions, MetricsExplorerOptions, @@ -42,7 +42,7 @@ export const useMetricsExplorerState = ( setChartOptions, setTimeRange, setOptions, - } = useContext(MetricsExplorerOptionsContainer.Context); + } = useMetricsExplorerOptionsContainerContext(); const { loading, error, data, loadData } = useMetricsExplorerData( options, diff --git a/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/hooks/use_metrics_explorer_options.ts b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/hooks/use_metrics_explorer_options.ts index 8bf64edcf89700..02cab766c57e9f 100644 --- a/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/hooks/use_metrics_explorer_options.ts +++ b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/hooks/use_metrics_explorer_options.ts @@ -208,4 +208,5 @@ export const useMetricsExplorerOptions = () => { }; }; -export const MetricsExplorerOptionsContainer = createContainer(useMetricsExplorerOptions); +export const [MetricsExplorerOptionsContainer, useMetricsExplorerOptionsContainerContext] = + createContainer(useMetricsExplorerOptions); diff --git a/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/index.tsx b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/index.tsx index a475ae1c88c9ae..f5269b99fd5c92 100644 --- a/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/index.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/index.tsx @@ -7,7 +7,7 @@ import { EuiErrorBoundary } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import React, { useEffect, useContext } from 'react'; +import React, { useEffect } from 'react'; import { useTrackPageview } from '@kbn/observability-plugin/public'; import { MetricsSourceConfigurationProperties } from '../../../../common/metrics_sources'; import { useMetricsBreadcrumbs } from '../../../hooks/use_metrics_breadcrumbs'; @@ -16,7 +16,7 @@ import { NoData } from '../../../components/empty_states'; import { MetricsExplorerCharts } from './components/charts'; import { MetricsExplorerToolbar } from './components/toolbar'; import { useMetricsExplorerState } from './hooks/use_metric_explorer_state'; -import { Source } from '../../../containers/metrics_source'; +import { useSourceContext } from '../../../containers/metrics_source'; import { useSavedViewContext } from '../../../containers/saved_view/saved_view'; import { MetricsPageTemplate } from '../page_template'; import { metricsExplorerTitle } from '../../../translations'; @@ -51,7 +51,7 @@ export const MetricsExplorerPage = ({ source, derivedIndexPattern }: MetricsExpl useTrackPageview({ app: 'infra_metrics', path: 'metrics_explorer' }); useTrackPageview({ app: 'infra_metrics', path: 'metrics_explorer', delay: 15000 }); - const { metricIndicesExist } = useContext(Source.Context); + const { metricIndicesExist } = useSourceContext(); useEffect(() => { if (currentView) { onViewStateChange(currentView); diff --git a/x-pack/plugins/infra/public/pages/metrics/page_template.tsx b/x-pack/plugins/infra/public/pages/metrics/page_template.tsx index 53a0cc21dd7cec..4d4dec50dd74c5 100644 --- a/x-pack/plugins/infra/public/pages/metrics/page_template.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/page_template.tsx @@ -7,7 +7,7 @@ import { i18n } from '@kbn/i18n'; import type { LazyObservabilityPageTemplateProps } from '@kbn/observability-plugin/public'; -import { KibanaPageTemplateProps } from '@kbn/shared-ux-components'; +import type { NoDataConfig } from '@kbn/shared-ux-page-kibana-template'; import React from 'react'; import { noMetricIndicesPromptDescription, @@ -33,7 +33,7 @@ export const MetricsPageTemplate: React.FC = ({ }, } = useKibanaContextForPlugin(); - const noDataConfig: KibanaPageTemplateProps['noDataConfig'] = hasData + const noDataConfig: NoDataConfig | undefined = hasData ? undefined : { solution: i18n.translate('xpack.infra.metrics.noDataConfig.solutionName', { diff --git a/x-pack/plugins/infra/public/pages/metrics/settings/source_configuration_settings.tsx b/x-pack/plugins/infra/public/pages/metrics/settings/source_configuration_settings.tsx index eab8a82bc2d1e3..1b21dfbc800f35 100644 --- a/x-pack/plugins/infra/public/pages/metrics/settings/source_configuration_settings.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/settings/source_configuration_settings.tsx @@ -15,10 +15,10 @@ import { } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; -import React, { useCallback, useContext, useMemo } from 'react'; +import React, { useCallback, useMemo } from 'react'; import { Prompt } from '@kbn/observability-plugin/public'; import { SourceLoadingPage } from '../../../components/source_loading_page'; -import { Source } from '../../../containers/metrics_source'; +import { useSourceContext } from '../../../containers/metrics_source'; import { useInfraMLCapabilitiesContext } from '../../../containers/ml/infra_ml_capabilities'; import { IndicesConfigurationPanel } from './indices_configuration_panel'; import { MLConfigurationPanel } from './ml_configuration_panel'; @@ -48,7 +48,7 @@ export const SourceConfigurationSettings = ({ isLoading, isUninitialized, updateSourceConfiguration, - } = useContext(Source.Context); + } = useSourceContext(); const { indicesConfigurationProps, diff --git a/x-pack/plugins/infra/server/lib/metrics/index.ts b/x-pack/plugins/infra/server/lib/metrics/index.ts index c4641e265ea555..54dd69adb3ff4f 100644 --- a/x-pack/plugins/infra/server/lib/metrics/index.ts +++ b/x-pack/plugins/infra/server/lib/metrics/index.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { set } from '@elastic/safer-lodash-set'; +import { set } from '@kbn/safer-lodash-set'; import { ThrowReporter } from 'io-ts/lib/ThrowReporter'; import { TIMESTAMP_FIELD } from '../../../common/constants'; import { MetricsAPIRequest, MetricsAPIResponse, afterKeyObjectRT } from '../../../common/http_api'; diff --git a/x-pack/plugins/infra/server/routes/metadata/lib/get_node_info.ts b/x-pack/plugins/infra/server/routes/metadata/lib/get_node_info.ts index 97a0707a4c2159..bc93d1f539e2ac 100644 --- a/x-pack/plugins/infra/server/routes/metadata/lib/get_node_info.ts +++ b/x-pack/plugins/infra/server/routes/metadata/lib/get_node_info.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { set } from '@elastic/safer-lodash-set'; +import { set } from '@kbn/safer-lodash-set'; import { first, startsWith } from 'lodash'; import type { InfraPluginRequestHandlerContext } from '../../../types'; import { KibanaFramework } from '../../../lib/adapters/framework/kibana_framework_adapter'; diff --git a/x-pack/plugins/infra/server/utils/create_afterkey_handler.ts b/x-pack/plugins/infra/server/utils/create_afterkey_handler.ts index 6d41f17a6bb5e4..de797385c71710 100644 --- a/x-pack/plugins/infra/server/utils/create_afterkey_handler.ts +++ b/x-pack/plugins/infra/server/utils/create_afterkey_handler.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { set } from '@elastic/safer-lodash-set'; +import { set } from '@kbn/safer-lodash-set'; import { InfraDatabaseSearchResponse } from '../lib/adapters/framework'; export const createAfterKeyHandler = diff --git a/x-pack/plugins/kubernetes_security/public/components/container_name_widget/hooks.ts b/x-pack/plugins/kubernetes_security/public/components/container_name_widget/hooks.ts index 66dcbc5b50265f..c1b7c091b17a42 100644 --- a/x-pack/plugins/kubernetes_security/public/components/container_name_widget/hooks.ts +++ b/x-pack/plugins/kubernetes_security/public/components/container_name_widget/hooks.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { useInfiniteQuery } from 'react-query'; +import { useInfiniteQuery } from '@tanstack/react-query'; import { CoreStart } from '@kbn/core/public'; import { useKibana } from '@kbn/kibana-react-plugin/public'; import { QUERY_KEY_CONTAINER_NAME_WIDGET, AGGREGATE_ROUTE } from '../../../common/constants'; diff --git a/x-pack/plugins/kubernetes_security/public/components/count_widget/hooks.ts b/x-pack/plugins/kubernetes_security/public/components/count_widget/hooks.ts index d194e74ae8c629..936419d06c7035 100644 --- a/x-pack/plugins/kubernetes_security/public/components/count_widget/hooks.ts +++ b/x-pack/plugins/kubernetes_security/public/components/count_widget/hooks.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { useInfiniteQuery } from 'react-query'; +import { useInfiniteQuery } from '@tanstack/react-query'; import { CoreStart } from '@kbn/core/public'; import { useKibana } from '@kbn/kibana-react-plugin/public'; import { QUERY_KEY_COUNT_WIDGET, COUNT_ROUTE } from '../../../common/constants'; diff --git a/x-pack/plugins/kubernetes_security/public/components/percent_widget/hooks.ts b/x-pack/plugins/kubernetes_security/public/components/percent_widget/hooks.ts index f13cdfa0ac7a4e..5f5bf99ffd26f3 100644 --- a/x-pack/plugins/kubernetes_security/public/components/percent_widget/hooks.ts +++ b/x-pack/plugins/kubernetes_security/public/components/percent_widget/hooks.ts @@ -4,7 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { useQuery } from 'react-query'; +import { useQuery } from '@tanstack/react-query'; import { CoreStart } from '@kbn/core/public'; import { useKibana } from '@kbn/kibana-react-plugin/public'; import { QUERY_KEY_PERCENT_WIDGET, AGGREGATE_ROUTE } from '../../../common/constants'; diff --git a/x-pack/plugins/kubernetes_security/public/components/tree_view_container/dynamic_tree_view/hooks.ts b/x-pack/plugins/kubernetes_security/public/components/tree_view_container/dynamic_tree_view/hooks.ts index ef6c849ee92421..0b8411e7107289 100644 --- a/x-pack/plugins/kubernetes_security/public/components/tree_view_container/dynamic_tree_view/hooks.ts +++ b/x-pack/plugins/kubernetes_security/public/components/tree_view_container/dynamic_tree_view/hooks.ts @@ -4,7 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { useInfiniteQuery } from 'react-query'; +import { useInfiniteQuery } from '@tanstack/react-query'; import { CoreStart } from '@kbn/core/public'; import { useKibana } from '@kbn/kibana-react-plugin/public'; import { QueryDslQueryContainerBool } from '../../../types'; diff --git a/x-pack/plugins/kubernetes_security/public/components/tree_view_container/dynamic_tree_view/index.test.tsx b/x-pack/plugins/kubernetes_security/public/components/tree_view_container/dynamic_tree_view/index.test.tsx index 6a4595ddfb9a34..1763a881c2ba9b 100644 --- a/x-pack/plugins/kubernetes_security/public/components/tree_view_container/dynamic_tree_view/index.test.tsx +++ b/x-pack/plugins/kubernetes_security/public/components/tree_view_container/dynamic_tree_view/index.test.tsx @@ -18,8 +18,6 @@ describe('DynamicTreeView component', () => { let mockedContext: AppContextTestRender; let mockedApi: AppContextTestRender['coreStart']['http']['get']; - const waitForApiCall = () => waitFor(() => expect(mockedApi).toHaveBeenCalled()); - const defaultProps = { globalFilter: { startDate: Date.now().toString(), @@ -69,8 +67,9 @@ describe('DynamicTreeView component', () => { it('should show loading state while retrieving empty data and hide it when settled', async () => { render(); expect(renderResult.queryByText(/loading/i)).toBeInTheDocument(); - await waitForApiCall(); - expect(renderResult.queryByText(/loading/i)).not.toBeInTheDocument(); + await waitFor(() => { + expect(renderResult.queryByText(/loading/i)).not.toBeInTheDocument(); + }); }); }); @@ -92,39 +91,42 @@ describe('DynamicTreeView component', () => { render({ tree, }); - await waitForApiCall(); - expect(mockedApi).toHaveBeenCalledWith( - '/internal/kubernetes_security/multi_terms_aggregate', - { - query: { - groupBys: `[{"field":"${key}"},{"field":"orchestrator.cluster.name","missing":""}]`, - index: '*-logs', - page: 0, - perPage: 50, - query: '{"bool":{"filter":[],"must":[],"must_not":[],"should":[]}}', - }, - } - ); + await waitFor(() => { + expect(mockedApi).toHaveBeenCalledWith( + '/internal/kubernetes_security/multi_terms_aggregate', + { + query: { + groupBys: `[{"field":"${key}"},{"field":"orchestrator.cluster.name","missing":""}]`, + index: '*-logs', + page: 0, + perPage: 50, + query: '{"bool":{"filter":[],"must":[],"must_not":[],"should":[]}}', + }, + } + ); + }); }); it('should render the parent level based on api response', async () => { render({ tree, }); - await waitForApiCall(); - ['awp-demo-gke-main', 'awp-demo-gke-test'].forEach((cluster) => { - expect(renderResult.queryByText(cluster)).toBeInTheDocument(); + await waitFor(() => { + ['awp-demo-gke-main', 'awp-demo-gke-test'].forEach((cluster) => { + expect(renderResult.queryByText(cluster)).toBeInTheDocument(); + }); }); }); it('should trigger a callback when tree node is clicked', async () => { const callback = jest.fn(); render({ tree, onSelect: callback }); - await waitForApiCall(); - renderResult.getByRole('button', { name: 'awp-demo-gke-main' }).click(); + await waitFor(() => { + renderResult.getByRole('button', { name: 'awp-demo-gke-main' }).click(); + }); expect(callback).toHaveBeenCalled(); }); @@ -156,37 +158,43 @@ describe('DynamicTreeView component', () => { it('should make a children api call with filter when parent is expanded', async () => { render({ tree }); - await waitForApiCall(); - renderResult.getByRole('button', { name: parent }).click(); + await waitFor(() => { + renderResult.getByRole('button', { name: parent }).click(); + }); mockedApi.mockResolvedValueOnce(nodeResponseMock); - await waitForApiCall(); - expect(mockedApi).toHaveBeenCalledWith('/internal/kubernetes_security/aggregate', { - query: { - groupBy: 'node', - index: '*-logs', - page: 0, - perPage: 50, - query: `{"bool":{"filter":[{"term":{"orchestrator.cluster.id":"${parent}"}}],"must":[],"must_not":[],"should":[]}}`, - }, + await waitFor(() => { + expect(mockedApi).toHaveBeenCalledWith('/internal/kubernetes_security/aggregate', { + query: { + groupBy: 'node', + index: '*-logs', + page: 0, + perPage: 50, + query: `{"bool":{"filter":[{"term":{"orchestrator.cluster.id":"${parent}"}}],"must":[],"must_not":[],"should":[]}}`, + }, + }); }); }); it('should render children when parent is expanded based on api request', async () => { render({ tree }); - await waitForApiCall(); - renderResult.getByRole('button', { name: parent }).click(); - - mockedApi.mockResolvedValueOnce(nodeResponseMock); + await waitFor(() => { + expect(renderResult.getByRole('button', { name: parent })).toBeTruthy(); + mockedApi.mockResolvedValueOnce(nodeResponseMock); + renderResult.getByRole('button', { name: parent }).click(); + }); // check if children has loading state - expect(renderResult.queryByText(/loading/i)).toBeInTheDocument(); - await waitForApiCall(); + await waitFor(() => { + expect(renderResult.queryByText(/loading/i)).toBeInTheDocument(); + }); - ['default', 'kube-system', 'production', 'qa', 'staging'].forEach((node) => { - expect(renderResult.queryByText(node)).toBeInTheDocument(); + await waitFor(() => { + ['default', 'kube-system', 'production', 'qa', 'staging'].forEach((node) => { + expect(renderResult.queryByText(node)).toBeInTheDocument(); + }); }); }); }); diff --git a/x-pack/plugins/kubernetes_security/public/methods/index.tsx b/x-pack/plugins/kubernetes_security/public/methods/index.tsx index f0a140a6127052..362560c3b1ddf0 100644 --- a/x-pack/plugins/kubernetes_security/public/methods/index.tsx +++ b/x-pack/plugins/kubernetes_security/public/methods/index.tsx @@ -7,7 +7,7 @@ import React, { lazy, Suspense } from 'react'; import { EuiLoadingSpinner } from '@elastic/eui'; -import { QueryClient, QueryClientProvider } from 'react-query'; +import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { KubernetesSecurityDeps } from '../types'; // Initializing react-query diff --git a/x-pack/plugins/kubernetes_security/public/test/index.tsx b/x-pack/plugins/kubernetes_security/public/test/index.tsx index 6174925b6003c4..244560d366ac4b 100644 --- a/x-pack/plugins/kubernetes_security/public/test/index.tsx +++ b/x-pack/plugins/kubernetes_security/public/test/index.tsx @@ -8,7 +8,7 @@ import React, { memo, ReactNode, useMemo } from 'react'; import { createMemoryHistory, MemoryHistory } from 'history'; import { render as reactRender, RenderOptions, RenderResult } from '@testing-library/react'; -import { QueryClient, QueryClientProvider, setLogger } from 'react-query'; +import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { Router } from 'react-router-dom'; import { History } from 'history'; import useObservable from 'react-use/lib/useObservable'; @@ -20,15 +20,6 @@ import { EuiThemeProvider } from '@kbn/kibana-react-plugin/common'; type UiRender = (ui: React.ReactElement, options?: RenderOptions) => RenderResult; -// hide react-query output in console -setLogger({ - error: () => {}, - // eslint-disable-next-line no-console - log: console.log, - // eslint-disable-next-line no-console - warn: console.warn, -}); - /** * Mocked app root context renderer */ @@ -113,6 +104,14 @@ export const createAppRootMockRenderer = (): AppContextTestRender => { cacheTime: Infinity, }, }, + // hide react-query output in console + logger: { + error: () => {}, + // eslint-disable-next-line no-console + log: console.log, + // eslint-disable-next-line no-console + warn: console.warn, + }, }); const AppWrapper: React.FC<{ children: React.ReactElement }> = ({ children }) => ( diff --git a/x-pack/plugins/lens/common/index.ts b/x-pack/plugins/lens/common/index.ts index e0600bd18afc11..45dd41422b0189 100644 --- a/x-pack/plugins/lens/common/index.ts +++ b/x-pack/plugins/lens/common/index.ts @@ -8,7 +8,6 @@ // TODO: https://github.com/elastic/kibana/issues/110891 /* eslint-disable @kbn/eslint/no_export_all */ -export * from './api'; export * from './constants'; export * from './types'; diff --git a/x-pack/plugins/lens/common/types.ts b/x-pack/plugins/lens/common/types.ts index d7432e0f10b6f7..f187ff02d5db9b 100644 --- a/x-pack/plugins/lens/common/types.ts +++ b/x-pack/plugins/lens/common/types.ts @@ -88,7 +88,7 @@ export interface PieVisualizationState { layers: PieLayerState[]; palette?: PaletteOutput; } -export interface MetricState { +export interface LegacyMetricState { layerId: string; accessor?: string; layerType: LayerType; diff --git a/x-pack/plugins/lens/kibana.json b/x-pack/plugins/lens/kibana.json index cb208eb60dafff..bff30e66a9bc84 100644 --- a/x-pack/plugins/lens/kibana.json +++ b/x-pack/plugins/lens/kibana.json @@ -26,7 +26,8 @@ "expressionMetricVis", "expressionHeatmap", "eventAnnotation", - "unifiedSearch" + "unifiedSearch", + "unifiedFieldList" ], "optionalPlugins": [ "expressionXY", diff --git a/x-pack/plugins/lens/public/app_plugin/app.test.tsx b/x-pack/plugins/lens/public/app_plugin/app.test.tsx index 03cf38f141f0dc..7f166cb54e299e 100644 --- a/x-pack/plugins/lens/public/app_plugin/app.test.tsx +++ b/x-pack/plugins/lens/public/app_plugin/app.test.tsx @@ -1415,7 +1415,8 @@ describe('Lens App', () => { layers: [ { indexPatternId: 'ff959d40-b880-11e8-a6d9-e546fe2bba5f', - timeFieldName: 'order_date', + xFieldName: 'order_date', + xMode: 'date_histogram', chartType: 'area', axisPosition: 'left', palette: { diff --git a/x-pack/plugins/lens/public/app_plugin/mounter.tsx b/x-pack/plugins/lens/public/app_plugin/mounter.tsx index 34a06439473a39..8c73d826724ea7 100644 --- a/x-pack/plugins/lens/public/app_plugin/mounter.tsx +++ b/x-pack/plugins/lens/public/app_plugin/mounter.tsx @@ -96,6 +96,7 @@ export async function getLensServices( dataViewEditor: startDependencies.dataViewEditor, dataViewFieldEditor: startDependencies.dataViewFieldEditor, dashboard: startDependencies.dashboard, + charts: startDependencies.charts, getOriginatingAppName: () => { return embeddableEditorIncomingState?.originatingApp ? stateTransfer?.getAppNameFromId(embeddableEditorIncomingState.originatingApp) diff --git a/x-pack/plugins/lens/public/app_plugin/types.ts b/x-pack/plugins/lens/public/app_plugin/types.ts index 6a2718fc498203..be49ca768acdc3 100644 --- a/x-pack/plugins/lens/public/app_plugin/types.ts +++ b/x-pack/plugins/lens/public/app_plugin/types.ts @@ -37,6 +37,7 @@ import { ACTION_CONVERT_TO_LENS } from '@kbn/visualizations-plugin/public'; import type { EmbeddableEditorState, EmbeddableStateTransfer } from '@kbn/embeddable-plugin/public'; import type { PresentationUtilPluginStart } from '@kbn/presentation-util-plugin/public'; import type { FieldFormatsStart } from '@kbn/field-formats-plugin/public'; +import type { ChartsPluginSetup } from '@kbn/charts-plugin/public'; import type { DatasourceMap, EditorFrameInstance, @@ -140,6 +141,7 @@ export interface LensAppServices { getOriginatingAppName: () => string | undefined; presentationUtil: PresentationUtilPluginStart; spaces: SpacesApi; + charts: ChartsPluginSetup; discover?: DiscoverStart; // Temporarily required until the 'by value' paradigm is default. diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/dimension_container.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/dimension_container.tsx index e660df8ff7bb96..3ddf2a2cc4b75c 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/dimension_container.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/dimension_container.tsx @@ -17,9 +17,6 @@ import { EuiFlexGroup, EuiFlexItem, EuiFocusTrap, - EuiOutsideClickDetector, - EuiWindowEvent, - keys, } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; @@ -37,7 +34,10 @@ function fromExcludedClickTarget(event: Event) { node !== null; node = node!.parentElement ) { - if (node.classList!.contains(DONT_CLOSE_DIMENSION_CONTAINER_ON_CLICK_CLASS)) { + if ( + node.classList!.contains(DONT_CLOSE_DIMENSION_CONTAINER_ON_CLICK_CLASS) || + node.classList!.contains('euiBody-hasPortalContent') + ) { return true; } } @@ -69,18 +69,6 @@ export function DimensionContainer({ return canClose; }, [handleClose]); - const closeOnEscape = useCallback( - (event: KeyboardEvent) => { - if (event.key === keys.ESCAPE) { - const canClose = closeFlyout(); - if (canClose) { - event.preventDefault(); - } - } - }, - [closeFlyout] - ); - useEffect(() => { if (isOpen) { document.body.classList.add('lnsBody--overflowHidden'); @@ -94,81 +82,80 @@ export function DimensionContainer({ return isOpen ? (
- - - { - if (isFullscreen || fromExcludedClickTarget(event)) { - return; + { + if (isFullscreen || fromExcludedClickTarget(event)) { + return; + } + closeFlyout(); + }} + onEscapeKey={closeFlyout} + > +
{ + if (isOpen) { + // EuiFocusTrap interferes with animating elements with absolute position: + // running this onAnimationEnd, otherwise the flyout pushes content when animating + setFocusTrapIsEnabled(true); } - closeFlyout(); }} - isDisabled={!isOpen} > -
{ - if (isOpen) { - // EuiFocusTrap interferes with animating elements with absolute position: - // running this onAnimationEnd, otherwise the flyout pushes content when animating - setFocusTrapIsEnabled(true); - } - }} - > - - - - -

- - {i18n.translate('xpack.lens.configure.configurePanelTitle', { - defaultMessage: '{groupLabel}', - values: { - groupLabel, - }, - })} - -

-
-
+ + + + +

+ + {i18n.translate('xpack.lens.configure.configurePanelTitle', { + defaultMessage: '{groupLabel}', + values: { + groupLabel, + }, + })} + +

+
+
- - - -
-
+ + + +
+
-
{panel}
+
{panel}
- - - {i18n.translate('xpack.lens.dimensionContainer.close', { - defaultMessage: 'Close', - })} - - -
- + + + {i18n.translate('xpack.lens.dimensionContainer.close', { + defaultMessage: 'Close', + })} + + +
) : null; diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.tsx index 86e896c29910c3..544835d2e3c21d 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.tsx @@ -614,7 +614,8 @@ export function LayerPanel( setState: updateDataLayerState, supportStaticValue: Boolean(activeGroup.supportStaticValue), paramEditorCustomProps: activeGroup.paramEditorCustomProps, - supportFieldFormat: activeGroup.supportFieldFormat !== false, + enableFormatSelector: activeGroup.enableFormatSelector !== false, + formatSelectorOptions: activeGroup.formatSelectorOptions, layerType: activeVisualization.getLayerType(layerId, visualizationState), indexPatterns: dataViews.indexPatterns, existingFields: dataViews.existingFields, diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_helpers.test.ts b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_helpers.test.ts index 5cc62012a50949..e566443640d857 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_helpers.test.ts +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_helpers.test.ts @@ -288,7 +288,8 @@ describe('suggestion helpers', () => { layers: [ { indexPatternId: 'ff959d40-b880-11e8-a6d9-e546fe2bba5f', - timeFieldName: 'order_date', + xFieldName: 'order_date', + xMode: 'date_histogram', chartType: 'area', axisPosition: 'left', palette: { @@ -369,7 +370,8 @@ describe('suggestion helpers', () => { layers: [ { indexPatternId: 'ff959d40-b880-11e8-a6d9-e546fe2bba5f', - timeFieldName: 'order_date', + xFieldName: 'order_date', + xMode: 'date_histogram', chartType: 'area', axisPosition: 'left', palette: { diff --git a/x-pack/plugins/lens/public/embeddable/embeddable_component.tsx b/x-pack/plugins/lens/public/embeddable/embeddable_component.tsx index 78aae56c5b9ad3..98c8d363a45b77 100644 --- a/x-pack/plugins/lens/public/embeddable/embeddable_component.tsx +++ b/x-pack/plugins/lens/public/embeddable/embeddable_component.tsx @@ -24,8 +24,9 @@ import type { LensByReferenceInput, LensByValueInput } from './embeddable'; import type { Document } from '../persistence'; import type { IndexPatternPersistedState } from '../indexpattern_datasource/types'; import type { XYState } from '../visualizations/xy/types'; -import type { PieVisualizationState, MetricState } from '../../common'; +import type { PieVisualizationState, LegacyMetricState } from '../../common'; import type { DatatableVisualizationState } from '../visualizations/datatable/visualization'; +import type { MetricVisualizationState } from '../visualizations/metric/visualization'; import type { HeatmapVisualizationState } from '../visualizations/heatmap/types'; import type { GaugeVisualizationState } from '../visualizations/gauge/constants'; @@ -51,7 +52,8 @@ export type TypedLensByValueInput = Omit & { | LensAttributes<'lnsXY', XYState> | LensAttributes<'lnsPie', PieVisualizationState> | LensAttributes<'lnsDatatable', DatatableVisualizationState> - | LensAttributes<'lnsMetric', MetricState> + | LensAttributes<'lnsLegacyMetric', LegacyMetricState> + | LensAttributes<'lnsMetric', MetricVisualizationState> | LensAttributes<'lnsHeatmap', HeatmapVisualizationState> | LensAttributes<'lnsGauge', GaugeVisualizationState> | LensAttributes; diff --git a/x-pack/plugins/lens/public/index.ts b/x-pack/plugins/lens/public/index.ts index 82e510dbb63931..776d8731d7eae8 100644 --- a/x-pack/plugins/lens/public/index.ts +++ b/x-pack/plugins/lens/public/index.ts @@ -32,7 +32,7 @@ export type { VisualizationSuggestion, } from './types'; export type { - MetricState, + LegacyMetricState as MetricState, ValueLabelConfig, PieVisualizationState, PieLayerState, diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/dimension_editor.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/dimension_editor.tsx index 284caa2e35f35b..a87e7cd3cac6ca 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/dimension_editor.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/dimension_editor.tsx @@ -95,7 +95,8 @@ export function DimensionEditor(props: DimensionEditorProps) { toggleFullscreen, isFullscreen, supportStaticValue, - supportFieldFormat = true, + enableFormatSelector = true, + formatSelectorOptions, layerType, paramEditorCustomProps, } = props; @@ -979,8 +980,6 @@ export function DimensionEditor(props: DimensionEditorProps) { <> {!incompleteInfo && selectedColumn && temporaryState === 'none' && ( { @@ -1012,11 +1011,15 @@ export function DimensionEditor(props: DimensionEditorProps) { /> )} - {supportFieldFormat && + {enableFormatSelector && !isFullscreen && selectedColumn && (selectedColumn.dataType === 'number' || selectedColumn.operationType === 'range') ? ( - + ) : null}
diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/dimension_panel.test.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/dimension_panel.test.tsx index 35bd94d4482700..b64e12b7bf0a49 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/dimension_panel.test.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/dimension_panel.test.tsx @@ -244,6 +244,8 @@ describe('IndexPatternDimensionEditorPanel', () => { isFullscreen: false, supportStaticValue: false, toggleFullscreen: jest.fn(), + enableFormatSelector: true, + formatSelectorOptions: undefined, }; jest.clearAllMocks(); diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/format_selector.test.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/format_selector.test.tsx index 60fdb382322a6e..d59cb4f136fda3 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/format_selector.test.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/format_selector.test.tsx @@ -86,4 +86,18 @@ describe('FormatSelector', () => { component.update(); expect(props.onChange).toBeCalledWith({ id: 'bytes', params: { suffix: 'GB' } }); }); + describe('options', () => { + it('can disable the extra options', () => { + const props = getDefaultProps(); + const component = mount( + + ); + expect(component.exists('[data-test-subj="indexPattern-dimension-formatDecimals"]')).toBe( + false + ); + expect(component.exists('[data-test-subj="indexPattern-dimension-formatSuffix"]')).toBe( + false + ); + }); + }); }); diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/format_selector.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/format_selector.tsx index 49231e64d53bea..5a6fc9aab91eb5 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/format_selector.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/format_selector.tsx @@ -51,9 +51,14 @@ const suffixLabel = i18n.translate('xpack.lens.indexPattern.suffixLabel', { defaultMessage: 'Suffix', }); +export interface FormatSelectorOptions { + disableExtraOptions?: boolean; +} + interface FormatSelectorProps { selectedColumn: GenericIndexPatternColumn; onChange: (newFormat?: { id: string; params?: Record }) => void; + options?: FormatSelectorOptions; } const RANGE_MIN = 0; @@ -149,9 +154,9 @@ export function FormatSelector(props: FormatSelectorProps) { selectedOptions={currentOption} onChange={onChangeWrapped} /> - {currentFormat ? ( + {currentFormat && !props.options?.disableExtraOptions ? ( <> - + - + + { diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/field_item.scss b/x-pack/plugins/lens/public/indexpattern_datasource/field_item.scss index b96a670144d37f..a309e37938cdac 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/field_item.scss +++ b/x-pack/plugins/lens/public/indexpattern_datasource/field_item.scss @@ -50,23 +50,6 @@ color: $euiColorDarkShade; } -.lnsFieldItem__topValue { - margin-bottom: $euiSizeS; - - &:last-of-type { - margin-bottom: 0; - } -} - -.lnsFieldItem__topValueProgress { - background-color: $euiColorLightestShade; - - // sass-lint:disable-block no-vendor-prefixes - &::-webkit-progress-bar { - background-color: $euiColorLightestShade; - } -} - .lnsFieldItem__fieldPanel { min-width: 260px; max-width: 300px; diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/field_item.test.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/field_item.test.tsx index 3c3b81cd126df3..615279b71b82c5 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/field_item.test.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/field_item.test.tsx @@ -18,18 +18,45 @@ import { chartPluginMock } from '@kbn/charts-plugin/public/mocks'; import { documentField } from './document_field'; import { uiActionsPluginMock } from '@kbn/ui-actions-plugin/public/mocks'; import { FieldFormatsStart } from '@kbn/field-formats-plugin/public'; +import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public'; +import { dataPluginMock } from '@kbn/data-plugin/public/mocks'; +import { dataViewPluginMocks } from '@kbn/data-views-plugin/public/mocks'; +import type { DataView } from '@kbn/data-views-plugin/common'; +import { loadFieldStats } from '@kbn/unified-field-list-plugin/public'; import { DOCUMENT_FIELD_NAME } from '../../common'; +jest.mock('@kbn/unified-field-list-plugin/public/services/field_stats', () => ({ + loadFieldStats: jest.fn().mockResolvedValue({}), +})); + const chartsThemeService = chartPluginMock.createSetupContract().theme; -function clickField(wrapper: ReactWrapper, field: string) { - wrapper.find(`[data-test-subj="lnsFieldListPanelField-${field}"] button`).simulate('click'); -} +const clickField = async (wrapper: ReactWrapper, field: string) => { + await act(async () => { + wrapper.find(`[data-test-subj="lnsFieldListPanelField-${field}"] button`).simulate('click'); + }); +}; + +const mockedServices = { + data: dataPluginMock.createStartContract(), + dataViews: dataViewPluginMocks.createStartContract(), + fieldFormats: fieldFormatsServiceMock.createStartContract(), + charts: chartPluginMock.createSetupContract(), + uiSettings: coreMock.createStart().uiSettings, +}; + +const InnerFieldItemWrapper: React.FC = (props) => { + return ( + + + + ); +}; describe('IndexPattern Field Item', () => { let defaultProps: FieldItemProps; let indexPattern: IndexPattern; - let core: ReturnType; + let dataView: DataView; beforeEach(() => { indexPattern = { @@ -83,8 +110,6 @@ describe('IndexPattern Field Item', () => { ], } as IndexPattern; - core = coreMock.createSetup(); - core.http.post.mockClear(); defaultProps = { indexPattern, fieldFormats: { @@ -93,7 +118,7 @@ describe('IndexPattern Field Item', () => { convert: jest.fn((s: unknown) => JSON.stringify(s)), })), } as unknown as FieldFormatsStart, - core, + core: coreMock.createStart(), highlight: '', dateRange: { fromDate: 'now-7d', @@ -116,10 +141,19 @@ describe('IndexPattern Field Item', () => { hasSuggestionForField: () => false, uiActions: uiActionsPluginMock.createStartContract(), }; + + dataView = { + ...indexPattern, + getFormatterForField: defaultProps.fieldFormats.getDefaultInstance, + } as unknown as DataView; + + (mockedServices.dataViews.get as jest.Mock).mockImplementation(() => { + return Promise.resolve(dataView); + }); }); it('should display displayName of a field', () => { - const wrapper = mountWithIntl(); + const wrapper = mountWithIntl(); // Using .toContain over .toEqual because this element includes text from // which can't be seen, but shows in the text content @@ -128,15 +162,12 @@ describe('IndexPattern Field Item', () => { ); }); - it('should render edit field button if callback is set', () => { - core.http.post.mockImplementation(() => { - return new Promise(() => {}); - }); + it('should render edit field button if callback is set', async () => { const editFieldSpy = jest.fn(); const wrapper = mountWithIntl( - + ); - clickField(wrapper, 'bytes'); + await clickField(wrapper, 'bytes'); wrapper.update(); const popoverContent = wrapper.find(EuiPopover).prop('children'); act(() => { @@ -148,20 +179,17 @@ describe('IndexPattern Field Item', () => { expect(editFieldSpy).toHaveBeenCalledWith('bytes'); }); - it('should not render edit field button for document field', () => { - core.http.post.mockImplementation(() => { - return new Promise(() => {}); - }); + it('should not render edit field button for document field', async () => { const editFieldSpy = jest.fn(); const wrapper = mountWithIntl( - ); - clickField(wrapper, documentField.name); + await clickField(wrapper, documentField.name); wrapper.update(); const popoverContent = wrapper.find(EuiPopover).prop('children'); expect( @@ -174,30 +202,33 @@ describe('IndexPattern Field Item', () => { it('should request field stats every time the button is clicked', async () => { let resolveFunction: (arg: unknown) => void; - core.http.post.mockImplementation(() => { + (loadFieldStats as jest.Mock).mockImplementation(() => { return new Promise((resolve) => { resolveFunction = resolve; }); }); - const wrapper = mountWithIntl(); + const wrapper = mountWithIntl(); - clickField(wrapper, 'bytes'); + await clickField(wrapper, 'bytes'); - expect(core.http.post).toHaveBeenCalledWith(`/api/lens/index_stats/1/field`, { - body: JSON.stringify({ - dslQuery: { - bool: { - must: [], - filter: [], - should: [], - must_not: [], - }, + await wrapper.update(); + + expect(loadFieldStats).toHaveBeenCalledWith({ + abortController: new AbortController(), + services: { data: mockedServices.data }, + dataView, + dslQuery: { + bool: { + must: [], + filter: [], + should: [], + must_not: [], }, - fromDate: 'now-7d', - toDate: 'now', - fieldName: 'bytes', - }), + }, + fromDate: 'now-7d', + toDate: 'now', + field: defaultProps.field, }); expect(wrapper.find(EuiPopover).prop('isOpen')).toEqual(true); @@ -218,12 +249,15 @@ describe('IndexPattern Field Item', () => { }); }); - wrapper.update(); + await wrapper.update(); expect(wrapper.find(EuiLoadingSpinner)).toHaveLength(0); - clickField(wrapper, 'bytes'); - expect(core.http.post).toHaveBeenCalledTimes(1); + await clickField(wrapper, 'bytes'); + + await wrapper.update(); + + expect(loadFieldStats).toHaveBeenCalledTimes(1); act(() => { const closePopover = wrapper.find(EuiPopover).prop('closePopover'); @@ -231,6 +265,8 @@ describe('IndexPattern Field Item', () => { closePopover(); }); + await wrapper.update(); + expect(wrapper.find(EuiPopover).prop('isOpen')).toEqual(false); act(() => { @@ -248,49 +284,59 @@ describe('IndexPattern Field Item', () => { }); }); - clickField(wrapper, 'bytes'); - - expect(core.http.post).toHaveBeenCalledTimes(2); - expect(core.http.post).toHaveBeenLastCalledWith(`/api/lens/index_stats/1/field`, { - body: JSON.stringify({ - dslQuery: { - bool: { - must: [], - filter: [ - { - bool: { - should: [{ match_phrase: { 'geo.src': 'US' } }], - minimum_should_match: 1, - }, + await clickField(wrapper, 'bytes'); + + await wrapper.update(); + + expect(loadFieldStats).toHaveBeenCalledTimes(2); + expect(loadFieldStats).toHaveBeenLastCalledWith({ + abortController: new AbortController(), + services: { data: mockedServices.data }, + dataView, + dslQuery: { + bool: { + must: [], + filter: [ + { + bool: { + should: [{ match_phrase: { 'geo.src': 'US' } }], + minimum_should_match: 1, }, - { - match: { phrase: { 'geo.dest': 'US' } }, - }, - ], - should: [], - must_not: [], - }, + }, + { + match: { phrase: { 'geo.dest': 'US' } }, + }, + ], + should: [], + must_not: [], }, - fromDate: 'now-14d', - toDate: 'now-7d', - fieldName: 'bytes', - }), + }, + fromDate: 'now-14d', + toDate: 'now-7d', + field: defaultProps.field, }); + + (loadFieldStats as jest.Mock).mockReset(); + (loadFieldStats as jest.Mock).mockImplementation(() => Promise.resolve({})); }); it('should not request field stats for document field', async () => { - const wrapper = mountWithIntl(); + const wrapper = mountWithIntl( + + ); - clickField(wrapper, DOCUMENT_FIELD_NAME); + await clickField(wrapper, DOCUMENT_FIELD_NAME); - expect(core.http.post).not.toHaveBeenCalled(); + await wrapper.update(); + + expect(loadFieldStats).not.toHaveBeenCalled(); expect(wrapper.find(EuiPopover).prop('isOpen')).toEqual(true); expect(wrapper.find(EuiLoadingSpinner)).toHaveLength(0); }); it('should not request field stats for range fields', async () => { const wrapper = mountWithIntl( - { /> ); - await act(async () => { - clickField(wrapper, 'ip_range'); - }); + await clickField(wrapper, 'ip_range'); - expect(core.http.post).not.toHaveBeenCalled(); + expect(loadFieldStats).not.toHaveBeenCalled(); }); }); diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/field_item.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/field_item.tsx index 1ec3c3b41ca40c..427b8e46233539 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/field_item.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/field_item.tsx @@ -8,49 +8,38 @@ import './field_item.scss'; import React, { useCallback, useState, useMemo } from 'react'; -import DateMath from '@kbn/datemath'; import { - EuiButtonGroup, EuiButtonIcon, EuiFlexGroup, EuiFlexItem, EuiIconTip, - EuiLoadingSpinner, EuiPopover, - EuiPopoverFooter, EuiPopoverTitle, - EuiProgress, + EuiPopoverFooter, EuiSpacer, EuiText, EuiTitle, EuiToolTip, } from '@elastic/eui'; -import { - Axis, - HistogramBarSeries, - Chart, - niceTimeFormatter, - Position, - ScaleType, - Settings, - TooltipType, -} from '@elastic/charts'; import { i18n } from '@kbn/i18n'; +import { useKibana } from '@kbn/kibana-react-plugin/public'; import { FieldButton } from '@kbn/react-field'; import type { FieldFormatsStart } from '@kbn/field-formats-plugin/public'; import { EuiHighlight } from '@elastic/eui'; -import { Filter, buildEsQuery, Query } from '@kbn/es-query'; -import { KBN_FIELD_TYPES, ES_FIELD_TYPES, getEsQueryConfig } from '@kbn/data-plugin/public'; +import { Filter, Query } from '@kbn/es-query'; +import { DataViewField } from '@kbn/data-views-plugin/common'; import { ChartsPluginSetup } from '@kbn/charts-plugin/public'; import { UiActionsStart } from '@kbn/ui-actions-plugin/public'; +import { FieldStats } from '@kbn/unified-field-list-plugin/public'; import { DragDrop, DragDropIdentifier } from '../drag_drop'; -import type { DatasourceDataPanelProps, DataType, IndexPattern, IndexPatternField } from '../types'; -import { BucketedAggregation, DOCUMENT_FIELD_NAME, FieldStatsResponse } from '../../common'; -import { DraggedField } from './types'; +import { DatasourceDataPanelProps, DataType } from '../types'; +import { DOCUMENT_FIELD_NAME } from '../../common'; +import type { IndexPattern, IndexPatternField } from '../types'; +import type { DraggedField } from './types'; import { LensFieldIcon } from '../shared_components/field_picker/lens_field_icon'; import { VisualizeGeoFieldButton } from './visualize_geo_field_button'; import { getVisualizeGeoFieldMessage } from '../utils'; - +import type { LensAppServices } from '../app_plugin/types'; import { debouncedComponent } from '../debounced_component'; export interface FieldItemProps { @@ -74,15 +63,6 @@ export interface FieldItemProps { uiActions: UiActionsStart; } -interface State { - isLoading: boolean; - totalDocuments?: number; - sampledDocuments?: number; - sampledValues?: number; - histogram?: BucketedAggregation; - topValues?: BucketedAggregation; -} - function wrapOnDot(str?: string) { // u200B is a non-width white-space character, which allows // the browser to efficiently word-wrap right after the dot @@ -92,14 +72,10 @@ function wrapOnDot(str?: string) { export const InnerFieldItem = function InnerFieldItem(props: FieldItemProps) { const { - core, field, indexPattern, highlight, exists, - query, - dateRange, - filters, hideDetails, itemIndex, groupIndex, @@ -140,54 +116,8 @@ export const InnerFieldItem = function InnerFieldItem(props: FieldItemProps) { [dropOntoWorkspace, setOpen] ); - const [state, setState] = useState({ - isLoading: false, - }); - - function fetchData() { - // Range types don't have any useful stats we can show - if ( - state.isLoading || - field.type === 'document' || - field.type.includes('range') || - field.type === 'geo_point' || - field.type === 'geo_shape' - ) { - return; - } - - setState((s) => ({ ...s, isLoading: true })); - - core.http - .post>(`/api/lens/index_stats/${indexPattern.id}/field`, { - body: JSON.stringify({ - dslQuery: buildEsQuery(indexPattern, query, filters, getEsQueryConfig(core.uiSettings)), - fromDate: dateRange.fromDate, - toDate: dateRange.toDate, - fieldName: field.name, - }), - }) - .then((results) => { - setState((s) => ({ - ...s, - isLoading: false, - totalDocuments: results.totalDocuments, - sampledDocuments: results.sampledDocuments, - sampledValues: results.sampledValues, - histogram: results.histogram, - topValues: results.topValues, - })); - }) - .catch(() => { - setState((s) => ({ ...s, isLoading: false })); - }); - } - function togglePopover() { setOpen(!infoIsOpen); - if (!infoIsOpen) { - fetchData(); - } } const onDragStart = useCallback(() => { @@ -281,13 +211,14 @@ export const InnerFieldItem = function InnerFieldItem(props: FieldItemProps) { panelClassName="lnsFieldItem__fieldPanel" initialFocus=".lnsFieldItem__fieldPanel" > - + {infoIsOpen && ( + + )} ); @@ -373,45 +304,22 @@ function FieldPanelHeader({ ); } -function FieldItemPopoverContents(props: State & FieldItemProps) { +function FieldItemPopoverContents(props: FieldItemProps) { const { - histogram, - topValues, + query, + filters, indexPattern, field, dateRange, - core, - sampledValues, - chartsThemeService, - fieldFormats, dropOntoWorkspace, editField, removeField, hasSuggestionForField, hideDetails, uiActions, + core, } = props; - - const chartTheme = chartsThemeService.useChartsTheme(); - const chartBaseTheme = chartsThemeService.useChartsBaseTheme(); - let histogramDefault = !!props.histogram; - - const totalValuesCount = - topValues && topValues.buckets.reduce((prev, bucket) => bucket.count + prev, 0); - const otherCount = sampledValues && totalValuesCount ? sampledValues - totalValuesCount : 0; - - if ( - totalValuesCount && - histogram && - histogram.buckets.length && - topValues && - topValues.buckets.length - ) { - // Default to histogram when top values are less than 10% of total - histogramDefault = otherCount / totalValuesCount > 0.9; - } - - const [showingHistogram, setShowingHistogram] = useState(histogramDefault); + const services = useKibana().services; const panelHeader = ( string }; - if (indexPattern.fieldFormatMap && indexPattern.fieldFormatMap[field.name]) { - const FormatType = fieldFormats.getType(indexPattern.fieldFormatMap[field.name].id as string); - if (FormatType) { - formatter = new FormatType( - indexPattern.fieldFormatMap[field.name].params, - core.uiSettings.get.bind(core.uiSettings) - ); - } else { - formatter = { convert: (data: unknown) => JSON.stringify(data) }; - } - } else { - formatter = fieldFormats.getDefaultInstance( - field.type as KBN_FIELD_TYPES, - field.esTypes as ES_FIELD_TYPES[] - ); - } - - const fromDate = DateMath.parse(dateRange.fromDate); - const toDate = DateMath.parse(dateRange.toDate); - - let title = <>; - - if (props.isLoading) { - return ( - <> - {panelHeader} - - - ); - } else if (field.type.includes('range')) { - return ( - <> - {panelHeader} - - - {i18n.translate('xpack.lens.indexPattern.fieldStatsLimited', { - defaultMessage: `Summary information is not available for range type fields.`, - })} - - - ); - } else if (field.type === 'murmur3') { - return ( - <> - {panelHeader} - - - {i18n.translate('xpack.lens.indexPattern.fieldStatsMurmur3Limited', { - defaultMessage: `Summary information is not available for murmur3 fields.`, - })} - - - ); - } else if (field.type === 'geo_point' || field.type === 'geo_shape') { - return ( - <> - {panelHeader} - - {getVisualizeGeoFieldMessage(field.type)} - - - - - ); - } else if ( - (!props.histogram || props.histogram.buckets.length === 0) && - (!props.topValues || props.topValues.buckets.length === 0) - ) { - const isUsingSampling = core.uiSettings.get('lens:useFieldExistenceSampling'); - return ( - <> - {panelHeader} + return ( + <> + {panelHeader} + {element}} + overrideMissingContent={(params) => { + if (field.type === 'geo_point' || field.type === 'geo_shape') { + return ( + <> + {getVisualizeGeoFieldMessage(field.type)} + + + + + ); + } - - {isUsingSampling - ? i18n.translate('xpack.lens.indexPattern.fieldStatsSamplingNoData', { - defaultMessage: - 'Lens is unable to create visualizations with this field because it does not contain data in the first 500 documents that match your filters. To create a visualization, drag and drop a different field.', - }) - : i18n.translate('xpack.lens.indexPattern.fieldStatsNoData', { - defaultMessage: - 'Lens is unable to create visualizations with this field because it does not contain data. To create a visualization, drag and drop a different field.', - })} - - - ); - } + if (params?.noDataFound) { + const isUsingSampling = core.uiSettings.get('lens:useFieldExistenceSampling'); + return ( + <> + + {isUsingSampling + ? i18n.translate('xpack.lens.indexPattern.fieldStatsSamplingNoData', { + defaultMessage: + 'Lens is unable to create visualizations with this field because it does not contain data in the first 500 documents that match your filters. To create a visualization, drag and drop a different field.', + }) + : i18n.translate('xpack.lens.indexPattern.fieldStatsNoData', { + defaultMessage: + 'Lens is unable to create visualizations with this field because it does not contain data. To create a visualization, drag and drop a different field.', + })} + + + ); + } - if (histogram && histogram.buckets.length && topValues && topValues.buckets.length) { - title = ( - { - setShowingHistogram(optionId === 'histogram'); + return null; }} - idSelected={showingHistogram ? 'histogram' : 'topValues'} /> - ); - } else if (field.type === 'date') { - title = ( - -
- {i18n.translate('xpack.lens.indexPattern.fieldTimeDistributionLabel', { - defaultMessage: 'Time distribution', - })} -
-
- ); - } else if (topValues && topValues.buckets.length) { - title = ( - -
- {i18n.translate('xpack.lens.indexPattern.fieldTopValuesLabel', { - defaultMessage: 'Top values', - })} -
-
- ); - } - - function wrapInPopover(el: React.ReactElement) { - return ( - <> - {panelHeader} - - {title ? title : <>} - - - - {el} - - {props.totalDocuments ? ( - - - {props.sampledDocuments && ( - <> - {i18n.translate('xpack.lens.indexPattern.percentageOfLabel', { - defaultMessage: '{percentage}% of', - values: { - percentage: Math.round((props.sampledDocuments / props.totalDocuments) * 100), - }, - })} - - )}{' '} - - {fieldFormats - .getDefaultInstance(KBN_FIELD_TYPES.NUMBER, [ES_FIELD_TYPES.INTEGER]) - .convert(props.totalDocuments)} - {' '} - {i18n.translate('xpack.lens.indexPattern.ofDocumentsLabel', { - defaultMessage: 'documents', - })} - - - ) : ( - <> - )} - - ); - } - - if (histogram && histogram.buckets.length) { - const specId = i18n.translate('xpack.lens.indexPattern.fieldStatsCountLabel', { - defaultMessage: 'Count', - }); - - if (field.type === 'date') { - return wrapInPopover( - - - - - - - - ); - } else if (showingHistogram || !topValues || !topValues.buckets.length) { - return wrapInPopover( - - - - formatter.convert(d)} - /> - - - - ); - } - } - - if (props.topValues && props.topValues.buckets.length) { - const digitsRequired = props.topValues.buckets.some( - (topValue) => !Number.isInteger(topValue.count / props.sampledValues!) - ); - return wrapInPopover( -
- {props.topValues.buckets.map((topValue) => { - const formatted = formatter.convert(topValue.key); - return ( -
- - - {formatted === '' ? ( - - - {i18n.translate('xpack.lens.indexPattern.fieldPanelEmptyStringValue', { - defaultMessage: 'Empty string', - })} - - - ) : ( - - - {formatted} - - - )} - - - - {(Math.round((topValue.count / props.sampledValues!) * 1000) / 10).toFixed( - digitsRequired ? 1 : 0 - )} - % - - - - - -
- ); - })} - {otherCount ? ( - <> - - - - {i18n.translate('xpack.lens.indexPattern.otherDocsLabel', { - defaultMessage: 'Other', - })} - - - - - - {(Math.round((otherCount / props.sampledValues!) * 1000) / 10).toFixed( - digitsRequired ? 1 : 0 - )} - % - - - - - - - ) : ( - <> - )} -
- ); - } - return <>; + + ); } const DragToWorkspaceButton = ({ diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern.tsx index a2ab9fd2382150..74f006a0c3174d 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern.tsx @@ -248,17 +248,27 @@ export function getIndexPatternDatasource({ render( - + + + , domElement @@ -586,7 +596,14 @@ export function getIndexPatternDatasource({ .filter(([_, layer]) => !!indexPatterns[layer.indexPatternId]) .map(([layerId, layer]) => ( - getErrorMessages(layer, indexPatterns[layer.indexPatternId], state, layerId, core) ?? [] + getErrorMessages( + layer, + indexPatterns[layer.indexPatternId], + state, + layerId, + core, + data + ) ?? [] ).map((message) => ({ shortMessage: '', // Not displayed currently longMessage: typeof message === 'string' ? message : message.message, diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.test.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.test.tsx index 90f59f5470e377..e90ed2c781d5a2 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.test.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.test.tsx @@ -1504,7 +1504,8 @@ describe('IndexPattern Data Source suggestions', () => { const context = [ { indexPatternId: '1', - timeFieldName: 'timestamp', + xFieldName: 'timestamp', + xMode: 'date_histogram', chartType: 'area', axisPosition: 'left', palette: { diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.ts b/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.ts index 319c309cac0363..382df0c9b53dd8 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.ts @@ -178,10 +178,8 @@ function getEmptyLayersSuggestionsForVisualizeCharts( if (!indexPattern) return []; const newId = generateId(); - let newLayer: IndexPatternLayer | undefined; - if (indexPattern.timeFieldName) { - newLayer = createNewTimeseriesLayerWithMetricAggregationFromVizEditor(indexPattern, layer); - } + const newLayer: IndexPatternLayer | undefined = + createNewLayerWithMetricAggregationFromVizEditor(indexPattern, layer); if (newLayer) { const suggestion = buildSuggestion({ state, @@ -197,13 +195,13 @@ function getEmptyLayersSuggestionsForVisualizeCharts( return suggestions; } -function createNewTimeseriesLayerWithMetricAggregationFromVizEditor( +function createNewLayerWithMetricAggregationFromVizEditor( indexPattern: IndexPattern, layer: VisualizeEditorLayersContext ): IndexPatternLayer | undefined { - const { timeFieldName, splitMode, splitFilters, metrics, timeInterval, dropPartialBuckets } = + const { splitMode, splitFilters, metrics, timeInterval, dropPartialBuckets, xMode, xFieldName } = layer; - const dateField = indexPattern.getFieldByName(timeFieldName!); + const xField = xFieldName ? indexPattern.getFieldByName(xFieldName) : undefined; const splitFields = layer.splitFields ? (layer.splitFields @@ -213,10 +211,10 @@ function createNewTimeseriesLayerWithMetricAggregationFromVizEditor( // generate the layer for split by terms if (splitMode === 'terms' && splitFields?.length) { - return getSplitByTermsLayer(indexPattern, splitFields, dateField, layer); + return getSplitByTermsLayer(indexPattern, splitFields, xField, xMode, layer); // generate the layer for split by filters } else if (splitMode?.includes('filter') && splitFilters && splitFilters.length) { - return getSplitByFiltersLayer(indexPattern, dateField, layer); + return getSplitByFiltersLayer(indexPattern, xField, xMode, layer); } else { const copyMetricsArray = [...metrics]; const computedLayer = computeLayerFromContext( @@ -231,11 +229,15 @@ function createNewTimeseriesLayerWithMetricAggregationFromVizEditor( return computedLayer; } + if (!xField || !xMode) { + return computedLayer; + } + return insertNewColumn({ - op: 'date_histogram', + op: xMode, layer: computedLayer, columnId: generateId(), - field: dateField, + field: xField, indexPattern, visualizationGroups: [], columnParams: { diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/loader.test.ts b/x-pack/plugins/lens/public/indexpattern_datasource/loader.test.ts index 3a85a317eec0f3..80f6eaecd3a8a7 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/loader.test.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/loader.test.ts @@ -148,7 +148,8 @@ describe('loader', () => { layers: [ { indexPatternId: '1', - timeFieldName: 'timestamp', + xFieldName: 'timestamp', + xMode: 'date_histogram', chartType: 'area', axisPosition: 'left', metrics: [], diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/date_histogram.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/date_histogram.tsx index 50eb6df5723f73..40b2f66b2b93d1 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/date_histogram.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/date_histogram.tsx @@ -457,7 +457,7 @@ export const dateHistogramOperation: OperationDefinition< ); }, helpComponentTitle: i18n.translate('xpack.lens.indexPattern.dateHistogram.titleHelp', { - defaultMessage: 'How auto date histogram works', + defaultMessage: 'How Date histogram works', }), helpComponent() { const infiniteBound = i18n.translate('xpack.lens.indexPattern.dateHistogram.moreThanYear', { @@ -471,14 +471,14 @@ export const dateHistogramOperation: OperationDefinition< <>

{i18n.translate('xpack.lens.indexPattern.dateHistogram.autoBasicExplanation', { - defaultMessage: 'The auto date histogram splits a data field into buckets by interval.', + defaultMessage: 'Date histogram splits data into time intervals.', })}

{UI_SETTINGS.HISTOGRAM_MAX_BARS}, targetBarSetting: {UI_SETTINGS.HISTOGRAM_BAR_TARGET}, diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/filters/filter_popover.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/filters/filter_popover.tsx index c4ab33c36f1f1e..95021dd22900ff 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/filters/filter_popover.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/filters/filter_popover.tsx @@ -32,29 +32,6 @@ export const FilterPopover = ({ }) => { const inputRef = React.useRef(); - // The following code is to prevent an keypress - // from propagating. - // - // TODO - It looks like EUI should be handling this - // (see https://github.com/elastic/eui/commit/ad97583b0d644690379f72c7a20879cfadb16e7a) - const popoverRef = React.useRef(null); - let panelElement: HTMLDivElement; - const panelRefCallback = (element: HTMLDivElement) => { - const listener = (event: KeyboardEvent) => { - if (event.key === 'Escape') { - event.stopPropagation(); - panelElement.removeEventListener('keydown', listener); - popoverRef.current?.closePopover(); - } - }; - - if (element) { - panelElement = element; - panelElement.addEventListener('keydown', listener); - } - }; - // End handling code - const setFilterLabel = (label: string) => setFilter({ ...filter, label }); const setFilterQuery = (input: Query) => setFilter({ ...filter, input }); @@ -70,14 +47,12 @@ export const FilterPopover = ({ return ( triggerClose()} + closePopover={triggerClose} button={button} > triggerClose()} + onSubmit={triggerClose} dataTestSubj="indexPattern-filters-label" /> diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/index.ts b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/index.ts index 9a5abf8b796330..4a4364be1835d6 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/index.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/index.ts @@ -325,6 +325,7 @@ interface BaseOperationDefinitionProps< fixAction?: { label: string; newState: ( + data: DataPublicPluginStart, core: CoreStart, frame: FrameDatasourceAPI, layerId: string @@ -552,6 +553,7 @@ interface FieldBasedOperationDefinition undefined, - }, - http: { - post: jest.fn(() => - Promise.resolve({ - topValues: { - buckets: [ - { - key: 'A', - }, - { - key: 'B', - }, - ], +jest.mock('@kbn/unified-field-list-plugin/public/services/field_stats', () => ({ + loadFieldStats: jest.fn().mockResolvedValue({ + topValues: { + buckets: [ + { + key: 'A', }, - }) - ), - }, -} as unknown as CoreStart; + { + key: 'B', + }, + ], + }, + }), +})); + +const indexPattern = createMockedIndexPattern(); +const dataMock = dataPluginMock.createStartContract(); +const coreMock = corePluginMock.createStart(); function getStringBasedOperationColumn( field = 'source', @@ -214,6 +210,7 @@ describe('getDisallowedTermsMessage()', () => { indexPattern )!.fixAction.newState; const newLayer = await fixAction( + dataMock, coreMock, { query: { language: 'kuery', query: 'a: b' }, @@ -261,6 +258,7 @@ describe('getDisallowedTermsMessage()', () => { indexPattern )!.fixAction.newState; const newLayer = await fixAction( + dataMock, coreMock, { query: { language: 'kuery', query: 'a: b' }, @@ -302,6 +300,7 @@ describe('getDisallowedTermsMessage()', () => { indexPattern )!.fixAction.newState; const newLayer = await fixAction( + dataMock, coreMock, { query: { language: 'kuery', query: 'a: b' }, @@ -342,6 +341,7 @@ describe('getDisallowedTermsMessage()', () => { indexPattern )!.fixAction.newState; const newLayer = await fixAction( + dataMock, coreMock, { query: { language: 'kuery', query: 'a: b' }, diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms/helpers.ts b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms/helpers.ts index a290c2d239a1e2..6dec5e3aef6cf4 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms/helpers.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms/helpers.ts @@ -9,12 +9,12 @@ import { i18n } from '@kbn/i18n'; import { uniq } from 'lodash'; import type { CoreStart } from '@kbn/core/public'; import { buildEsQuery } from '@kbn/es-query'; -import { getEsQueryConfig } from '@kbn/data-plugin/public'; +import { getEsQueryConfig, DataPublicPluginStart } from '@kbn/data-plugin/public'; +import { FieldStatsResponse, loadFieldStats } from '@kbn/unified-field-list-plugin/public'; import { GenericIndexPatternColumn, operationDefinitionMap } from '..'; import { defaultLabel } from '../filters'; import { isReferenced } from '../../layer_helpers'; -import type { FieldStatsResponse } from '../../../../../common'; import type { FrameDatasourceAPI, IndexPattern, IndexPatternField } from '../../../../types'; import type { FiltersIndexPatternColumn } from '..'; import type { TermsIndexPatternColumn } from './types'; @@ -109,7 +109,12 @@ export function getDisallowedTermsMessage( label: i18n.translate('xpack.lens.indexPattern.termsWithMultipleShiftsFixActionLabel', { defaultMessage: 'Use filters', }), - newState: async (core: CoreStart, frame: FrameDatasourceAPI, layerId: string) => { + newState: async ( + data: DataPublicPluginStart, + core: CoreStart, + frame: FrameDatasourceAPI, + layerId: string + ) => { const currentColumn = layer.columns[columnId] as TermsIndexPatternColumn; const fieldNames = [ currentColumn.sourceField, @@ -133,23 +138,21 @@ export function getDisallowedTermsMessage( ); if (!activeDataFieldNameMatch || currentTerms.length === 0) { if (fieldNames.length === 1) { - const response: FieldStatsResponse = await core.http.post( - `/api/lens/index_stats/${indexPattern.id}/field`, - { - body: JSON.stringify({ - fieldName: fieldNames[0], - dslQuery: buildEsQuery( - indexPattern, - frame.query, - frame.filters, - getEsQueryConfig(core.uiSettings) - ), - fromDate: frame.dateRange.fromDate, - toDate: frame.dateRange.toDate, - size: currentColumn.params.size, - }), - } - ); + const currentDataView = await data.dataViews.get(indexPattern.id); + const response: FieldStatsResponse = await loadFieldStats({ + services: { data }, + dataView: currentDataView, + field: indexPattern.getFieldByName(fieldNames[0])!, + dslQuery: buildEsQuery( + indexPattern, + frame.query, + frame.filters, + getEsQueryConfig(core.uiSettings) + ), + fromDate: frame.dateRange.fromDate, + toDate: frame.dateRange.toDate, + size: currentColumn.params.size, + }); currentTerms = response.topValues?.buckets.map(({ key }) => String(key)) || []; } } diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms/terms.test.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms/terms.test.tsx index 407abc0203493c..8c3b7f90d57d33 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms/terms.test.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms/terms.test.tsx @@ -9,17 +9,13 @@ import React from 'react'; import { act } from 'react-dom/test-utils'; import { shallow, mount } from 'enzyme'; import { EuiButtonGroup, EuiComboBox, EuiFieldNumber, EuiSelect, EuiSwitch } from '@elastic/eui'; -import type { - IUiSettingsClient, - SavedObjectsClientContract, - HttpSetup, - CoreStart, -} from '@kbn/core/public'; +import type { IUiSettingsClient, SavedObjectsClientContract, HttpSetup } from '@kbn/core/public'; import { fieldFormatsServiceMock } from '@kbn/field-formats-plugin/public/mocks'; import { unifiedSearchPluginMock } from '@kbn/unified-search-plugin/public/mocks'; import type { IStorageWrapper } from '@kbn/kibana-utils-plugin/public'; import { dataPluginMock } from '@kbn/data-plugin/public/mocks'; import { dataViewPluginMocks } from '@kbn/data-views-plugin/public/mocks'; +import { coreMock as corePluginMock } from '@kbn/core/public/mocks'; import { createMockedIndexPattern } from '../../../mocks'; import { ValuesInput } from './values_input'; import type { TermsIndexPatternColumn } from '.'; @@ -39,6 +35,21 @@ import { IndexPattern } from '../../../../types'; import { cloneDeep } from 'lodash'; import { IncludeExcludeRow } from './include_exclude_options'; +jest.mock('@kbn/unified-field-list-plugin/public/services/field_stats', () => ({ + loadFieldStats: jest.fn().mockResolvedValue({ + topValues: { + buckets: [ + { + key: 'A', + }, + { + key: 'B', + }, + ], + }, + }), +})); + // mocking random id generator function jest.mock('@elastic/eui', () => { const original = jest.requireActual('@elastic/eui'); @@ -2772,29 +2783,10 @@ describe('terms', () => { const fixAction = ( typeof errorMessage === 'object' ? errorMessage.fixAction!.newState : undefined )!; - const coreMock = { - uiSettings: { - get: () => undefined, - }, - http: { - post: jest.fn(() => - Promise.resolve({ - topValues: { - buckets: [ - { - key: 'A', - }, - { - key: 'B', - }, - ], - }, - }) - ), - }, - } as unknown as CoreStart; + const dataMock = dataPluginMock.createStartContract(); const newLayer = await fixAction( - coreMock, + dataMock, + corePluginMock.createStart(), { query: { language: 'kuery', query: 'a: b' }, filters: [], diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/layer_helpers.test.ts b/x-pack/plugins/lens/public/indexpattern_datasource/operations/layer_helpers.test.ts index a865a1de16a772..9006cf0f2cc9c9 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/layer_helpers.test.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/layer_helpers.test.ts @@ -39,6 +39,9 @@ import { import { TinymathAST } from '@kbn/tinymath'; import { CoreStart } from '@kbn/core/public'; import { IndexPattern } from '../../types'; +import { dataPluginMock } from '@kbn/data-plugin/public/mocks'; + +const dataMock = dataPluginMock.createStartContract(); jest.mock('.'); jest.mock('../../id_generator'); @@ -3043,7 +3046,8 @@ describe('state_helpers', () => { indexPattern, {}, '1', - {} + {}, + dataMock ); expect(mock).toHaveBeenCalled(); expect(errors).toHaveLength(1); @@ -3069,7 +3073,8 @@ describe('state_helpers', () => { indexPattern, {} as IndexPatternPrivateState, '1', - {} as CoreStart + {} as CoreStart, + dataMock ); expect(mock).toHaveBeenCalled(); expect(errors).toHaveLength(1); @@ -3104,7 +3109,8 @@ describe('state_helpers', () => { indexPattern, {} as IndexPatternPrivateState, '1', - {} as CoreStart + {} as CoreStart, + dataMock ); expect(notCalledMock).not.toHaveBeenCalled(); expect(mock).toHaveBeenCalledTimes(1); @@ -3140,7 +3146,8 @@ describe('state_helpers', () => { indexPattern, {} as IndexPatternPrivateState, '1', - {} as CoreStart + {} as CoreStart, + dataMock ); expect(savedRef).toHaveBeenCalled(); expect(incompleteRef).not.toHaveBeenCalled(); @@ -3169,7 +3176,8 @@ describe('state_helpers', () => { indexPattern, {} as IndexPatternPrivateState, '1', - {} as CoreStart + {} as CoreStart, + dataMock ); expect(mock).toHaveBeenCalledWith( { diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/layer_helpers.ts b/x-pack/plugins/lens/public/indexpattern_datasource/operations/layer_helpers.ts index 3d079584e32f9a..04860408b822e0 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/layer_helpers.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/layer_helpers.ts @@ -9,6 +9,7 @@ import { partition, mapValues, pickBy, isArray } from 'lodash'; import { CoreStart } from '@kbn/core/public'; import type { Query } from '@kbn/es-query'; import memoizeOne from 'memoize-one'; +import type { DataPublicPluginStart } from '@kbn/data-plugin/public'; import type { VisualizeEditorLayersContext } from '@kbn/visualizations-plugin/public'; import type { DatasourceFixAction, @@ -1375,7 +1376,8 @@ export function getErrorMessages( indexPattern: IndexPattern, state: IndexPatternPrivateState, layerId: string, - core: CoreStart + core: CoreStart, + data: DataPublicPluginStart ): | Array< | string @@ -1417,7 +1419,7 @@ export function getErrorMessages( ...state, layers: { ...state.layers, - [layerId]: await errorMessage.fixAction!.newState(core, frame, layerId), + [layerId]: await errorMessage.fixAction!.newState(data, core, frame, layerId), }, }), } @@ -1651,7 +1653,9 @@ export function computeLayerFromContext( FormulaIndexPatternColumn, 'managedReference' >; - const tempLayer = { indexPatternId: indexPattern.id, columns: {}, columnOrder: [] }; + const tempLayer = isLast + ? { indexPatternId: indexPattern.id, columns: {}, columnOrder: [] } + : computeLayerFromContext(metricsArray.length === 1, metricsArray, indexPattern); let newColumn = operationDefinition.buildColumn({ indexPattern, layer: tempLayer, @@ -1740,7 +1744,8 @@ export function computeLayerFromContext( export function getSplitByTermsLayer( indexPattern: IndexPattern, splitFields: IndexPatternField[], - dateField: IndexPatternField | undefined, + xField: IndexPatternField | undefined, + xMode: string | undefined, layer: VisualizeEditorLayersContext ): IndexPatternLayer { const { termsParams, metrics, timeInterval, splitWithDateHistogram, dropPartialBuckets } = layer; @@ -1759,18 +1764,21 @@ export function getSplitByTermsLayer( let termsLayer = insertNewColumn({ op: splitWithDateHistogram ? 'date_histogram' : 'terms', - layer: insertNewColumn({ - op: 'date_histogram', - layer: computedLayer, - columnId: generateId(), - field: dateField, - indexPattern, - visualizationGroups: [], - columnParams: { - interval: timeInterval, - dropPartials: dropPartialBuckets, - }, - }), + layer: + xField && xMode + ? insertNewColumn({ + op: xMode, + layer: computedLayer, + columnId: generateId(), + field: xField, + indexPattern, + visualizationGroups: [], + columnParams: { + interval: timeInterval, + dropPartials: dropPartialBuckets, + }, + }) + : computedLayer, columnId, field: baseField, indexPattern, @@ -1821,7 +1829,8 @@ export function getSplitByTermsLayer( export function getSplitByFiltersLayer( indexPattern: IndexPattern, - dateField: IndexPatternField | undefined, + xField: IndexPatternField | undefined, + xMode: string | undefined, layer: VisualizeEditorLayersContext ): IndexPatternLayer { const { splitFilters, metrics, timeInterval, dropPartialBuckets } = layer; @@ -1847,18 +1856,21 @@ export function getSplitByFiltersLayer( const columnId = generateId(); let filtersLayer = insertNewColumn({ op: 'filters', - layer: insertNewColumn({ - op: 'date_histogram', - layer: computedLayer, - columnId: generateId(), - field: dateField, - indexPattern, - visualizationGroups: [], - columnParams: { - interval: timeInterval, - dropPartials: dropPartialBuckets, - }, - }), + layer: + xField && xMode + ? insertNewColumn({ + op: xMode, + layer: computedLayer, + columnId: generateId(), + field: xField, + indexPattern, + visualizationGroups: [], + columnParams: { + interval: timeInterval, + dropPartials: dropPartialBuckets, + }, + }) + : computedLayer, columnId, field: undefined, indexPattern, diff --git a/x-pack/plugins/lens/public/mocks/services_mock.tsx b/x-pack/plugins/lens/public/mocks/services_mock.tsx index e9d0c7cd14f280..8c323e7e071fa3 100644 --- a/x-pack/plugins/lens/public/mocks/services_mock.tsx +++ b/x-pack/plugins/lens/public/mocks/services_mock.tsx @@ -16,6 +16,7 @@ import { inspectorPluginMock } from '@kbn/inspector-plugin/public/mocks'; import { spacesPluginMock } from '@kbn/spaces-plugin/public/mocks'; import { dashboardPluginMock } from '@kbn/dashboard-plugin/public/mocks'; import { dataViewPluginMocks } from '@kbn/data-views-plugin/public/mocks'; +import { chartPluginMock } from '@kbn/charts-plugin/public/mocks'; import { DataViewsPublicPluginStart } from '@kbn/data-views-plugin/public'; import { @@ -158,6 +159,7 @@ export function makeDefaultServices( clear: jest.fn(), }, spaces: spacesPluginMock.createStartContract(), + charts: chartPluginMock.createSetupContract(), dataViewFieldEditor: indexPatternFieldEditorPluginMock.createStartContract(), dataViewEditor: indexPatternEditorPluginMock.createStartContract(), }; diff --git a/x-pack/plugins/lens/public/shared_components/debounced_input.test.tsx b/x-pack/plugins/lens/public/shared_components/debounced_input.test.tsx new file mode 100644 index 00000000000000..feab19d02c7202 --- /dev/null +++ b/x-pack/plugins/lens/public/shared_components/debounced_input.test.tsx @@ -0,0 +1,76 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { EuiFieldText } from '@elastic/eui'; +import { mount } from 'enzyme'; +import { DebouncedInput } from './debounced_input'; +import { act } from 'react-dom/test-utils'; + +jest.mock('lodash', () => { + const original = jest.requireActual('lodash'); + + return { + ...original, + debounce: (fn: unknown) => fn, + }; +}); + +describe('DebouncedInput', () => { + it('should render', () => { + const mockOnChange = jest.fn(); + const wrapper = mount( + + ); + + const textProps = wrapper.find(EuiFieldText).props(); + expect(textProps.value).toBe('my value'); + expect(textProps.placeholder).toBe('default value'); + + act(() => { + textProps.onChange!({ + target: { value: 'new value' }, + } as unknown as React.ChangeEvent); + }); + expect(mockOnChange).toHaveBeenCalledWith('new value'); + }); + + it('should update placeholder when default value changes', () => { + const wrapper = mount( + {}} defaultValue={'old default'} /> + ); + + expect(wrapper.find(EuiFieldText).props().placeholder).toBe('old default'); + + act(() => { + wrapper.setProps({ defaultValue: 'new default' }); + }); + + expect(wrapper.find(EuiFieldText).props().placeholder).toBe('new default'); + }); + + it('should forward text field props', () => { + const wrapper = mount( + {}} + defaultValue={'old default'} + /> + ); + + expect(wrapper.find(EuiFieldText).props()).toEqual( + expect.objectContaining({ + compressed: true, + fullWidth: true, + readOnly: true, + }) + ); + }); +}); diff --git a/x-pack/plugins/lens/public/shared_components/debounced_input.tsx b/x-pack/plugins/lens/public/shared_components/debounced_input.tsx new file mode 100644 index 00000000000000..cd309a2bb0bfd4 --- /dev/null +++ b/x-pack/plugins/lens/public/shared_components/debounced_input.tsx @@ -0,0 +1,54 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { EuiFieldText, EuiFieldTextProps } from '@elastic/eui'; +import { useDebouncedValue } from './debounced_value'; + +type Props = { + value: string; + onChange: (value: string) => void; + defaultValue?: string; + allowFalsyValue?: boolean; +} & Omit; + +const DebouncedInputHelper = ({ + onChange, + value, + defaultValue, + allowFalsyValue, + ...rest +}: Props) => { + const { inputValue, handleInputChange, initialValue } = useDebouncedValue( + { + onChange, + value, + defaultValue, + }, + { allowFalsyValue } + ); + + return ( + { + handleInputChange(e.target.value); + }} + placeholder={initialValue} + /> + ); +}; + +/** + * When testing this component, mock the "debounce" function in lodash (see this module test for an example) + */ +export const DebouncedInput = (props: Props) => ( + // need this extra layer to force a rerender whenever the default value changes. + // this is because we need a new initialValue to be computed from the debounce hook. + +); diff --git a/x-pack/plugins/lens/public/shared_components/name_input.tsx b/x-pack/plugins/lens/public/shared_components/name_input.tsx index 9502c7df93d55d..e455caa199dd00 100644 --- a/x-pack/plugins/lens/public/shared_components/name_input.tsx +++ b/x-pack/plugins/lens/public/shared_components/name_input.tsx @@ -7,8 +7,8 @@ import React from 'react'; import { i18n } from '@kbn/i18n'; -import { EuiFormRow, EuiFieldText } from '@elastic/eui'; -import { useDebouncedValue } from '.'; +import { EuiFormRow } from '@elastic/eui'; +import { DebouncedInput } from './debounced_input'; export const NameInput = ({ value, @@ -19,12 +19,6 @@ export const NameInput = ({ onChange: (value: string) => void; defaultValue?: string; }) => { - const { inputValue, handleInputChange, initialValue } = useDebouncedValue({ - onChange, - value, - defaultValue, - }); - return ( - { - handleInputChange(e.target.value); - }} - placeholder={initialValue} + value={value} + onChange={onChange} + defaultValue={defaultValue} /> ); diff --git a/x-pack/plugins/lens/public/types.ts b/x-pack/plugins/lens/public/types.ts index 0a76ceec5d3153..97df24648f4d4f 100644 --- a/x-pack/plugins/lens/public/types.ts +++ b/x-pack/plugins/lens/public/types.ts @@ -44,8 +44,9 @@ import { LENS_EDIT_PAGESIZE_ACTION, } from './visualizations/datatable/components/constants'; import type { LensInspector } from './lens_inspector_service'; -import { DataViewsState } from './state_management/types'; -import { IndexPatternServiceAPI } from './indexpattern_service/service'; +import type { FormatSelectorOptions } from './indexpattern_datasource/dimension_panel/format_selector'; +import type { DataViewsState } from './state_management/types'; +import type { IndexPatternServiceAPI } from './indexpattern_service/service'; export interface IndexPatternRef { id: string; @@ -228,6 +229,9 @@ interface ChartSettings { fill?: string; legend?: Record; gridLinesVisibility?: Record; + tickLabelsVisibility?: Record; + axisTitlesVisibility?: Record; + valueLabels?: boolean; extents?: { yLeftExtent: AxisExtents; yRightExtent: AxisExtents; @@ -538,7 +542,8 @@ export type DatasourceDimensionEditorProps = DatasourceDimensionPro layerType: LayerType | undefined; supportStaticValue: boolean; paramEditorCustomProps?: ParamEditorCustomProps; - supportFieldFormat?: boolean; + enableFormatSelector: boolean; + formatSelectorOptions: FormatSelectorOptions | undefined; }; export type DatasourceDimensionTriggerProps = DatasourceDimensionProps; @@ -698,7 +703,8 @@ export type VisualizationDimensionGroupConfig = SharedDimensionProps & { requiresPreviousColumnOnDuplicate?: boolean; supportStaticValue?: boolean; paramEditorCustomProps?: ParamEditorCustomProps; - supportFieldFormat?: boolean; + enableFormatSelector?: boolean; + formatSelectorOptions?: FormatSelectorOptions; // only relevant if supportFieldFormat is true labels?: { buttonAriaLabel: string; buttonLabel: string }; }; diff --git a/x-pack/plugins/lens/public/visualizations/datatable/components/columns.tsx b/x-pack/plugins/lens/public/visualizations/datatable/components/columns.tsx index 81b73b8f267b73..c4583d131dc1cc 100644 --- a/x-pack/plugins/lens/public/visualizations/datatable/components/columns.tsx +++ b/x-pack/plugins/lens/public/visualizations/datatable/components/columns.tsx @@ -63,7 +63,8 @@ export const createGridColumns = ( rowIndex, columnId, }: Pick) => { - const rowValue = table.rows[rowIndex][columnId]; + // incoming data might change and put the current page out of bounds - check whether row actually exists + const rowValue = table.rows[rowIndex]?.[columnId]; const column = columnsReverseLookup?.[columnId]; const contentsIsDefined = rowValue != null; diff --git a/x-pack/plugins/lens/public/visualizations/datatable/components/table_basic.test.tsx b/x-pack/plugins/lens/public/visualizations/datatable/components/table_basic.test.tsx index c1986b9ff7ef59..7ab05fc5ce24f2 100644 --- a/x-pack/plugins/lens/public/visualizations/datatable/components/table_basic.test.tsx +++ b/x-pack/plugins/lens/public/visualizations/datatable/components/table_basic.test.tsx @@ -739,7 +739,9 @@ describe('DatatableComponent', () => { it('enables pagination', async () => { const { data, args } = sampleArgs(); - args.pageSize = 10; + data.rows = new Array(10).fill({ a: 'shoes', b: 1588024800000, c: 3 }); + + args.pageSize = 2; const wrapper = mount( { expect(updatedConfig?.pageSize).toBe(args.pageSize); }); + it('resets page position if rows change so page will be empty', async () => { + const { data, args } = sampleArgs(); + + data.rows = new Array(10).fill({ a: 'shoes', b: 1588024800000, c: 3 }); + + args.pageSize = 2; + + const wrapper = mount( + x as unknown as IFieldFormat} + dispatchEvent={onDispatchEvent} + getType={jest.fn()} + paletteService={chartPluginMock.createPaletteRegistry()} + uiSettings={{ get: jest.fn() } as unknown as IUiSettingsClient} + renderMode="edit" + interactive + renderComplete={renderComplete} + /> + ); + const newIndex = 3; + act(() => wrapper.find(EuiDataGrid).prop('pagination')?.onChangePage(newIndex)); + wrapper.update(); + + expect(wrapper.find(EuiDataGrid).prop('pagination')?.pageIndex).toBe(newIndex); + + wrapper.setProps({ + data: { + ...data, + rows: new Array(20).fill({ a: 'shoes', b: 1588024800000, c: 3 }), + }, + }); + + await waitForWrapperUpdate(wrapper); + + // keeps existing page if more data is added + expect(wrapper.find(EuiDataGrid).prop('pagination')?.pageIndex).toBe(newIndex); + + wrapper.setProps({ + data: { + ...data, + rows: new Array(3).fill({ a: 'shoes', b: 1588024800000, c: 3 }), + }, + }); + + await waitForWrapperUpdate(wrapper); + // resets to the last page if the current page becomes out of bounds + expect(wrapper.find(EuiDataGrid).prop('pagination')?.pageIndex).toBe(1); + }); + it('disables pagination by default', async () => { const { data, args } = sampleArgs(); diff --git a/x-pack/plugins/lens/public/visualizations/datatable/components/table_basic.tsx b/x-pack/plugins/lens/public/visualizations/datatable/components/table_basic.tsx index fe0a7da701f2a1..275eca93d6cbb5 100644 --- a/x-pack/plugins/lens/public/visualizations/datatable/components/table_basic.tsx +++ b/x-pack/plugins/lens/public/visualizations/datatable/components/table_basic.tsx @@ -114,6 +114,25 @@ export const DatatableComponent = (props: DatatableRenderProps) => { const firstTableRef = useRef(firstLocalTable); firstTableRef.current = firstLocalTable; + useEffect(() => { + if (!pagination?.pageIndex && !pagination?.pageSize) return; + const lastPageIndex = Math.ceil(firstLocalTable.rows.length / pagination.pageSize) - 1; + /** + * When the underlying data changes, there might be a case when actual pagination page + * doesn't exist anymore - if the number of rows has decreased. + * Set the last page as an actual. + */ + setPagination((pag) => { + if (!pag) { + return pag; + } + return { + pageIndex: pag.pageIndex > lastPageIndex ? lastPageIndex : pag.pageIndex, + pageSize: pag.pageSize, + }; + }); + }, [pagination?.pageIndex, pagination?.pageSize, firstLocalTable.rows.length]); + const untransposedDataRef = useRef(props.untransposedData); untransposedDataRef.current = props.untransposedData; diff --git a/x-pack/plugins/lens/public/visualizations/gauge/visualization.test.ts b/x-pack/plugins/lens/public/visualizations/gauge/visualization.test.ts index 7282259108a926..94c9ce28987bfb 100644 --- a/x-pack/plugins/lens/public/visualizations/gauge/visualization.test.ts +++ b/x-pack/plugins/lens/public/visualizations/gauge/visualization.test.ts @@ -108,7 +108,7 @@ describe('gauge', () => { required: true, dataTestSubj: 'lnsGauge_metricDimensionPanel', enableDimensionEditor: true, - supportFieldFormat: true, + enableFormatSelector: true, }, { layerId: 'first', @@ -124,7 +124,7 @@ describe('gauge', () => { dataTestSubj: 'lnsGauge_minDimensionPanel', prioritizedOperation: 'min', suggestedValue: expect.any(Function), - supportFieldFormat: false, + enableFormatSelector: false, supportStaticValue: true, }, { @@ -141,7 +141,7 @@ describe('gauge', () => { dataTestSubj: 'lnsGauge_maxDimensionPanel', prioritizedOperation: 'max', suggestedValue: expect.any(Function), - supportFieldFormat: false, + enableFormatSelector: false, supportStaticValue: true, }, { @@ -157,7 +157,7 @@ describe('gauge', () => { supportsMoreColumns: false, required: false, dataTestSubj: 'lnsGauge_goalDimensionPanel', - supportFieldFormat: false, + enableFormatSelector: false, supportStaticValue: true, }, ], @@ -190,7 +190,7 @@ describe('gauge', () => { required: true, dataTestSubj: 'lnsGauge_metricDimensionPanel', enableDimensionEditor: true, - supportFieldFormat: true, + enableFormatSelector: true, }, { layerId: 'first', @@ -206,7 +206,7 @@ describe('gauge', () => { dataTestSubj: 'lnsGauge_minDimensionPanel', prioritizedOperation: 'min', suggestedValue: expect.any(Function), - supportFieldFormat: false, + enableFormatSelector: false, supportStaticValue: true, }, { @@ -223,7 +223,7 @@ describe('gauge', () => { dataTestSubj: 'lnsGauge_maxDimensionPanel', prioritizedOperation: 'max', suggestedValue: expect.any(Function), - supportFieldFormat: false, + enableFormatSelector: false, supportStaticValue: true, }, { @@ -239,7 +239,7 @@ describe('gauge', () => { supportsMoreColumns: true, required: false, dataTestSubj: 'lnsGauge_goalDimensionPanel', - supportFieldFormat: false, + enableFormatSelector: false, supportStaticValue: true, }, ], @@ -278,7 +278,7 @@ describe('gauge', () => { required: true, dataTestSubj: 'lnsGauge_metricDimensionPanel', enableDimensionEditor: true, - supportFieldFormat: true, + enableFormatSelector: true, }, { layerId: 'first', @@ -294,7 +294,7 @@ describe('gauge', () => { dataTestSubj: 'lnsGauge_minDimensionPanel', prioritizedOperation: 'min', suggestedValue: expect.any(Function), - supportFieldFormat: false, + enableFormatSelector: false, supportStaticValue: true, }, { @@ -311,7 +311,7 @@ describe('gauge', () => { dataTestSubj: 'lnsGauge_maxDimensionPanel', prioritizedOperation: 'max', suggestedValue: expect.any(Function), - supportFieldFormat: false, + enableFormatSelector: false, supportStaticValue: true, }, { @@ -327,7 +327,7 @@ describe('gauge', () => { supportsMoreColumns: false, required: false, dataTestSubj: 'lnsGauge_goalDimensionPanel', - supportFieldFormat: false, + enableFormatSelector: false, supportStaticValue: true, }, ], @@ -371,7 +371,7 @@ describe('gauge', () => { required: true, dataTestSubj: 'lnsGauge_metricDimensionPanel', enableDimensionEditor: true, - supportFieldFormat: true, + enableFormatSelector: true, }, { layerId: 'first', @@ -387,7 +387,7 @@ describe('gauge', () => { dataTestSubj: 'lnsGauge_minDimensionPanel', prioritizedOperation: 'min', suggestedValue: expect.any(Function), - supportFieldFormat: false, + enableFormatSelector: false, supportStaticValue: true, invalid: true, invalidMessage: 'Minimum value may not be greater than maximum value', @@ -406,7 +406,7 @@ describe('gauge', () => { dataTestSubj: 'lnsGauge_maxDimensionPanel', prioritizedOperation: 'max', suggestedValue: expect.any(Function), - supportFieldFormat: false, + enableFormatSelector: false, supportStaticValue: true, invalid: true, invalidMessage: 'Minimum value may not be greater than maximum value', @@ -424,7 +424,7 @@ describe('gauge', () => { supportsMoreColumns: false, required: false, dataTestSubj: 'lnsGauge_goalDimensionPanel', - supportFieldFormat: false, + enableFormatSelector: false, supportStaticValue: true, }, ], diff --git a/x-pack/plugins/lens/public/visualizations/gauge/visualization.tsx b/x-pack/plugins/lens/public/visualizations/gauge/visualization.tsx index 8c35a442429557..37d10918d4129c 100644 --- a/x-pack/plugins/lens/public/visualizations/gauge/visualization.tsx +++ b/x-pack/plugins/lens/public/visualizations/gauge/visualization.tsx @@ -248,7 +248,7 @@ export const getGaugeVisualization = ({ return { groups: [ { - supportFieldFormat: true, + enableFormatSelector: true, layerId: state.layerId, groupId: GROUP_ID.METRIC, groupLabel: i18n.translate('xpack.lens.gauge.metricLabel', { @@ -281,7 +281,7 @@ export const getGaugeVisualization = ({ }, { supportStaticValue: true, - supportFieldFormat: false, + enableFormatSelector: false, layerId: state.layerId, groupId: GROUP_ID.MIN, groupLabel: i18n.translate('xpack.lens.gauge.minValueLabel', { @@ -307,7 +307,7 @@ export const getGaugeVisualization = ({ }, { supportStaticValue: true, - supportFieldFormat: false, + enableFormatSelector: false, layerId: state.layerId, groupId: GROUP_ID.MAX, groupLabel: i18n.translate('xpack.lens.gauge.maxValueLabel', { @@ -333,7 +333,7 @@ export const getGaugeVisualization = ({ }, { supportStaticValue: true, - supportFieldFormat: false, + enableFormatSelector: false, layerId: state.layerId, groupId: GROUP_ID.GOAL, groupLabel: i18n.translate('xpack.lens.gauge.goalValueLabel', { diff --git a/x-pack/plugins/lens/public/visualizations/legacy_metric/dimension_editor.test.tsx b/x-pack/plugins/lens/public/visualizations/legacy_metric/dimension_editor.test.tsx index bdc9fd200f6b49..560e4ed67b5474 100644 --- a/x-pack/plugins/lens/public/visualizations/legacy_metric/dimension_editor.test.tsx +++ b/x-pack/plugins/lens/public/visualizations/legacy_metric/dimension_editor.test.tsx @@ -23,7 +23,7 @@ import { act } from 'react-dom/test-utils'; import { PalettePanelContainer } from '../../shared_components'; import { layerTypes } from '../../../common'; -import type { MetricState } from '../../../common/types'; +import type { LegacyMetricState } from '../../../common/types'; // mocking random id generator function jest.mock('@elastic/eui', () => { @@ -48,13 +48,13 @@ function paletteParamsContaining(paramsToCheck: PaletteOutput { let frame: FramePublicAPI; - let state: MetricState; - let setState: (newState: MetricState) => void; - let props: VisualizationDimensionEditorProps & { + let state: LegacyMetricState; + let setState: (newState: LegacyMetricState) => void; + let props: VisualizationDimensionEditorProps & { paletteService: PaletteRegistry; }; - function testState(): MetricState { + function testState(): LegacyMetricState { return { layerId: 'first', layerType: layerTypes.DATA, diff --git a/x-pack/plugins/lens/public/visualizations/legacy_metric/dimension_editor.tsx b/x-pack/plugins/lens/public/visualizations/legacy_metric/dimension_editor.tsx index 9dd478712d5d99..bb62ea57bef550 100644 --- a/x-pack/plugins/lens/public/visualizations/legacy_metric/dimension_editor.tsx +++ b/x-pack/plugins/lens/public/visualizations/legacy_metric/dimension_editor.tsx @@ -22,7 +22,7 @@ import { import { i18n } from '@kbn/i18n'; import React, { useCallback, useState } from 'react'; import { ColorMode } from '@kbn/charts-plugin/common'; -import type { MetricState } from '../../../common/types'; +import type { LegacyMetricState } from '../../../common/types'; import { isNumericFieldForDatatable } from '../../../common/expressions'; import { applyPaletteParams, PalettePanelContainer } from '../../shared_components'; import type { VisualizationDimensionEditorProps } from '../../types'; @@ -33,7 +33,7 @@ import './dimension_editor.scss'; const idPrefix = htmlIdGenerator()(); export function MetricDimensionEditor( - props: VisualizationDimensionEditorProps & { + props: VisualizationDimensionEditorProps & { paletteService: PaletteRegistry; } ) { @@ -117,7 +117,7 @@ export function MetricDimensionEditor( idSelected={`${idPrefix}${currentColorMode}`} onChange={(id) => { const newMode = id.replace(idPrefix, '') as ColorMode; - const params: Partial = { + const params: Partial = { colorMode: newMode, }; if (!state?.palette && newMode !== ColorMode.None) { @@ -190,6 +190,7 @@ export function MetricDimensionEditor( palettes={props.paletteService} activePalette={activePalette} dataBounds={currentMinMax} + displayInfinity={true} setPalette={(newPalette) => { // if the new palette is not custom, replace the rangeMin with the artificial one if ( diff --git a/x-pack/plugins/lens/public/visualizations/legacy_metric/metric_config_panel/align_options.tsx b/x-pack/plugins/lens/public/visualizations/legacy_metric/metric_config_panel/align_options.tsx index 0da058db3d5b5c..3ba5d3bc024a70 100644 --- a/x-pack/plugins/lens/public/visualizations/legacy_metric/metric_config_panel/align_options.tsx +++ b/x-pack/plugins/lens/public/visualizations/legacy_metric/metric_config_panel/align_options.tsx @@ -8,11 +8,11 @@ import React from 'react'; import { i18n } from '@kbn/i18n'; import { EuiButtonGroup } from '@elastic/eui'; -import { MetricState } from '../../../../common/types'; +import { LegacyMetricState } from '../../../../common/types'; export interface TitlePositionProps { - state: MetricState; - setState: (newState: MetricState) => void; + state: LegacyMetricState; + setState: (newState: LegacyMetricState) => void; } export const DEFAULT_TEXT_ALIGNMENT = 'left'; @@ -50,7 +50,7 @@ export const AlignOptions: React.FC = ({ state, setState }) options={alignButtonIcons} idSelected={state.textAlign ?? DEFAULT_TEXT_ALIGNMENT} onChange={(id) => { - setState({ ...state, textAlign: id as MetricState['textAlign'] }); + setState({ ...state, textAlign: id as LegacyMetricState['textAlign'] }); }} isIconOnly buttonSize="compressed" diff --git a/x-pack/plugins/lens/public/visualizations/legacy_metric/metric_config_panel/appearance_options_popover.tsx b/x-pack/plugins/lens/public/visualizations/legacy_metric/metric_config_panel/appearance_options_popover.tsx index cbde82a193c35a..b5ce24e030d573 100644 --- a/x-pack/plugins/lens/public/visualizations/legacy_metric/metric_config_panel/appearance_options_popover.tsx +++ b/x-pack/plugins/lens/public/visualizations/legacy_metric/metric_config_panel/appearance_options_popover.tsx @@ -10,12 +10,12 @@ import { i18n } from '@kbn/i18n'; import { ToolbarPopover, TooltipWrapper } from '../../../shared_components'; import { TitlePositionOptions } from './title_position_option'; import { FramePublicAPI } from '../../../types'; -import type { MetricState } from '../../../../common/types'; +import type { LegacyMetricState } from '../../../../common/types'; import { TextFormattingOptions } from './text_formatting_options'; export interface VisualOptionsPopoverProps { - state: MetricState; - setState: (newState: MetricState) => void; + state: LegacyMetricState; + setState: (newState: LegacyMetricState) => void; datasourceLayers: FramePublicAPI['datasourceLayers']; } diff --git a/x-pack/plugins/lens/public/visualizations/legacy_metric/metric_config_panel/index.tsx b/x-pack/plugins/lens/public/visualizations/legacy_metric/metric_config_panel/index.tsx index 0988aefa244929..4397f47acdcec4 100644 --- a/x-pack/plugins/lens/public/visualizations/legacy_metric/metric_config_panel/index.tsx +++ b/x-pack/plugins/lens/public/visualizations/legacy_metric/metric_config_panel/index.tsx @@ -8,12 +8,12 @@ import React, { memo } from 'react'; import { EuiFlexGroup, EuiFlexItem, htmlIdGenerator } from '@elastic/eui'; import type { VisualizationToolbarProps } from '../../../types'; -import type { MetricState } from '../../../../common/types'; +import type { LegacyMetricState } from '../../../../common/types'; import { AppearanceOptionsPopover } from './appearance_options_popover'; export const MetricToolbar = memo(function MetricToolbar( - props: VisualizationToolbarProps + props: VisualizationToolbarProps ) { const { state, setState, frame } = props; diff --git a/x-pack/plugins/lens/public/visualizations/legacy_metric/metric_config_panel/size_options.tsx b/x-pack/plugins/lens/public/visualizations/legacy_metric/metric_config_panel/size_options.tsx index 40eba671c56a37..bb2427d3287255 100644 --- a/x-pack/plugins/lens/public/visualizations/legacy_metric/metric_config_panel/size_options.tsx +++ b/x-pack/plugins/lens/public/visualizations/legacy_metric/metric_config_panel/size_options.tsx @@ -8,11 +8,11 @@ import React from 'react'; import { i18n } from '@kbn/i18n'; import { EuiButtonIcon, EuiSuperSelect } from '@elastic/eui'; -import type { MetricState } from '../../../../common/types'; +import type { LegacyMetricState } from '../../../../common/types'; export interface TitlePositionProps { - state: MetricState; - setState: (newState: MetricState) => void; + state: LegacyMetricState; + setState: (newState: LegacyMetricState) => void; } export const DEFAULT_TITLE_SIZE = 'm'; diff --git a/x-pack/plugins/lens/public/visualizations/legacy_metric/metric_config_panel/text_formatting_options.tsx b/x-pack/plugins/lens/public/visualizations/legacy_metric/metric_config_panel/text_formatting_options.tsx index 8a1f97cd8251ee..e425e94216fe5e 100644 --- a/x-pack/plugins/lens/public/visualizations/legacy_metric/metric_config_panel/text_formatting_options.tsx +++ b/x-pack/plugins/lens/public/visualizations/legacy_metric/metric_config_panel/text_formatting_options.tsx @@ -8,13 +8,13 @@ import React from 'react'; import { i18n } from '@kbn/i18n'; import { EuiFormRow, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; -import type { MetricState } from '../../../../common/types'; +import type { LegacyMetricState } from '../../../../common/types'; import { SizeOptions } from './size_options'; import { AlignOptions } from './align_options'; export interface TitlePositionProps { - state: MetricState; - setState: (newState: MetricState) => void; + state: LegacyMetricState; + setState: (newState: LegacyMetricState) => void; } export const TextFormattingOptions: React.FC = ({ state, setState }) => { diff --git a/x-pack/plugins/lens/public/visualizations/legacy_metric/metric_config_panel/title_position_option.tsx b/x-pack/plugins/lens/public/visualizations/legacy_metric/metric_config_panel/title_position_option.tsx index 233a2e382669f7..ef406c21217487 100644 --- a/x-pack/plugins/lens/public/visualizations/legacy_metric/metric_config_panel/title_position_option.tsx +++ b/x-pack/plugins/lens/public/visualizations/legacy_metric/metric_config_panel/title_position_option.tsx @@ -8,11 +8,11 @@ import React from 'react'; import { i18n } from '@kbn/i18n'; import { EuiButtonGroup, EuiFormRow } from '@elastic/eui'; -import type { MetricState } from '../../../../common/types'; +import type { LegacyMetricState } from '../../../../common/types'; export interface TitlePositionProps { - state: MetricState; - setState: (newState: MetricState) => void; + state: LegacyMetricState; + setState: (newState: LegacyMetricState) => void; } export const DEFAULT_TITLE_POSITION = 'top'; @@ -52,7 +52,7 @@ export const TitlePositionOptions: React.FC = ({ state, setS options={titlePositions} idSelected={state.titlePosition ?? DEFAULT_TITLE_POSITION} onChange={(value) => { - setState({ ...state, titlePosition: value as MetricState['titlePosition'] }); + setState({ ...state, titlePosition: value as LegacyMetricState['titlePosition'] }); }} buttonSize="compressed" /> diff --git a/x-pack/plugins/lens/public/visualizations/legacy_metric/metric_suggestions.ts b/x-pack/plugins/lens/public/visualizations/legacy_metric/metric_suggestions.ts index 6fa35a8a17821b..16f4d4890f474d 100644 --- a/x-pack/plugins/lens/public/visualizations/legacy_metric/metric_suggestions.ts +++ b/x-pack/plugins/lens/public/visualizations/legacy_metric/metric_suggestions.ts @@ -7,7 +7,7 @@ import { IconChartMetric } from '@kbn/chart-icons'; import { SuggestionRequest, VisualizationSuggestion, TableSuggestion } from '../../types'; -import type { MetricState } from '../../../common/types'; +import type { LegacyMetricState } from '../../../common/types'; import { layerTypes } from '../../../common'; import { legacyMetricSupportedTypes } from './visualization'; @@ -20,7 +20,7 @@ export function getSuggestions({ table, state, keptLayerIds, -}: SuggestionRequest): Array> { +}: SuggestionRequest): Array> { // We only render metric charts for single-row queries. We require a single, numeric column. if ( table.isMultiRow || @@ -42,7 +42,7 @@ export function getSuggestions({ return [getSuggestion(table)]; } -function getSuggestion(table: TableSuggestion): VisualizationSuggestion { +function getSuggestion(table: TableSuggestion): VisualizationSuggestion { const col = table.columns[0]; const title = table.label || col.operation.label; diff --git a/x-pack/plugins/lens/public/visualizations/legacy_metric/visualization.test.ts b/x-pack/plugins/lens/public/visualizations/legacy_metric/visualization.test.ts index 399c29797ff831..fb8493fc4d0f52 100644 --- a/x-pack/plugins/lens/public/visualizations/legacy_metric/visualization.test.ts +++ b/x-pack/plugins/lens/public/visualizations/legacy_metric/visualization.test.ts @@ -6,7 +6,7 @@ */ import { getLegacyMetricVisualization } from './visualization'; -import type { MetricState } from '../../../common/types'; +import type { LegacyMetricState } from '../../../common/types'; import { layerTypes } from '../../../common'; import { createMockDatasource, createMockFramePublicAPI } from '../../mocks'; import { generateId } from '../../id_generator'; @@ -17,7 +17,7 @@ import { themeServiceMock } from '@kbn/core/public/mocks'; jest.mock('../../id_generator'); -function exampleState(): MetricState { +function exampleState(): LegacyMetricState { return { accessor: 'a', layerId: 'l1', diff --git a/x-pack/plugins/lens/public/visualizations/legacy_metric/visualization.tsx b/x-pack/plugins/lens/public/visualizations/legacy_metric/visualization.tsx index 361dc066bebf64..20bd48fb9dd959 100644 --- a/x-pack/plugins/lens/public/visualizations/legacy_metric/visualization.tsx +++ b/x-pack/plugins/lens/public/visualizations/legacy_metric/visualization.tsx @@ -17,7 +17,7 @@ import { VIS_EVENT_TO_TRIGGER } from '@kbn/visualizations-plugin/public'; import { IconChartMetric } from '@kbn/chart-icons'; import { getSuggestions } from './metric_suggestions'; import { Visualization, OperationMetadata, DatasourceLayers } from '../../types'; -import type { MetricState } from '../../../common/types'; +import type { LegacyMetricState } from '../../../common/types'; import { layerTypes } from '../../../common'; import { MetricDimensionEditor } from './dimension_editor'; import { MetricToolbar } from './metric_config_panel'; @@ -25,7 +25,7 @@ import { DEFAULT_TITLE_POSITION } from './metric_config_panel/title_position_opt import { DEFAULT_TITLE_SIZE } from './metric_config_panel/size_options'; import { DEFAULT_TEXT_ALIGNMENT } from './metric_config_panel/align_options'; -interface MetricConfig extends Omit { +interface MetricConfig extends Omit { title: string; description: string; metricTitle: string; @@ -46,9 +46,9 @@ const getFontSizeAndUnit = (fontSize: string) => { const toExpression = ( paletteService: PaletteRegistry, - state: MetricState, + state: LegacyMetricState, datasourceLayers: DatasourceLayers, - attributes?: Partial>, + attributes?: Partial>, datasourceExpressionsByLayers: Record | undefined = {} ): Ast | null => { if (!state.accessor) { @@ -175,12 +175,12 @@ export const getLegacyMetricVisualization = ({ }: { paletteService: PaletteRegistry; theme: ThemeServiceStart; -}): Visualization => ({ - id: 'lnsMetric', +}): Visualization => ({ + id: 'lnsLegacyMetric', visualizationTypes: [ { - id: 'lnsMetric', + id: 'lnsLegacyMetric', icon: IconChartMetric, label: i18n.translate('xpack.lens.legacyMetric.label', { defaultMessage: 'Legacy Metric', @@ -192,7 +192,7 @@ export const getLegacyMetricVisualization = ({ ], getVisualizationTypeId() { - return 'lnsMetric'; + return 'lnsLegacyMetric'; }, clearLayer(state) { @@ -240,8 +240,8 @@ export const getLegacyMetricVisualization = ({ defaultMessage: 'Value', }), }, - groupLabel: i18n.translate('xpack.lens.legacyMetric.label', { - defaultMessage: 'Legacy Metric', + groupLabel: i18n.translate('xpack.lens.metric.label', { + defaultMessage: 'Metric', }), layerId: props.state.layerId, accessors: props.state.accessor diff --git a/x-pack/plugins/lens/public/visualizations/metric/__snapshots__/visualization.test.ts.snap b/x-pack/plugins/lens/public/visualizations/metric/__snapshots__/visualization.test.ts.snap index c6fced0eba5e4b..239baf2244da87 100644 --- a/x-pack/plugins/lens/public/visualizations/metric/__snapshots__/visualization.test.ts.snap +++ b/x-pack/plugins/lens/public/visualizations/metric/__snapshots__/visualization.test.ts.snap @@ -13,7 +13,11 @@ Object { ], "dataTestSubj": "lnsMetric_primaryMetricDimensionPanel", "enableDimensionEditor": true, + "enableFormatSelector": true, "filterOperations": [Function], + "formatSelectorOptions": Object { + "disableExtraOptions": true, + }, "groupId": "metric", "groupLabel": "Primary metric", "layerId": "first", @@ -21,7 +25,6 @@ Object { "headingLabel": "Value", }, "required": true, - "supportFieldFormat": false, "supportsMoreColumns": false, }, Object { @@ -32,7 +35,11 @@ Object { ], "dataTestSubj": "lnsMetric_secondaryMetricDimensionPanel", "enableDimensionEditor": true, + "enableFormatSelector": true, "filterOperations": [Function], + "formatSelectorOptions": Object { + "disableExtraOptions": true, + }, "groupId": "secondaryMetric", "groupLabel": "Secondary metric", "layerId": "first", @@ -40,7 +47,6 @@ Object { "headingLabel": "Value", }, "required": false, - "supportFieldFormat": false, "supportsMoreColumns": false, }, Object { @@ -51,7 +57,11 @@ Object { ], "dataTestSubj": "lnsMetric_maxDimensionPanel", "enableDimensionEditor": true, + "enableFormatSelector": false, "filterOperations": [Function], + "formatSelectorOptions": Object { + "disableExtraOptions": true, + }, "groupId": "max", "groupLabel": "Maximum value", "groupTooltip": "If the maximum value is specified, the minimum value is fixed at zero.", @@ -60,7 +70,6 @@ Object { "headingLabel": "Value", }, "required": false, - "supportFieldFormat": false, "supportStaticValue": true, "supportsMoreColumns": false, }, @@ -73,12 +82,15 @@ Object { ], "dataTestSubj": "lnsMetric_breakdownByDimensionPanel", "enableDimensionEditor": true, + "enableFormatSelector": true, "filterOperations": [Function], + "formatSelectorOptions": Object { + "disableExtraOptions": true, + }, "groupId": "breakdownBy", "groupLabel": "Break down by", "layerId": "first", "required": false, - "supportFieldFormat": false, "supportsMoreColumns": false, }, ], diff --git a/x-pack/plugins/lens/public/visualizations/metric/constants.ts b/x-pack/plugins/lens/public/visualizations/metric/constants.ts index 4a3830f10ec910..58a35d89146ed3 100644 --- a/x-pack/plugins/lens/public/visualizations/metric/constants.ts +++ b/x-pack/plugins/lens/public/visualizations/metric/constants.ts @@ -5,7 +5,7 @@ * 2.0. */ -export const LENS_METRIC_ID = 'lnsMetricNew'; // TODO - rename old one to "legacy" +export const LENS_METRIC_ID = 'lnsMetric'; export const GROUP_ID = { METRIC: 'metric', diff --git a/x-pack/plugins/lens/public/visualizations/metric/dimension_editor.test.tsx b/x-pack/plugins/lens/public/visualizations/metric/dimension_editor.test.tsx index ba43fae0d71dd5..fb7c505600e9ad 100644 --- a/x-pack/plugins/lens/public/visualizations/metric/dimension_editor.test.tsx +++ b/x-pack/plugins/lens/public/visualizations/metric/dimension_editor.test.tsx @@ -7,15 +7,15 @@ /* eslint-disable max-classes-per-file */ -import React, { ChangeEvent, FormEvent } from 'react'; +import React, { FormEvent } from 'react'; import { VisualizationDimensionEditorProps } from '../../types'; import { CustomPaletteParams, PaletteOutput, PaletteRegistry } from '@kbn/coloring'; import { MetricVisualizationState } from './visualization'; import { DimensionEditor } from './dimension_editor'; -import { HTMLAttributes, ReactWrapper, shallow } from 'enzyme'; +import { HTMLAttributes, mount, ReactWrapper, shallow } from 'enzyme'; import { CollapseSetting } from '../../shared_components/collapse_setting'; -import { EuiButtonGroup, EuiColorPicker, EuiFieldText } from '@elastic/eui'; +import { EuiButtonGroup, EuiColorPicker } from '@elastic/eui'; import { mountWithIntl } from '@kbn/test-jest-helpers'; import { LayoutDirection } from '@elastic/charts'; import { act } from 'react-dom/test-utils'; @@ -23,6 +23,7 @@ import { EuiColorPickerOutput } from '@elastic/eui/src/components/color_picker/c import { createMockFramePublicAPI } from '../../mocks'; import { chartPluginMock } from '@kbn/charts-plugin/public/mocks'; import { euiLightVars } from '@kbn/ui-theme'; +import { DebouncedInput } from '../../shared_components/debounced_input'; jest.mock('lodash', () => { const original = jest.requireActual('lodash'); @@ -64,39 +65,43 @@ describe('dimension editor', () => { palette, }; - const mockedFrame = createMockFramePublicAPI(); - - const props: VisualizationDimensionEditorProps & { + let props: VisualizationDimensionEditorProps & { paletteService: PaletteRegistry; - } = { - layerId: 'first', - groupId: 'some-group', - accessor: 'some-accessor', - state: fullState, - frame: mockedFrame, - setState: jest.fn(), - panelRef: {} as React.MutableRefObject, - paletteService: chartPluginMock.createPaletteRegistry(), }; + beforeEach(() => { + props = { + layerId: 'first', + groupId: 'some-group', + accessor: 'some-accessor', + state: fullState, + frame: createMockFramePublicAPI(), + setState: jest.fn(), + panelRef: {} as React.MutableRefObject, + paletteService: chartPluginMock.createPaletteRegistry(), + }; + }); + describe('primary metric dimension', () => { const accessor = 'primary-metric-col-id'; - props.frame.activeData = { - first: { - type: 'datatable', - columns: [ - { - id: accessor, - name: 'foo', - meta: { - type: 'number', + beforeEach(() => { + props.frame.activeData = { + first: { + type: 'datatable', + columns: [ + { + id: accessor, + name: 'foo', + meta: { + type: 'number', + }, }, - }, - ], - rows: [], - }, - }; + ], + rows: [], + }, + }; + }); class Harness { public _wrapper; @@ -200,6 +205,24 @@ describe('dimension editor', () => { describe('secondary metric dimension', () => { const accessor = 'secondary-metric-col-id'; + beforeEach(() => { + props.frame.activeData = { + first: { + type: 'datatable', + columns: [ + { + id: accessor, + name: 'foo', + meta: { + type: 'number', + }, + }, + ], + rows: [], + }, + }; + }); + it('renders when the accessor matches', () => { const component = shallow( { expect(component.exists(SELECTORS.PRIMARY_METRIC_EDITOR)).toBeFalsy(); }); - it('sets metric prefix', () => { - const setState = jest.fn(); - const localState = { ...fullState, secondaryMetricAccessor: accessor }; - const component = shallow( - - ); + describe('metric prefix', () => { + const NONE_PREFIX = ''; + const AUTO_PREFIX = undefined; + + it('activates the correct buttons', () => { + const setState = jest.fn(); + const localState = { + ...fullState, + secondaryPrefix: AUTO_PREFIX, + secondaryMetricAccessor: accessor, + }; + const component = mount( + + ); + + expect(component.find(EuiButtonGroup).props().idSelected).toContain('auto'); + + component.setProps({ + state: { + ...localState, + secondaryPrefix: NONE_PREFIX, + }, + }); - const newVal = 'Metric explanation'; - component.find(EuiFieldText).props().onChange!({ - target: { value: newVal }, - } as ChangeEvent); - expect(setState).toHaveBeenCalledWith({ ...localState, secondaryPrefix: newVal }); + expect(component.find(EuiButtonGroup).props().idSelected).toContain('none'); + + component.setProps({ + state: { + ...localState, + secondaryPrefix: 'some custom prefix', + }, + }); + + expect(component.find(EuiButtonGroup).props().idSelected).toContain('custom'); + }); + + it('clicking a button sets the prefix value', () => { + const setState = jest.fn(); + const localState = { + ...fullState, + secondaryPrefix: AUTO_PREFIX, + secondaryMetricAccessor: accessor, + }; + const component = mount( + + ); + + const newVal = 'Metric explanation'; + + component.find(EuiButtonGroup).props().onChange('some-id', newVal); + + expect(setState).toHaveBeenCalledWith({ ...localState, secondaryPrefix: newVal }); + }); + + it('sets a custom prefix value', () => { + const setState = jest.fn(); + const localState = { + ...fullState, + secondaryPrefix: 'foo', + secondaryMetricAccessor: accessor, + }; + const component = mount( + + ); + + const buttonGroup = component.find(EuiButtonGroup); + + // make sure that if the user was to select the "custom" option, they would get the default value + expect(buttonGroup.props().options[1].value).toBe('foo'); + + const newVal = 'bar'; + + component.find(DebouncedInput).props().onChange(newVal); + + expect(setState).toHaveBeenCalledWith({ ...localState, secondaryPrefix: newVal }); + }); }); }); diff --git a/x-pack/plugins/lens/public/visualizations/metric/dimension_editor.tsx b/x-pack/plugins/lens/public/visualizations/metric/dimension_editor.tsx index 198f3dd755ebc8..de285da29b1e3a 100644 --- a/x-pack/plugins/lens/public/visualizations/metric/dimension_editor.tsx +++ b/x-pack/plugins/lens/public/visualizations/metric/dimension_editor.tsx @@ -11,12 +11,12 @@ import { EuiColorPaletteDisplay, EuiFormRow, EuiFlexItem, - EuiFieldText, EuiButtonGroup, EuiFieldNumber, htmlIdGenerator, EuiColorPicker, euiPaletteColorBlind, + EuiSpacer, } from '@elastic/eui'; import { LayoutDirection } from '@elastic/charts'; import React, { useCallback, useState } from 'react'; @@ -30,6 +30,7 @@ import { } from '@kbn/coloring'; import { getDataBoundsForPalette } from '@kbn/expression-metric-vis-plugin/public'; import { css } from '@emotion/react'; +import { getColumnByAccessor } from '@kbn/visualizations-plugin/common/utils'; import { isNumericFieldForDatatable } from '../../../common/expressions'; import { applyPaletteParams, @@ -40,63 +41,42 @@ import type { VisualizationDimensionEditorProps } from '../../types'; import { defaultNumberPaletteParams, defaultPercentagePaletteParams } from './palette_config'; import { DEFAULT_MAX_COLUMNS, getDefaultColor, MetricVisualizationState } from './visualization'; import { CollapseSetting } from '../../shared_components/collapse_setting'; +import { DebouncedInput } from '../../shared_components/debounced_input'; type Props = VisualizationDimensionEditorProps & { paletteService: PaletteRegistry; }; -export function DimensionEditor(props: Props) { - const { state, setState, accessor } = props; +type SubProps = Props & { idPrefix: string }; - const setPrefix = useCallback( - (prefix: string) => setState({ ...state, secondaryPrefix: prefix }), - [setState, state] - ); +export function DimensionEditor(props: Props) { + const { state, accessor } = props; - const { inputValue: prefixInputVal, handleInputChange: handlePrefixChange } = - useDebouncedValue( - { - onChange: setPrefix, - value: state.secondaryPrefix || '', - }, - { allowFalsyValue: true } - ); + const idPrefix = htmlIdGenerator()(); switch (accessor) { case state?.metricAccessor: return (

- +
); case state.secondaryMetricAccessor: return (
- - handlePrefixChange(value)} - /> - +
); case state.maxAccessor: return ( -
- +
+
); case state.breakdownByAccessor: return (
- +
); default: @@ -104,7 +84,7 @@ export function DimensionEditor(props: Props) { } } -function BreakdownByEditor({ setState, state }: Props) { +function BreakdownByEditor({ setState, state }: SubProps) { const setMaxCols = useCallback( (columns: string) => { setState({ ...state, maxCols: parseInt(columns, 10) }); @@ -148,8 +128,7 @@ function BreakdownByEditor({ setState, state }: Props) { ); } -function MaximumEditor({ setState, state }: Props) { - const idPrefix = htmlIdGenerator()(); +function MaximumEditor({ setState, state, idPrefix }: SubProps) { return ( + + <> + { + setState({ + ...state, + secondaryPrefix, + }); + }} + /> + + {state.secondaryPrefix && ( + { + setState({ + ...state, + secondaryPrefix: newPrefix, + }); + }} + /> + )} + + +
+ ); +} + +function PrimaryMetricEditor(props: SubProps) { + const { state, setState, frame, accessor, idPrefix } = props; const [isPaletteOpen, setIsPaletteOpen] = useState(false); @@ -235,7 +294,6 @@ function PrimaryMetricEditor(props: Props) { const togglePalette = () => setIsPaletteOpen(!isPaletteOpen); - const idPrefix = htmlIdGenerator()(); return ( <> { it('clears a layer', () => { expect(visualization.clearLayer(fullState, 'some-id')).toMatchInlineSnapshot(` Object { - "color": "static-color", "layerId": "first", "layerType": "data", - "maxCols": 5, - "progressDirection": "vertical", - "subtitle": "subtitle", } `); }); @@ -634,6 +630,7 @@ describe('metric visualization', () => { expect(removed).not.toHaveProperty('metricAccessor'); expect(removed).not.toHaveProperty('palette'); + expect(removed).not.toHaveProperty('color'); }); it('removes secondary metric dimension', () => { const removed = visualization.removeDimension({ @@ -651,6 +648,7 @@ describe('metric visualization', () => { }); expect(removed).not.toHaveProperty('maxAccessor'); + expect(removed).not.toHaveProperty('progressDirection'); }); it('removes breakdown-by dimension', () => { const removed = visualization.removeDimension({ @@ -660,6 +658,7 @@ describe('metric visualization', () => { expect(removed).not.toHaveProperty('breakdownByAccessor'); expect(removed).not.toHaveProperty('collapseFn'); + expect(removed).not.toHaveProperty('maxCols'); }); }); diff --git a/x-pack/plugins/lens/public/visualizations/metric/visualization.tsx b/x-pack/plugins/lens/public/visualizations/metric/visualization.tsx index 596d2596dd5d8c..6d74b02bae1208 100644 --- a/x-pack/plugins/lens/public/visualizations/metric/visualization.tsx +++ b/x-pack/plugins/lens/public/visualizations/metric/visualization.tsx @@ -25,6 +25,7 @@ import { GROUP_ID, LENS_METRIC_ID } from './constants'; import { DimensionEditor } from './dimension_editor'; import { Toolbar } from './toolbar'; import { generateId } from '../../id_generator'; +import { FormatSelectorOptions } from '../../indexpattern_datasource/dimension_panel/format_selector'; export const DEFAULT_MAX_COLUMNS = 3; @@ -125,7 +126,8 @@ const toExpression = ( arguments: { metric: state.metricAccessor ? [state.metricAccessor] : [], secondaryMetric: state.secondaryMetricAccessor ? [state.secondaryMetricAccessor] : [], - secondaryPrefix: state.secondaryPrefix ? [state.secondaryPrefix] : [], + secondaryPrefix: + typeof state.secondaryPrefix !== 'undefined' ? [state.secondaryPrefix] : [], max: state.maxAccessor ? [state.maxAccessor] : [], breakdownBy: state.breakdownByAccessor && !state.collapseFn ? [state.breakdownByAccessor] : [], @@ -154,6 +156,28 @@ const metricGroupLabel = i18n.translate('xpack.lens.metric.groupLabel', { defaultMessage: 'Goal and single value', }); +const removeMetricDimension = (state: MetricVisualizationState) => { + delete state.metricAccessor; + delete state.palette; + delete state.color; +}; + +const removeSecondaryMetricDimension = (state: MetricVisualizationState) => { + delete state.secondaryMetricAccessor; + delete state.secondaryPrefix; +}; + +const removeMaxDimension = (state: MetricVisualizationState) => { + delete state.maxAccessor; + delete state.progressDirection; +}; + +const removeBreakdownByDimension = (state: MetricVisualizationState) => { + delete state.breakdownByAccessor; + delete state.collapseFn; + delete state.maxCols; +}; + export const getMetricVisualization = ({ paletteService, theme, @@ -180,14 +204,13 @@ export const getMetricVisualization = ({ clearLayer(state) { const newState = { ...state }; - delete newState.metricAccessor; - delete newState.secondaryMetricAccessor; - delete newState.secondaryPrefix; - delete newState.breakdownByAccessor; - delete newState.collapseFn; - delete newState.maxAccessor; - delete newState.palette; - // TODO - clear more? + delete newState.subtitle; + + removeMetricDimension(newState); + removeSecondaryMetricDimension(newState); + removeMaxDimension(newState); + removeBreakdownByDimension(newState); + return newState; }, @@ -244,6 +267,10 @@ export const getMetricVisualization = ({ const isBucketed = (op: OperationMetadata) => op.isBucketed; + const formatterOptions: FormatSelectorOptions = { + disableExtraOptions: true, + }; + return { groups: [ { @@ -269,7 +296,8 @@ export const getMetricVisualization = ({ supportsMoreColumns: !props.state.metricAccessor, filterOperations: isSupportedDynamicMetric, enableDimensionEditor: true, - supportFieldFormat: false, + enableFormatSelector: true, + formatSelectorOptions: formatterOptions, required: true, }, { @@ -294,7 +322,8 @@ export const getMetricVisualization = ({ supportsMoreColumns: !props.state.secondaryMetricAccessor, filterOperations: isSupportedDynamicMetric, enableDimensionEditor: true, - supportFieldFormat: false, + enableFormatSelector: true, + formatSelectorOptions: formatterOptions, required: false, }, { @@ -317,7 +346,8 @@ export const getMetricVisualization = ({ supportsMoreColumns: !props.state.maxAccessor, filterOperations: isSupportedMetric, enableDimensionEditor: true, - supportFieldFormat: false, + enableFormatSelector: false, + formatSelectorOptions: formatterOptions, supportStaticValue: true, required: false, groupTooltip: i18n.translate('xpack.lens.metric.maxTooltip', { @@ -343,7 +373,8 @@ export const getMetricVisualization = ({ supportsMoreColumns: !props.state.breakdownByAccessor, filterOperations: isBucketed, enableDimensionEditor: true, - supportFieldFormat: false, + enableFormatSelector: true, + formatSelectorOptions: formatterOptions, required: false, }, ], @@ -404,20 +435,16 @@ export const getMetricVisualization = ({ const updated = { ...prevState }; if (prevState.metricAccessor === columnId) { - delete updated.metricAccessor; - delete updated.palette; - delete updated.color; + removeMetricDimension(updated); } if (prevState.secondaryMetricAccessor === columnId) { - delete updated.secondaryMetricAccessor; - delete updated.secondaryPrefix; + removeSecondaryMetricDimension(updated); } if (prevState.maxAccessor === columnId) { - delete updated.maxAccessor; + removeMaxDimension(updated); } if (prevState.breakdownByAccessor === columnId) { - delete updated.breakdownByAccessor; - delete updated.collapseFn; + removeBreakdownByDimension(updated); } return updated; diff --git a/x-pack/plugins/lens/public/visualizations/xy/visualization.test.ts b/x-pack/plugins/lens/public/visualizations/xy/visualization.test.ts index 68170468647834..ad26ea92762bf7 100644 --- a/x-pack/plugins/lens/public/visualizations/xy/visualization.test.ts +++ b/x-pack/plugins/lens/public/visualizations/xy/visualization.test.ts @@ -971,7 +971,8 @@ describe('xy_visualization', () => { layers: [ { indexPatternId: 'ff959d40-b880-11e8-a6d9-e546fe2bba5f', - timeFieldName: 'order_date', + xFieldName: 'order_date', + xMode: 'date_histogram', chartType: 'area', axisPosition: 'left', palette: { diff --git a/x-pack/plugins/lens/public/visualizations/xy/visualization.tsx b/x-pack/plugins/lens/public/visualizations/xy/visualization.tsx index e0d0a19cebec87..24710c3261cdbe 100644 --- a/x-pack/plugins/lens/public/visualizations/xy/visualization.tsx +++ b/x-pack/plugins/lens/public/visualizations/xy/visualization.tsx @@ -452,7 +452,10 @@ export const getXyVisualization = ({ yLeftExtent: context.configuration.extents?.yLeftExtent, legend: context.configuration.legend, gridlinesVisibilitySettings: context.configuration.gridLinesVisibility, + tickLabelsVisibilitySettings: context.configuration.tickLabelsVisibility, + axisTitlesVisibilitySettings: context.configuration.axisTitlesVisibility, valuesInLegend: true, + valueLabels: context.configuration.valueLabels ? 'show' : 'hide', layers: visualizationStateLayers, }, }; diff --git a/x-pack/plugins/lens/server/embeddable/make_lens_embeddable_factory.ts b/x-pack/plugins/lens/server/embeddable/make_lens_embeddable_factory.ts index dc3933d852979c..98b5f5d8d186d0 100644 --- a/x-pack/plugins/lens/server/embeddable/make_lens_embeddable_factory.ts +++ b/x-pack/plugins/lens/server/embeddable/make_lens_embeddable_factory.ts @@ -27,15 +27,18 @@ import { commonUpdateVisLayerType, getLensCustomVisualizationMigrations, getLensFilterMigrations, + commonMigrateMetricIds, } from '../migrations/common_migrations'; import { CustomVisualizationMigrations, LensDocShape713, LensDocShape715, LensDocShape810, + LensDocShape840, LensDocShapePre712, VisState716, VisState810, + VisState840, VisStatePre715, VisStatePre830, } from '../migrations/types'; @@ -124,6 +127,14 @@ export const makeLensEmbeddableFactory = attributes: migratedLensState, } as unknown as SerializableRecord; }, + '8.5.0': (state) => { + const lensState = state as unknown as { attributes: LensDocShape840 }; + const migratedLensState = commonMigrateMetricIds(lensState.attributes); + return { + ...lensState, + attributes: migratedLensState, + } as unknown as SerializableRecord; + }, }), getLensCustomVisualizationMigrations(customVisualizationMigrations) ), diff --git a/x-pack/plugins/lens/server/migrations/common_migrations.ts b/x-pack/plugins/lens/server/migrations/common_migrations.ts index 10fc9b25e6f349..2681a7f2abe2e4 100644 --- a/x-pack/plugins/lens/server/migrations/common_migrations.ts +++ b/x-pack/plugins/lens/server/migrations/common_migrations.ts @@ -30,8 +30,9 @@ import { LensDocShape810, LensDocShape830, VisStatePre830, + LensDocShape840, } from './types'; -import { DOCUMENT_FIELD_NAME, layerTypes, MetricState } from '../../common'; +import { DOCUMENT_FIELD_NAME, layerTypes, LegacyMetricState } from '../../common'; import { LensDocShape } from './saved_object_migrations'; export const commonRenameOperationsForFormula = ( @@ -248,7 +249,7 @@ export const commonLockOldMetricVisSettings = ( return newAttributes as LensDocShape830; } - const visState = newAttributes.state.visualization as MetricState; + const visState = newAttributes.state.visualization as LegacyMetricState; visState.textAlign = visState.textAlign ?? 'center'; visState.titlePosition = visState.titlePosition ?? 'bottom'; visState.size = visState.size ?? 'xl'; @@ -398,3 +399,21 @@ export const commonFixValueLabelsInXY = ( }, }; }; + +export const commonMigrateMetricIds = ( + attributes: LensDocShape840 +): LensDocShape840 => { + const typeMappings = { + lnsMetric: 'lnsLegacyMetric', + lnsMetricNew: 'lnsMetric', + } as Record; + + if (!attributes.visualizationType || !(attributes.visualizationType in typeMappings)) { + return attributes as LensDocShape840; + } + + const newAttributes = cloneDeep(attributes); + newAttributes.visualizationType = typeMappings[attributes.visualizationType]; + + return newAttributes; +}; diff --git a/x-pack/plugins/lens/server/migrations/saved_object_migrations.test.ts b/x-pack/plugins/lens/server/migrations/saved_object_migrations.test.ts index 53765ed69cdac3..e5754ee048b86b 100644 --- a/x-pack/plugins/lens/server/migrations/saved_object_migrations.test.ts +++ b/x-pack/plugins/lens/server/migrations/saved_object_migrations.test.ts @@ -23,7 +23,7 @@ import { VisState820, VisState830, } from './types'; -import { layerTypes, MetricState } from '../../common'; +import { layerTypes, LegacyMetricState } from '../../common'; import { Filter } from '@kbn/es-query'; describe('Lens migrations', () => { @@ -2086,7 +2086,7 @@ describe('Lens migrations', () => { const result = migrations['8.3.0'](example, context) as ReturnType< SavedObjectMigrationFn >; - const visState = result.attributes.state.visualization as MetricState; + const visState = result.attributes.state.visualization as LegacyMetricState; expect(visState.textAlign).toBe('center'); expect(visState.titlePosition).toBe('bottom'); expect(visState.size).toBe('xl'); @@ -2109,7 +2109,7 @@ describe('Lens migrations', () => { }, context ) as ReturnType>; - const visState = result.attributes.state.visualization as MetricState; + const visState = result.attributes.state.visualization as LegacyMetricState; expect(visState.textAlign).toBe('right'); expect(visState.titlePosition).toBe('top'); expect(visState.size).toBe('s'); @@ -2232,4 +2232,34 @@ describe('Lens migrations', () => { expect(visState.valueLabels).toBe('hide'); }); }); + + describe('8.5.0 migrates metric IDs', () => { + const context = { log: { warn: () => {} } } as unknown as SavedObjectMigrationContext; + const example = { + type: 'lens', + id: 'mocked-saved-object-id', + attributes: { + savedObjectId: '1', + title: 'MyRenamedOps', + description: '', + visualizationType: 'lnsMetric', + state: {}, + }, + } as unknown as SavedObjectUnsanitizedDoc; + + it('lnsMetric => lnsLegacyMetric', () => { + const result = migrations['8.5.0'](example, context) as ReturnType< + SavedObjectMigrationFn + >; + expect(result.attributes.visualizationType).toBe('lnsLegacyMetric'); + }); + + it('lnsMetricNew => lnsMetric', () => { + const result = migrations['8.5.0']( + { ...example, attributes: { ...example.attributes, visualizationType: 'lnsMetricNew' } }, + context + ) as ReturnType>; + expect(result.attributes.visualizationType).toBe('lnsMetric'); + }); + }); }); diff --git a/x-pack/plugins/lens/server/migrations/saved_object_migrations.ts b/x-pack/plugins/lens/server/migrations/saved_object_migrations.ts index e6daa2cb99439c..cdc231db5f9eec 100644 --- a/x-pack/plugins/lens/server/migrations/saved_object_migrations.ts +++ b/x-pack/plugins/lens/server/migrations/saved_object_migrations.ts @@ -33,6 +33,7 @@ import { XYVisualizationState830, VisState810, VisState820, + LensDocShape840, } from './types'; import { commonRenameOperationsForFormula, @@ -50,6 +51,7 @@ import { commonFixValueLabelsInXY, commonLockOldMetricVisSettings, commonPreserveOldLegendSizeDefault, + commonMigrateMetricIds, } from './common_migrations'; interface LensDocShapePre710 { @@ -510,6 +512,11 @@ const preserveOldLegendSizeDefault: SavedObjectMigrationFn ({ ...doc, attributes: commonPreserveOldLegendSizeDefault(doc.attributes) }); +const migrateMetricIds: SavedObjectMigrationFn = (doc) => ({ + ...doc, + attributes: commonMigrateMetricIds(doc.attributes), +}); + const lensMigrations: SavedObjectMigrationMap = { '7.7.0': removeInvalidAccessors, // The order of these migrations matter, since the timefield migration relies on the aggConfigs @@ -530,6 +537,7 @@ const lensMigrations: SavedObjectMigrationMap = { enhanceTableRowHeight ), '8.3.0': flow(lockOldMetricVisSettings, preserveOldLegendSizeDefault, fixValueLabelsInXY), + '8.5.0': flow(migrateMetricIds), }; export const getAllMigrations = ( diff --git a/x-pack/plugins/lens/server/migrations/types.ts b/x-pack/plugins/lens/server/migrations/types.ts index 6b38bb4b4f6311..fa3d4dfecf9d70 100644 --- a/x-pack/plugins/lens/server/migrations/types.ts +++ b/x-pack/plugins/lens/server/migrations/types.ts @@ -269,3 +269,6 @@ export interface XYVisualizationState830 extends VisState820 { export type VisStatePre830 = XYVisualizationStatePre830; export type VisState830 = XYVisualizationState830; + +export type VisState840 = VisState830; +export type LensDocShape840 = LensDocShape830; diff --git a/x-pack/plugins/lens/server/routes/index.ts b/x-pack/plugins/lens/server/routes/index.ts index bb6986cd7d2d27..c8145cd54b9a05 100644 --- a/x-pack/plugins/lens/server/routes/index.ts +++ b/x-pack/plugins/lens/server/routes/index.ts @@ -8,9 +8,7 @@ import { CoreSetup, Logger } from '@kbn/core/server'; import { PluginStartContract } from '../plugin'; import { existingFieldsRoute } from './existing_fields'; -import { initFieldsRoute } from './field_stats'; export function setupRoutes(setup: CoreSetup, logger: Logger) { existingFieldsRoute(setup, logger); - initFieldsRoute(setup); } diff --git a/x-pack/plugins/lens/tsconfig.json b/x-pack/plugins/lens/tsconfig.json index 9f548139a47d65..e29e0d1cb86b48 100644 --- a/x-pack/plugins/lens/tsconfig.json +++ b/x-pack/plugins/lens/tsconfig.json @@ -38,6 +38,7 @@ { "path": "../../../src/plugins/data_view_editor/tsconfig.json"}, { "path": "../../../src/plugins/event_annotation/tsconfig.json"}, { "path": "../../../src/plugins/chart_expressions/expression_xy/tsconfig.json"}, - { "path": "../../../src/plugins/unified_search/tsconfig.json" } + { "path": "../../../src/plugins/unified_search/tsconfig.json" }, + { "path": "../../../src/plugins/unified_field_list/tsconfig.json" } ] } diff --git a/x-pack/plugins/maps/common/descriptor_types/layer_descriptor_types.ts b/x-pack/plugins/maps/common/descriptor_types/layer_descriptor_types.ts index 36325c561b19a8..160a34f8bcc0d9 100644 --- a/x-pack/plugins/maps/common/descriptor_types/layer_descriptor_types.ts +++ b/x-pack/plugins/maps/common/descriptor_types/layer_descriptor_types.ts @@ -77,6 +77,7 @@ export type VectorLayerDescriptor = LayerDescriptor & { type: LAYER_TYPE.GEOJSON_VECTOR | LAYER_TYPE.MVT_VECTOR | LAYER_TYPE.BLENDED_VECTOR; joins?: JoinDescriptor[]; style: VectorStyleDescriptor; + disableTooltips?: boolean; }; export type HeatmapLayerDescriptor = LayerDescriptor & { diff --git a/x-pack/plugins/maps/common/descriptor_types/source_descriptor_types.ts b/x-pack/plugins/maps/common/descriptor_types/source_descriptor_types.ts index 8ca9f2acb49d64..b862558d6a2152 100644 --- a/x-pack/plugins/maps/common/descriptor_types/source_descriptor_types.ts +++ b/x-pack/plugins/maps/common/descriptor_types/source_descriptor_types.ts @@ -107,7 +107,6 @@ export type ESPewPewSourceDescriptor = AbstractESAggSourceDescriptor & { }; export type ESTermSourceDescriptor = AbstractESAggSourceDescriptor & { - indexPatternTitle?: string; term: string; // term field name whereQuery?: Query; size?: number; diff --git a/x-pack/plugins/maps/common/elasticsearch_util/elasticsearch_geo_utils.test.js b/x-pack/plugins/maps/common/elasticsearch_util/elasticsearch_geo_utils.test.js index 49996b61ba6c6e..096f5370ca3b97 100644 --- a/x-pack/plugins/maps/common/elasticsearch_util/elasticsearch_geo_utils.test.js +++ b/x-pack/plugins/maps/common/elasticsearch_util/elasticsearch_geo_utils.test.js @@ -360,14 +360,6 @@ describe('geoPointToGeometry', () => { expect(points[0].coordinates).toEqual([lon, lat]); }); - it('Should convert runtime geo_point value', () => { - const points = []; - geoPointToGeometry(`${lat},${lon}`, points); - expect(points.length).toBe(1); - expect(points[0].type).toBe('Point'); - expect(points[0].coordinates).toEqual([lon, lat]); - }); - it('Should convert array of values', () => { const lat2 = 30; const lon2 = -60; diff --git a/x-pack/plugins/maps/common/elasticsearch_util/elasticsearch_geo_utils.ts b/x-pack/plugins/maps/common/elasticsearch_util/elasticsearch_geo_utils.ts index 964a88a8b1a93b..9b03be8e7f8a0a 100644 --- a/x-pack/plugins/maps/common/elasticsearch_util/elasticsearch_geo_utils.ts +++ b/x-pack/plugins/maps/common/elasticsearch_util/elasticsearch_geo_utils.ts @@ -129,7 +129,7 @@ export function hitsToGeoJson( // Parse geo_point fields API response export function geoPointToGeometry( - value: Point[] | Point | string | undefined, + value: Point[] | Point | undefined, accumulator: Geometry[] ): void { if (!value) { @@ -143,19 +143,6 @@ export function geoPointToGeometry( return; } - // runtime geo_point field returns value as "lat,lon" string instead of GeoJSON - // This is a workaround for a bug - https://github.com/elastic/elasticsearch/issues/85245 - if (typeof value === 'string') { - const commaSplit = value.split(','); - const lat = parseFloat(commaSplit[0]); - const lon = parseFloat(commaSplit[1]); - accumulator.push({ - type: GEO_JSON_TYPE.POINT, - coordinates: [lon, lat], - } as Point); - return; - } - // geo_point fields API returns GeoJSON accumulator.push(value as Point); } diff --git a/x-pack/plugins/maps/common/elasticsearch_util/es_agg_utils.ts b/x-pack/plugins/maps/common/elasticsearch_util/es_agg_utils.ts index 76dafc6a6c68e3..90a29a0f72ee2e 100644 --- a/x-pack/plugins/maps/common/elasticsearch_util/es_agg_utils.ts +++ b/x-pack/plugins/maps/common/elasticsearch_util/es_agg_utils.ts @@ -18,8 +18,8 @@ export function getField(indexPattern: DataView, fieldName: string): DataViewFie if (!field) { throw new Error( i18n.translate('xpack.maps.source.esSearch.fieldNotFoundMsg', { - defaultMessage: `Unable to find '{fieldName}' in index-pattern '{indexPatternTitle}'.`, - values: { fieldName, indexPatternTitle: indexPattern.title }, + defaultMessage: `Unable to find '{fieldName}' in index-pattern '{indexPatternName}'.`, + values: { fieldName, indexPatternName: indexPattern.getName() }, }) ); } diff --git a/x-pack/plugins/maps/common/telemetry/index.ts b/x-pack/plugins/maps/common/telemetry/index.ts index c5ca2b05c6b524..6c5941db23d5bf 100644 --- a/x-pack/plugins/maps/common/telemetry/index.ts +++ b/x-pack/plugins/maps/common/telemetry/index.ts @@ -6,6 +6,7 @@ */ export { LayerStatsCollector } from './layer_stats_collector'; +export { MapSettingsCollector } from './map_settings_collector'; export type { EMS_BASEMAP_KEYS, JOIN_KEYS, diff --git a/x-pack/plugins/maps/public/actions/layer_actions.ts b/x-pack/plugins/maps/public/actions/layer_actions.ts index 9c2fea2a302d5a..7a4377f0bfc27e 100644 --- a/x-pack/plugins/maps/public/actions/layer_actions.ts +++ b/x-pack/plugins/maps/public/actions/layer_actions.ts @@ -554,6 +554,15 @@ export function updateFittableFlag(id: string, includeInFitToBounds: boolean) { }; } +export function updateDisableTooltips(id: string, disableTooltips: boolean) { + return { + type: UPDATE_LAYER_PROP, + id, + propName: 'disableTooltips', + newValue: disableTooltips, + }; +} + export function setLayerQuery(id: string, query: Query) { return (dispatch: ThunkDispatch) => { dispatch({ diff --git a/x-pack/plugins/maps/public/classes/fields/agg/agg_field.ts b/x-pack/plugins/maps/public/classes/fields/agg/agg_field.ts index 869c69229ebf19..1a6841ffa9e7ef 100644 --- a/x-pack/plugins/maps/public/classes/fields/agg/agg_field.ts +++ b/x-pack/plugins/maps/public/classes/fields/agg/agg_field.ts @@ -83,7 +83,7 @@ export class AggField extends CountAggField { async getLabel(): Promise { return this._label ? this._label - : this._source.getAggLabel( + : await this._source.getAggLabel( this._aggType, this._esDocField ? await this._esDocField.getLabel() : '' ); diff --git a/x-pack/plugins/maps/public/classes/fields/agg/count_agg_field.ts b/x-pack/plugins/maps/public/classes/fields/agg/count_agg_field.ts index 16f7a7d09d28f9..03ade37c3dbecc 100644 --- a/x-pack/plugins/maps/public/classes/fields/agg/count_agg_field.ts +++ b/x-pack/plugins/maps/public/classes/fields/agg/count_agg_field.ts @@ -66,7 +66,7 @@ export class CountAggField implements IESAggField { } async getLabel(): Promise { - return this._label ? this._label : this._source.getAggLabel(AGG_TYPE.COUNT, ''); + return this._label ? this._label : await this._source.getAggLabel(AGG_TYPE.COUNT, ''); } isValid(): boolean { diff --git a/x-pack/plugins/maps/public/classes/fields/agg/percentile_agg_field.test.ts b/x-pack/plugins/maps/public/classes/fields/agg/percentile_agg_field.test.ts index 4566cf4a73f1c1..3b6eff33130776 100644 --- a/x-pack/plugins/maps/public/classes/fields/agg/percentile_agg_field.test.ts +++ b/x-pack/plugins/maps/public/classes/fields/agg/percentile_agg_field.test.ts @@ -32,7 +32,7 @@ const mockEsAggSource = { getAggKey: (aggType: AGG_TYPE, fieldName: string) => { return 'agg_key'; }, - getAggLabel: (aggType: AGG_TYPE, fieldName: string) => { + getAggLabel: async (aggType: AGG_TYPE, fieldName: string) => { return 'agg_label'; }, getIndexPattern: async () => { diff --git a/x-pack/plugins/maps/public/classes/fields/agg/percentile_agg_field.ts b/x-pack/plugins/maps/public/classes/fields/agg/percentile_agg_field.ts index bc542bf891517c..57dcd5631918c1 100644 --- a/x-pack/plugins/maps/public/classes/fields/agg/percentile_agg_field.ts +++ b/x-pack/plugins/maps/public/classes/fields/agg/percentile_agg_field.ts @@ -57,7 +57,7 @@ export class PercentileAggField extends AggField implements IESAggField { } const suffix = getOrdinalSuffix(this._percentile); - return `${this._percentile}${suffix} ${this._source.getAggLabel( + return `${this._percentile}${suffix} ${await this._source.getAggLabel( this._getAggType(), this.getRootName() )}`; diff --git a/x-pack/plugins/maps/public/classes/joins/inner_join.test.js b/x-pack/plugins/maps/public/classes/joins/inner_join.test.js index 4e273f95515e4e..f8ca092e9a1640 100644 --- a/x-pack/plugins/maps/public/classes/joins/inner_join.test.js +++ b/x-pack/plugins/maps/public/classes/joins/inner_join.test.js @@ -15,7 +15,6 @@ const rightSource = { type: SOURCE_TYPES.ES_TERM_SOURCE, id: 'd3625663-5b34-4d50-a784-0d743f676a0c', indexPatternId: '90943e30-9a47-11e8-b64d-95841ca0b247', - indexPatternTitle: 'kibana_sample_data_logs', term: 'geo.dest', metrics: [{ type: 'count' }], }; diff --git a/x-pack/plugins/maps/public/classes/layers/create_region_map_layer_descriptor.ts b/x-pack/plugins/maps/public/classes/layers/create_region_map_layer_descriptor.ts index 19d9567a3480a0..e88cbaa0d6d874 100644 --- a/x-pack/plugins/maps/public/classes/layers/create_region_map_layer_descriptor.ts +++ b/x-pack/plugins/maps/public/classes/layers/create_region_map_layer_descriptor.ts @@ -37,7 +37,6 @@ export interface CreateRegionMapLayerDescriptorParams { termsSize?: number; colorSchema: string; indexPatternId?: string; - indexPatternTitle?: string; metricAgg: string; metricFieldName?: string; } @@ -65,7 +64,6 @@ export function createRegionMapLayerDescriptor({ termsSize, colorSchema, indexPatternId, - indexPatternTitle, metricAgg, metricFieldName, }: CreateRegionMapLayerDescriptorParams): LayerDescriptor | null { @@ -87,7 +85,6 @@ export function createRegionMapLayerDescriptor({ type: SOURCE_TYPES.ES_TERM_SOURCE, id: joinId, indexPatternId, - indexPatternTitle: indexPatternTitle ? indexPatternTitle : indexPatternId, term: termsFieldName, metrics: [metricsDescriptor], applyGlobalQuery: true, diff --git a/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.test.tsx b/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.test.tsx index 5b91e5e49c5141..b71fef484de016 100644 --- a/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.test.tsx +++ b/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.test.tsx @@ -72,7 +72,6 @@ describe('cloneDescriptor', () => { right: { id: '557d0f15', indexPatternId: 'myIndexPattern', - indexPatternTitle: 'logs-*', metrics: [{ type: AGG_TYPE.COUNT }], term: 'myTermField', type: SOURCE_TYPES.ES_TERM_SOURCE, @@ -114,7 +113,6 @@ describe('cloneDescriptor', () => { right: { id: '557d0f15', indexPatternId: 'myIndexPattern', - indexPatternTitle: 'logs-*', term: 'myTermField', type: 'joinSource', } as unknown as ESTermSourceDescriptor, diff --git a/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.tsx b/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.tsx index 032f2d0384afa4..3c78bf954e258b 100644 --- a/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.tsx +++ b/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.tsx @@ -98,6 +98,7 @@ export interface IVectorLayer extends ILayer { hasJoins(): boolean; showJoinEditor(): boolean; canShowTooltip(): boolean; + areTooltipsDisabled(): boolean; supportsFeatureEditing(): boolean; getLeftJoinFields(): Promise; addFeature(geometry: Geometry | Position[]): Promise; @@ -115,6 +116,7 @@ export const NO_RESULTS_ICON_AND_TOOLTIPCONTENT = { export class AbstractVectorLayer extends AbstractLayer implements IVectorLayer { protected readonly _style: VectorStyle; private readonly _joins: InnerJoin[]; + protected readonly _descriptor: VectorLayerDescriptor; static createDescriptor( options: Partial, @@ -132,6 +134,8 @@ export class AbstractVectorLayer extends AbstractLayer implements IVectorLayer { layerDescriptor.joins = []; } + layerDescriptor.disableTooltips = options.disableTooltips ?? false; + return layerDescriptor; } @@ -147,6 +151,7 @@ export class AbstractVectorLayer extends AbstractLayer implements IVectorLayer { source, }); this._joins = joins; + this._descriptor = AbstractVectorLayer.createDescriptor(layerDescriptor); this._style = new VectorStyle( layerDescriptor.style, source, @@ -932,10 +937,23 @@ export class AbstractVectorLayer extends AbstractLayer implements IVectorLayer { return allProperties; } + /** + * Check if there are any properties we can display in a tooltip. If `false` the "Show tooltips" switch + * is disabled in Layer settings. + * @returns {boolean} + */ canShowTooltip() { return this.getSource().hasTooltipProperties() || this.getJoins().length > 0; } + /** + * Users can toggle tooltips on hover or click in the Layer settings. Tooltips are enabled by default. + * @returns {boolean} + */ + areTooltipsDisabled(): boolean { + return this._descriptor.disableTooltips ?? false; + } + getFeatureId(feature: Feature): string | number | undefined { throw new Error('Should implement AbstractVectorLayer#getFeatureId'); } diff --git a/x-pack/plugins/maps/public/classes/layers/wizards/choropleth_layer_wizard/create_choropleth_layer_descriptor.ts b/x-pack/plugins/maps/public/classes/layers/wizards/choropleth_layer_wizard/create_choropleth_layer_descriptor.ts index 36e07d7383d184..2cbf6d3000b9af 100644 --- a/x-pack/plugins/maps/public/classes/layers/wizards/choropleth_layer_wizard/create_choropleth_layer_descriptor.ts +++ b/x-pack/plugins/maps/public/classes/layers/wizards/choropleth_layer_wizard/create_choropleth_layer_descriptor.ts @@ -38,14 +38,12 @@ function createChoroplethLayerDescriptor({ sourceDescriptor, leftField, rightIndexPatternId, - rightIndexPatternTitle, rightTermField, layerType, }: { sourceDescriptor: EMSFileSourceDescriptor | ESSearchSourceDescriptor; leftField: string; rightIndexPatternId: string; - rightIndexPatternTitle: string; rightTermField: string; layerType: LAYER_TYPE.GEOJSON_VECTOR | LAYER_TYPE.MVT_VECTOR; }) { @@ -98,7 +96,6 @@ function createChoroplethLayerDescriptor({ type: SOURCE_TYPES.ES_TERM_SOURCE, id: joinId, indexPatternId: rightIndexPatternId, - indexPatternTitle: rightIndexPatternTitle, term: rightTermField, metrics: [metricsDescriptor], applyGlobalQuery: true, @@ -125,13 +122,11 @@ export function createEmsChoroplethLayerDescriptor({ leftEmsFileId, leftEmsField, rightIndexPatternId, - rightIndexPatternTitle, rightTermField, }: { leftEmsFileId: string; leftEmsField: string; rightIndexPatternId: string; - rightIndexPatternTitle: string; rightTermField: string; }) { return createChoroplethLayerDescriptor({ @@ -141,7 +136,6 @@ export function createEmsChoroplethLayerDescriptor({ }), leftField: leftEmsField, rightIndexPatternId, - rightIndexPatternTitle, rightTermField, layerType: LAYER_TYPE.GEOJSON_VECTOR, }); @@ -152,14 +146,12 @@ export function createEsChoroplethLayerDescriptor({ leftGeoField, leftJoinField, rightIndexPatternId, - rightIndexPatternTitle, rightTermField, }: { leftIndexPatternId: string; leftGeoField: string; leftJoinField: string; rightIndexPatternId: string; - rightIndexPatternTitle: string; rightTermField: string; }) { return createChoroplethLayerDescriptor({ @@ -174,7 +166,6 @@ export function createEsChoroplethLayerDescriptor({ }), leftField: leftJoinField, rightIndexPatternId, - rightIndexPatternTitle, rightTermField, layerType: LAYER_TYPE.MVT_VECTOR, }); diff --git a/x-pack/plugins/maps/public/classes/layers/wizards/choropleth_layer_wizard/layer_template.tsx b/x-pack/plugins/maps/public/classes/layers/wizards/choropleth_layer_wizard/layer_template.tsx index 4edf85bc922d17..5fef8dd28ceb18 100644 --- a/x-pack/plugins/maps/public/classes/layers/wizards/choropleth_layer_wizard/layer_template.tsx +++ b/x-pack/plugins/maps/public/classes/layers/wizards/choropleth_layer_wizard/layer_template.tsx @@ -66,7 +66,6 @@ interface State { leftEmsJoinField: string | null; leftElasticsearchJoinField: string | null; rightIndexPatternId: string; - rightIndexPatternTitle: string | null; rightTermsFields: DataViewField[]; rightJoinField: string | null; } @@ -85,7 +84,6 @@ export class LayerTemplate extends Component { leftEmsJoinField: null, leftElasticsearchJoinField: null, rightIndexPatternId: '', - rightIndexPatternTitle: null, rightTermsFields: [], rightJoinField: null, }; @@ -99,7 +97,7 @@ export class LayerTemplate extends Component { } _loadRightFields = async (indexPatternId: string) => { - this.setState({ rightTermsFields: [], rightIndexPatternTitle: null }); + this.setState({ rightTermsFields: [] }); let indexPattern; try { @@ -116,7 +114,6 @@ export class LayerTemplate extends Component { this.setState({ rightTermsFields: getTermsFields(indexPattern.fields), - rightIndexPatternTitle: indexPattern.title, }); }; @@ -265,14 +262,12 @@ export class LayerTemplate extends Component { leftGeoField: this.state.leftGeoField!, leftJoinField: this.state.leftElasticsearchJoinField!, rightIndexPatternId: this.state.rightIndexPatternId, - rightIndexPatternTitle: this.state.rightIndexPatternTitle!, rightTermField: this.state.rightJoinField!, }) : createEmsChoroplethLayerDescriptor({ leftEmsFileId: this.state.leftEmsFileId!, leftEmsField: this.state.leftEmsJoinField!, rightIndexPatternId: this.state.rightIndexPatternId, - rightIndexPatternTitle: this.state.rightIndexPatternTitle!, rightTermField: this.state.rightJoinField!, }); diff --git a/x-pack/plugins/maps/public/classes/layers/wizards/solution_layers/observability/create_layer_descriptor.test.ts b/x-pack/plugins/maps/public/classes/layers/wizards/solution_layers/observability/create_layer_descriptor.test.ts index 771cf55ec25d3f..eff03a29ac99ad 100644 --- a/x-pack/plugins/maps/public/classes/layers/wizards/solution_layers/observability/create_layer_descriptor.test.ts +++ b/x-pack/plugins/maps/public/classes/layers/wizards/solution_layers/observability/create_layer_descriptor.test.ts @@ -55,7 +55,6 @@ describe('createLayerDescriptor', () => { applyGlobalTime: true, id: '12345', indexPatternId: 'apm_static_index_pattern_id', - indexPatternTitle: 'traces-apm*,logs-apm*,metrics-apm*,apm-*', metrics: [ { field: 'transaction.duration.us', @@ -75,6 +74,7 @@ describe('createLayerDescriptor', () => { label: '[Performance] Duration', maxZoom: 24, minZoom: 0, + disableTooltips: false, sourceDescriptor: { id: emsWorldLayerId, tooltipProperties: ['name', 'iso2'], @@ -173,6 +173,7 @@ describe('createLayerDescriptor', () => { label: '[Performance] Duration', maxZoom: 24, minZoom: 0, + disableTooltips: false, query: { language: 'kuery', query: 'processor.event:"transaction"', diff --git a/x-pack/plugins/maps/public/classes/layers/wizards/solution_layers/observability/create_layer_descriptor.ts b/x-pack/plugins/maps/public/classes/layers/wizards/solution_layers/observability/create_layer_descriptor.ts index 26a9f14b8160fe..b8536d89709399 100644 --- a/x-pack/plugins/maps/public/classes/layers/wizards/solution_layers/observability/create_layer_descriptor.ts +++ b/x-pack/plugins/maps/public/classes/layers/wizards/solution_layers/observability/create_layer_descriptor.ts @@ -173,7 +173,6 @@ export function createLayerDescriptor({ type: SOURCE_TYPES.ES_TERM_SOURCE, id: joinId, indexPatternId: APM_INDEX_PATTERN_ID, - indexPatternTitle: APM_INDEX_PATTERN_TITLE, // TODO look up from APM_OSS.indexPattern term: 'client.geo.country_iso_code', metrics: [metricsDescriptor], whereQuery: apmSourceQuery, diff --git a/x-pack/plugins/maps/public/classes/layers/wizards/solution_layers/security/create_layer_descriptors.test.ts b/x-pack/plugins/maps/public/classes/layers/wizards/solution_layers/security/create_layer_descriptors.test.ts index 934d5c6eee3ab6..2006c3eed6c2a9 100644 --- a/x-pack/plugins/maps/public/classes/layers/wizards/solution_layers/security/create_layer_descriptors.test.ts +++ b/x-pack/plugins/maps/public/classes/layers/wizards/solution_layers/security/create_layer_descriptors.test.ts @@ -42,6 +42,7 @@ describe('createLayerDescriptor', () => { label: 'apm-*-transaction* | Source Point', maxZoom: 24, minZoom: 0, + disableTooltips: false, sourceDescriptor: { applyGlobalQuery: true, applyGlobalTime: true, @@ -118,6 +119,7 @@ describe('createLayerDescriptor', () => { label: 'apm-*-transaction* | Destination point', maxZoom: 24, minZoom: 0, + disableTooltips: false, sourceDescriptor: { applyGlobalQuery: true, applyGlobalTime: true, @@ -194,6 +196,7 @@ describe('createLayerDescriptor', () => { label: 'apm-*-transaction* | Line', maxZoom: 24, minZoom: 0, + disableTooltips: false, sourceDescriptor: { applyGlobalQuery: true, applyGlobalTime: true, @@ -259,6 +262,7 @@ describe('createLayerDescriptor', () => { label: 'filebeat-* | Source Point', maxZoom: 24, minZoom: 0, + disableTooltips: false, sourceDescriptor: { applyGlobalQuery: true, applyGlobalTime: true, @@ -335,6 +339,7 @@ describe('createLayerDescriptor', () => { label: 'filebeat-* | Destination point', maxZoom: 24, minZoom: 0, + disableTooltips: false, sourceDescriptor: { applyGlobalQuery: true, applyGlobalTime: true, @@ -405,6 +410,7 @@ describe('createLayerDescriptor', () => { label: 'filebeat-* | Line', maxZoom: 24, minZoom: 0, + disableTooltips: false, sourceDescriptor: { applyGlobalQuery: true, applyGlobalTime: true, @@ -470,6 +476,7 @@ describe('createLayerDescriptor', () => { label: 'traces-apm-opbean-node | Source Point', maxZoom: 24, minZoom: 0, + disableTooltips: false, sourceDescriptor: { applyGlobalQuery: true, applyGlobalTime: true, @@ -546,6 +553,7 @@ describe('createLayerDescriptor', () => { label: 'traces-apm-opbean-node | Destination point', maxZoom: 24, minZoom: 0, + disableTooltips: false, sourceDescriptor: { applyGlobalQuery: true, applyGlobalTime: true, @@ -616,6 +624,7 @@ describe('createLayerDescriptor', () => { label: 'traces-apm-opbean-node | Line', maxZoom: 24, minZoom: 0, + disableTooltips: false, sourceDescriptor: { applyGlobalQuery: true, applyGlobalTime: true, diff --git a/x-pack/plugins/maps/public/classes/sources/es_agg_source/es_agg_source.ts b/x-pack/plugins/maps/public/classes/sources/es_agg_source/es_agg_source.ts index fce9293cf9f024..42b9c0ed73c77e 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_agg_source/es_agg_source.ts +++ b/x-pack/plugins/maps/public/classes/sources/es_agg_source/es_agg_source.ts @@ -21,7 +21,7 @@ export const DEFAULT_METRIC = { type: AGG_TYPE.COUNT }; export interface IESAggSource extends IESSource { getAggKey(aggType: AGG_TYPE, fieldName: string): string; - getAggLabel(aggType: AGG_TYPE, fieldLabel: string): string; + getAggLabel(aggType: AGG_TYPE, fieldLabel: string): Promise; getMetricFields(): IESAggField[]; getMetricFieldForName(fieldName: string): IESAggField | null; getValueAggsDsl(indexPattern: DataView): { [key: string]: unknown }; @@ -88,7 +88,7 @@ export abstract class AbstractESAggSource extends AbstractESSource implements IE }); } - getAggLabel(aggType: AGG_TYPE, fieldLabel: string): string { + async getAggLabel(aggType: AGG_TYPE, fieldLabel: string): Promise { switch (aggType) { case AGG_TYPE.COUNT: return COUNT_PROP_LABEL; diff --git a/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/es_geo_grid_source.tsx b/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/es_geo_grid_source.tsx index 37b764bf6dbdcc..b0a230bebc3cd3 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/es_geo_grid_source.tsx +++ b/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/es_geo_grid_source.tsx @@ -142,14 +142,6 @@ export class ESGeoGridSource extends AbstractESAggSource implements IMvtVectorSo } async getImmutableProperties(): Promise { - let indexPatternName = this.getIndexPatternId(); - try { - const indexPattern = await this.getIndexPattern(); - indexPatternName = indexPattern.title; - } catch (error) { - // ignore error, title will just default to id - } - return [ { label: getDataSourceLabel(), @@ -157,7 +149,7 @@ export class ESGeoGridSource extends AbstractESAggSource implements IMvtVectorSo }, { label: getDataViewLabel(), - value: indexPatternName, + value: await this.getDisplayName(), }, { label: i18n.translate('xpack.maps.source.esGrid.geospatialFieldLabel', { diff --git a/x-pack/plugins/maps/public/classes/sources/es_geo_line_source/es_geo_line_source.tsx b/x-pack/plugins/maps/public/classes/sources/es_geo_line_source/es_geo_line_source.tsx index 4bb23cfb7e55b1..78aae064a65553 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_geo_line_source/es_geo_line_source.tsx +++ b/x-pack/plugins/maps/public/classes/sources/es_geo_line_source/es_geo_line_source.tsx @@ -109,14 +109,6 @@ export class ESGeoLineSource extends AbstractESAggSource { } async getImmutableProperties(): Promise { - let indexPatternTitle = this.getIndexPatternId(); - try { - const indexPattern = await this.getIndexPattern(); - indexPatternTitle = indexPattern.title; - } catch (error) { - // ignore error, title will just default to id - } - return [ { label: getDataSourceLabel(), @@ -124,7 +116,7 @@ export class ESGeoLineSource extends AbstractESAggSource { }, { label: getDataViewLabel(), - value: indexPatternTitle, + value: await this.getDisplayName(), }, { label: i18n.translate('xpack.maps.source.esGeoLine.geospatialFieldLabel', { diff --git a/x-pack/plugins/maps/public/classes/sources/es_pew_pew_source/es_pew_pew_source.tsx b/x-pack/plugins/maps/public/classes/sources/es_pew_pew_source/es_pew_pew_source.tsx index 910181d6a28687..8e9f0aabf30707 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_pew_pew_source/es_pew_pew_source.tsx +++ b/x-pack/plugins/maps/public/classes/sources/es_pew_pew_source/es_pew_pew_source.tsx @@ -96,14 +96,6 @@ export class ESPewPewSource extends AbstractESAggSource { } async getImmutableProperties() { - let indexPatternTitle = this.getIndexPatternId(); - try { - const indexPattern = await this.getIndexPattern(); - indexPatternTitle = indexPattern.title; - } catch (error) { - // ignore error, title will just default to id - } - return [ { label: getDataSourceLabel(), @@ -111,7 +103,7 @@ export class ESPewPewSource extends AbstractESAggSource { }, { label: getDataViewLabel(), - value: indexPatternTitle, + value: await this.getDisplayName(), }, { label: i18n.translate('xpack.maps.source.pewPew.sourceGeoFieldLabel', { diff --git a/x-pack/plugins/maps/public/classes/sources/es_search_source/__snapshots__/update_source_editor.test.js.snap b/x-pack/plugins/maps/public/classes/sources/es_search_source/__snapshots__/update_source_editor.test.js.snap index 1edbdec2427229..c99d67ffd5a309 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_search_source/__snapshots__/update_source_editor.test.js.snap +++ b/x-pack/plugins/maps/public/classes/sources/es_search_source/__snapshots__/update_source_editor.test.js.snap @@ -94,12 +94,10 @@ exports[`should enable sort order select when sort field provided 1`] = ` clusteringDisabledReason={null} filterByMapBounds={true} indexPatternId="indexPattern1" - mvtDisabledReason={null} numberOfJoins={0} onChange={[Function]} scalingType="LIMIT" supportsClustering={false} - supportsMvt={true} /> { ? { indexPatternId: indexPattern.id, geoField: geoFieldName, - scalingType: field && field.isRuntimeField ? SCALING_TYPES.LIMIT : SCALING_TYPES.MVT, + scalingType: SCALING_TYPES.MVT, } : null; const isPointsOnly = field ? field.type === 'geo_point' : false; diff --git a/x-pack/plugins/maps/public/classes/sources/es_search_source/es_search_source.tsx b/x-pack/plugins/maps/public/classes/sources/es_search_source/es_search_source.tsx index b99903423376ee..f55f5be747dcd3 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_search_source/es_search_source.tsx +++ b/x-pack/plugins/maps/public/classes/sources/es_search_source/es_search_source.tsx @@ -220,15 +220,12 @@ export class ESSearchSource extends AbstractESSource implements IMvtVectorSource } async getImmutableProperties(): Promise { - let indexPatternName = this.getIndexPatternId(); let geoFieldType = ''; try { - const indexPattern = await this.getIndexPattern(); - indexPatternName = indexPattern.title; const geoField = await this._getGeoField(); geoFieldType = geoField.type; } catch (error) { - // ignore error, title will just default to id + // ignore error, geoFieldType will just be blank } return [ @@ -238,7 +235,7 @@ export class ESSearchSource extends AbstractESSource implements IMvtVectorSource }, { label: getDataViewLabel(), - value: indexPatternName, + value: await this.getDisplayName(), }, { label: i18n.translate('xpack.maps.source.esSearch.geoFieldLabel', { diff --git a/x-pack/plugins/maps/public/classes/sources/es_search_source/update_source_editor.tsx b/x-pack/plugins/maps/public/classes/sources/es_search_source/update_source_editor.tsx index 2c8dca0f1cdf61..51ebe8cc9e0426 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_search_source/update_source_editor.tsx +++ b/x-pack/plugins/maps/public/classes/sources/es_search_source/update_source_editor.tsx @@ -47,8 +47,6 @@ interface State { sortFields: DataViewField[] | undefined; supportsClustering: boolean; clusteringDisabledReason: string | null; - supportsMvt: boolean; - mvtDisabledReason: string | null; } export class UpdateSourceEditor extends Component { @@ -58,8 +56,6 @@ export class UpdateSourceEditor extends Component { sortFields: undefined, supportsClustering: false, clusteringDisabledReason: null, - supportsMvt: true, - mvtDisabledReason: null, }; componentDidMount() { @@ -111,13 +107,6 @@ export class UpdateSourceEditor extends Component { this.setState({ supportsClustering: supportsGeoTileAgg(geoField), clusteringDisabledReason: getGeoTileAggNotSupportedReason(geoField), - supportsMvt: !geoField.isRuntimeField, - mvtDisabledReason: geoField.isRuntimeField - ? i18n.translate('xpack.maps.source.esSearch.mvtDisableReason', { - defaultMessage: 'Vector tile API does not support runtime {type} field', - values: { type: geoField.type }, - }) - : null, sourceFields, sortFields: indexPattern.fields.filter( (field) => field.sortable && !indexPatterns.isNestedField(field) @@ -228,8 +217,6 @@ export class UpdateSourceEditor extends Component { scalingType={this.props.scalingType} supportsClustering={this.state.supportsClustering} clusteringDisabledReason={this.state.clusteringDisabledReason} - supportsMvt={this.state.supportsMvt} - mvtDisabledReason={this.state.mvtDisabledReason} numberOfJoins={this.props.numberOfJoins} /> diff --git a/x-pack/plugins/maps/public/classes/sources/es_search_source/util/__snapshots__/scaling_form.test.tsx.snap b/x-pack/plugins/maps/public/classes/sources/es_search_source/util/__snapshots__/scaling_form.test.tsx.snap index 0c77be62179c29..f8c5951e95e043 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_search_source/util/__snapshots__/scaling_form.test.tsx.snap +++ b/x-pack/plugins/maps/public/classes/sources/es_search_source/util/__snapshots__/scaling_form.test.tsx.snap @@ -34,7 +34,6 @@ exports[`scaling form should disable clusters option when clustering is not supp
{ _renderContent() { return (
- +
{this.props.mvtOptionLabel} (Default)
diff --git a/x-pack/plugins/maps/public/classes/sources/es_search_source/util/scaling_form.test.tsx b/x-pack/plugins/maps/public/classes/sources/es_search_source/util/scaling_form.test.tsx index 65ce7071df0486..38137ffcd72df5 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_search_source/util/scaling_form.test.tsx +++ b/x-pack/plugins/maps/public/classes/sources/es_search_source/util/scaling_form.test.tsx @@ -25,7 +25,6 @@ const defaultProps = { onChange: () => {}, scalingType: SCALING_TYPES.LIMIT, supportsClustering: true, - supportsMvt: true, termFields: [], numberOfJoins: 0, }; diff --git a/x-pack/plugins/maps/public/classes/sources/es_search_source/util/scaling_form.tsx b/x-pack/plugins/maps/public/classes/sources/es_search_source/util/scaling_form.tsx index fd0c23a98df459..ccd3b3913a0852 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_search_source/util/scaling_form.tsx +++ b/x-pack/plugins/maps/public/classes/sources/es_search_source/util/scaling_form.tsx @@ -35,8 +35,6 @@ interface Props { scalingType: SCALING_TYPES; supportsClustering: boolean; clusteringDisabledReason?: string | null; - supportsMvt: boolean; - mvtDisabledReason?: string | null; numberOfJoins: number; } @@ -188,26 +186,6 @@ export class ScalingForm extends Component { ); } - _renderMvtRadio() { - const radio = ( - this._onScalingTypeSelect(SCALING_TYPES.MVT)} - disabled={!this.props.supportsMvt} - /> - ); - - return this.props.mvtDisabledReason ? ( - - {radio} - - ) : ( - radio - ); - } - _renderClusteringRadio() { const clusteringRadio = ( {
- {this._renderMvtRadio()} + this._onScalingTypeSelect(SCALING_TYPES.MVT)} + /> {this._renderClusteringRadio()} { try { const indexPattern = await this.getIndexPattern(); - return indexPattern.title; + return indexPattern.getName(); } catch (error) { // Unable to load index pattern, just return id as display name return this.getIndexPatternId(); diff --git a/x-pack/plugins/maps/public/classes/sources/es_term_source/es_term_source.test.js b/x-pack/plugins/maps/public/classes/sources/es_term_source/es_term_source.test.js index 362b2b341714f7..c5bce9de0b0330 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_term_source/es_term_source.test.js +++ b/x-pack/plugins/maps/public/classes/sources/es_term_source/es_term_source.test.js @@ -9,7 +9,6 @@ import { ESTermSource, extractPropertiesMap } from './es_term_source'; jest.mock('../../layers/vector_layer', () => {}); -const indexPatternTitle = 'myIndex'; const termFieldName = 'myTermField'; const sumFieldName = 'myFieldGettingSummed'; const metricExamples = [ @@ -33,19 +32,17 @@ describe('getMetricFields', () => { it('should override name and label of count metric', async () => { const source = new ESTermSource({ id: '1234', - indexPatternTitle: indexPatternTitle, term: termFieldName, indexPatternId: 'foobar', }); const metrics = source.getMetricFields(); expect(metrics[0].getName()).toEqual('__kbnjoin__count__1234'); - expect(await metrics[0].getLabel()).toEqual('Count of myIndex'); + expect(await metrics[0].getLabel()).toEqual('Count of foobar'); }); it('should override name and label of sum metric', async () => { const source = new ESTermSource({ id: '1234', - indexPatternTitle: indexPatternTitle, term: termFieldName, metrics: metricExamples, indexPatternId: 'foobar', @@ -54,7 +51,7 @@ describe('getMetricFields', () => { expect(metrics[0].getName()).toEqual('__kbnjoin__sum_of_myFieldGettingSummed__1234'); expect(await metrics[0].getLabel()).toEqual('my custom label'); expect(metrics[1].getName()).toEqual('__kbnjoin__count__1234'); - expect(await metrics[1].getLabel()).toEqual('Count of myIndex'); + expect(await metrics[1].getLabel()).toEqual('Count of foobar'); }); }); @@ -114,7 +111,6 @@ describe('getSyncMeta', () => { it('should contain meta requiring source re-fetch when changed', () => { const source = new ESTermSource({ id: '1234', - indexPatternTitle: indexPatternTitle, term: termFieldName, indexPatternId: 'foobar', size: 10, diff --git a/x-pack/plugins/maps/public/classes/sources/es_term_source/es_term_source.ts b/x-pack/plugins/maps/public/classes/sources/es_term_source/es_term_source.ts index 5447910dc524a5..71ce42be22ab0c 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_term_source/es_term_source.ts +++ b/x-pack/plugins/maps/public/classes/sources/es_term_source/es_term_source.ts @@ -63,9 +63,6 @@ export class ESTermSource extends AbstractESAggSource implements ITermJoinSource } return { ...normalizedDescriptor, - indexPatternTitle: descriptor.indexPatternTitle - ? descriptor.indexPatternTitle - : descriptor.indexPatternId, term: descriptor.term!, type: SOURCE_TYPES.ES_TERM_SOURCE, }; @@ -109,11 +106,18 @@ export class ESTermSource extends AbstractESAggSource implements ITermJoinSource }); } - getAggLabel(aggType: AGG_TYPE, fieldLabel: string): string { + async getAggLabel(aggType: AGG_TYPE, fieldLabel: string): Promise { + let indexPatternLabel: string | undefined; + try { + const indexPattern = await this.getIndexPattern(); + indexPatternLabel = indexPattern.getName(); + } catch (error) { + indexPatternLabel = this._descriptor.indexPatternId; + } return aggType === AGG_TYPE.COUNT ? i18n.translate('xpack.maps.source.esJoin.countLabel', { - defaultMessage: `Count of {indexPatternTitle}`, - values: { indexPatternTitle: this._descriptor.indexPatternTitle }, + defaultMessage: `Count of {indexPatternLabel}`, + values: { indexPatternLabel }, }) : super.getAggLabel(aggType, fieldLabel); } @@ -145,14 +149,14 @@ export class ESTermSource extends AbstractESAggSource implements ITermJoinSource const rawEsData = await this._runEsQuery({ requestId: this.getId(), - requestName: `${this._descriptor.indexPatternTitle}.${this._termField.getName()}`, + requestName: `${indexPattern.getName()}.${this._termField.getName()}`, searchSource, registerCancelCallback, requestDescription: i18n.translate('xpack.maps.source.esJoin.joinDescription', { defaultMessage: `Elasticsearch terms aggregation request, left source: {leftSource}, right source: {rightSource}`, values: { leftSource: `${leftSourceName}:${leftFieldName}`, - rightSource: `${this._descriptor.indexPatternTitle}:${this._termField.getName()}`, + rightSource: `${indexPattern.getName()}:${this._termField.getName()}`, }, }), searchSessionId: searchFilters.searchSessionId, diff --git a/x-pack/plugins/maps/public/classes/styles/vector/components/symbol/custom_icon_modal.test.tsx b/x-pack/plugins/maps/public/classes/styles/vector/components/symbol/custom_icon_modal.test.tsx index 8e21679405c075..b17eb07756f27b 100644 --- a/x-pack/plugins/maps/public/classes/styles/vector/components/symbol/custom_icon_modal.test.tsx +++ b/x-pack/plugins/maps/public/classes/styles/vector/components/symbol/custom_icon_modal.test.tsx @@ -10,6 +10,14 @@ import { shallow } from 'enzyme'; import { CustomIconModal } from './custom_icon_modal'; +jest.mock('../../../../../kibana_services', () => ({ + getUsageCollection: () => { + return { + reportUiCounter: () => {}, + }; + }, +})); + const defaultProps = { cutoff: 0.25, onCancel: () => {}, diff --git a/x-pack/plugins/maps/public/classes/styles/vector/components/symbol/custom_icon_modal.tsx b/x-pack/plugins/maps/public/classes/styles/vector/components/symbol/custom_icon_modal.tsx index 9898ac0cd3e930..167672ad536a09 100644 --- a/x-pack/plugins/maps/public/classes/styles/vector/components/symbol/custom_icon_modal.tsx +++ b/x-pack/plugins/maps/public/classes/styles/vector/components/symbol/custom_icon_modal.tsx @@ -25,6 +25,7 @@ import { EuiSpacer, EuiToolTip, } from '@elastic/eui'; +import { METRIC_TYPE } from '@kbn/analytics'; import { i18n } from '@kbn/i18n'; import { IconPreview } from './icon_preview'; // @ts-expect-error @@ -32,6 +33,8 @@ import { getCustomIconId } from '../../symbol_utils'; // @ts-expect-error import { ValidatedRange } from '../../../../../components/validated_range'; import { CustomIcon } from '../../../../../../common/descriptor_types'; +import { APP_ID } from '../../../../../../common'; +import { getUsageCollection } from '../../../../../kibana_services'; const strings = { getAdvancedOptionsLabel: () => @@ -314,6 +317,7 @@ export class CustomIconModal extends Component { } public render() { + const usageCollector = getUsageCollection(); const { symbolId, onSave, onCancel, onDelete, title } = this.props; const { label, svg, cutoff, radius, isFileInvalid } = this.state; const isComplete = label.length !== 0 && svg.length !== 0 && !isFileInvalid; @@ -365,6 +369,11 @@ export class CustomIconModal extends Component { { + usageCollector?.reportUiCounter( + APP_ID, + METRIC_TYPE.CLICK, + 'settings_custom_icons_delete' + ); onDelete(symbolId); }} data-test-subj="mapsCustomIconForm-submit" @@ -377,6 +386,14 @@ export class CustomIconModal extends Component { { + if (!onDelete) { + // Only report events when adding a new custom icon, not when editing an existing icon + usageCollector?.reportUiCounter( + APP_ID, + METRIC_TYPE.CLICK, + 'settings_custom_icons_add' + ); + } onSave({ symbolId: symbolId ?? getCustomIconId(), label, svg, cutoff, radius }); }} data-test-subj="mapsCustomIconForm-submit" diff --git a/x-pack/plugins/maps/public/connected_components/edit_layer_panel/join_editor/__snapshots__/join_editor.test.tsx.snap b/x-pack/plugins/maps/public/connected_components/edit_layer_panel/join_editor/__snapshots__/join_editor.test.tsx.snap index de9d74f68f9656..41903e8accafc9 100644 --- a/x-pack/plugins/maps/public/connected_components/edit_layer_panel/join_editor/__snapshots__/join_editor.test.tsx.snap +++ b/x-pack/plugins/maps/public/connected_components/edit_layer_panel/join_editor/__snapshots__/join_editor.test.tsx.snap @@ -48,7 +48,6 @@ exports[`Should render join editor 1`] = ` "right": Object { "id": "673ff994-fc75-4c67-909b-69fcb0e1060e", "indexPatternId": "abcde", - "indexPatternTitle": "kibana_sample_data_logs", "metrics": Array [ Object { "label": "web logs count", diff --git a/x-pack/plugins/maps/public/connected_components/edit_layer_panel/join_editor/join_editor.test.tsx b/x-pack/plugins/maps/public/connected_components/edit_layer_panel/join_editor/join_editor.test.tsx index cb007110f7d35b..1bfe40b555261b 100644 --- a/x-pack/plugins/maps/public/connected_components/edit_layer_panel/join_editor/join_editor.test.tsx +++ b/x-pack/plugins/maps/public/connected_components/edit_layer_panel/join_editor/join_editor.test.tsx @@ -37,7 +37,6 @@ const defaultProps = { leftField: 'iso2', right: { id: '673ff994-fc75-4c67-909b-69fcb0e1060e', - indexPatternTitle: 'kibana_sample_data_logs', term: 'geo.src', indexPatternId: 'abcde', metrics: [ diff --git a/x-pack/plugins/maps/public/connected_components/edit_layer_panel/join_editor/resources/join.tsx b/x-pack/plugins/maps/public/connected_components/edit_layer_panel/join_editor/resources/join.tsx index bbfc9bbb0f3026..1eb23dc207cd4b 100644 --- a/x-pack/plugins/maps/public/connected_components/edit_layer_panel/join_editor/resources/join.tsx +++ b/x-pack/plugins/maps/public/connected_components/edit_layer_panel/join_editor/resources/join.tsx @@ -95,13 +95,7 @@ export class Join extends Component { }); }; - _onRightSourceChange = ({ - indexPatternId, - indexPatternTitle, - }: { - indexPatternId: string; - indexPatternTitle: string; - }) => { + _onRightSourceChange = (indexPatternId: string) => { this.setState({ rightFields: [], loadError: undefined, @@ -113,7 +107,6 @@ export class Join extends Component { right: { ...restOfRight, indexPatternId, - indexPatternTitle, type: SOURCE_TYPES.ES_TERM_SOURCE, } as ESTermSourceDescriptor, }); @@ -183,9 +176,7 @@ export class Join extends Component { const { join, onRemove, leftFields, leftSourceName } = this.props; const { rightFields, indexPattern } = this.state; const right = _.get(join, 'right', {}) as ESTermSourceDescriptor; - const rightSourceName = right.indexPatternTitle - ? right.indexPatternTitle - : right.indexPatternId; + const rightSourceName = indexPattern ? indexPattern.getName() : right.indexPatternId; const isJoinConfigComplete = join.leftField && right.indexPatternId && right.term; let metricsExpression; diff --git a/x-pack/plugins/maps/public/connected_components/edit_layer_panel/join_editor/resources/join_documentation_popover.tsx b/x-pack/plugins/maps/public/connected_components/edit_layer_panel/join_editor/resources/join_documentation_popover.tsx index 1799b7264611dc..1df70f334a4fd4 100644 --- a/x-pack/plugins/maps/public/connected_components/edit_layer_panel/join_editor/resources/join_documentation_popover.tsx +++ b/x-pack/plugins/maps/public/connected_components/edit_layer_panel/join_editor/resources/join_documentation_popover.tsx @@ -34,7 +34,7 @@ export class JoinDocumentationPopover extends Component<{}, State> { _renderContent() { return (
- +

void; + onRightSourceChange: (indexPatternId: string) => void; // Right field props rightValue: string; @@ -81,20 +72,12 @@ export class JoinExpression extends Component { }); }; - _onRightSourceChange = async (indexPatternId?: string) => { + _onRightSourceChange = (indexPatternId?: string) => { if (!indexPatternId || indexPatternId.length === 0) { return; } - try { - const indexPattern = await getIndexPatternService().get(indexPatternId); - this.props.onRightSourceChange({ - indexPatternId, - indexPatternTitle: indexPattern.title, - }); - } catch (err) { - // do not call onChange with when unable to get indexPatternId - } + this.props.onRightSourceChange(indexPatternId); }; _onLeftFieldChange = (selectedFields: Array>) => { diff --git a/x-pack/plugins/maps/public/connected_components/edit_layer_panel/layer_settings/index.tsx b/x-pack/plugins/maps/public/connected_components/edit_layer_panel/layer_settings/index.tsx index 44336a5bbaf56d..e2cb962f4dd514 100644 --- a/x-pack/plugins/maps/public/connected_components/edit_layer_panel/layer_settings/index.tsx +++ b/x-pack/plugins/maps/public/connected_components/edit_layer_panel/layer_settings/index.tsx @@ -18,6 +18,7 @@ import { updateLayerAlpha, updateLabelsOnTop, updateFittableFlag, + updateDisableTooltips, } from '../../../actions'; import { Attribution } from '../../../../common/descriptor_types'; @@ -35,6 +36,8 @@ function mapDispatchToProps(dispatch: Dispatch) { dispatch(updateLabelsOnTop(id, areLabelsOnTop)), updateIncludeInFitToBounds: (id: string, includeInFitToBounds: boolean) => dispatch(updateFittableFlag(id, includeInFitToBounds)), + updateDisableTooltips: (id: string, DisableTooltips: boolean) => + dispatch(updateDisableTooltips(id, DisableTooltips)), }; } diff --git a/x-pack/plugins/maps/public/connected_components/edit_layer_panel/layer_settings/layer_settings.tsx b/x-pack/plugins/maps/public/connected_components/edit_layer_panel/layer_settings/layer_settings.tsx index 4ae95b9dc5c48b..794064e09d3c63 100644 --- a/x-pack/plugins/maps/public/connected_components/edit_layer_panel/layer_settings/layer_settings.tsx +++ b/x-pack/plugins/maps/public/connected_components/edit_layer_panel/layer_settings/layer_settings.tsx @@ -24,6 +24,7 @@ import { Attribution } from '../../../../common/descriptor_types'; import { AUTOSELECT_EMS_LOCALE, NO_EMS_LOCALE, MAX_ZOOM } from '../../../../common/constants'; import { AlphaSlider } from '../../../components/alpha_slider'; import { ILayer } from '../../../classes/layers/layer'; +import { isVectorLayer, IVectorLayer } from '../../../classes/layers/vector_layer'; import { AttributionFormRow } from './attribution_form_row'; export interface Props { @@ -37,6 +38,7 @@ export interface Props { updateAlpha: (layerId: string, alpha: number) => void; updateLabelsOnTop: (layerId: string, areLabelsOnTop: boolean) => void; updateIncludeInFitToBounds: (layerId: string, includeInFitToBounds: boolean) => void; + updateDisableTooltips: (layerId: string, disableTooltips: boolean) => void; supportsFitToBounds: boolean; } @@ -68,6 +70,10 @@ export function LayerSettings(props: Props) { props.updateLabelsOnTop(layerId, event.target.checked); }; + const onShowTooltipsChange = (event: EuiSwitchEvent) => { + props.updateDisableTooltips(layerId, !event.target.checked); + }; + const includeInFitToBoundsChange = (event: EuiSwitchEvent) => { props.updateIncludeInFitToBounds(layerId, event.target.checked); }; @@ -162,6 +168,27 @@ export function LayerSettings(props: Props) { ); }; + const renderDisableTooltips = () => { + if (!isVectorLayer(props.layer)) { + return null; + } else { + const layer = props.layer as unknown as IVectorLayer; + return ( + + + + ); + } + }; + const renderShowLocaleSelector = () => { if (!props.layer.supportsLabelLocales()) { return null; @@ -234,6 +261,7 @@ export function LayerSettings(props: Props) { {renderShowLocaleSelector()} {renderIncludeInFitToBounds()} + {renderDisableTooltips()} diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/tooltip_control/tooltip_control.test.tsx b/x-pack/plugins/maps/public/connected_components/mb_map/tooltip_control/tooltip_control.test.tsx index 736d7810757c55..cda7a4a2739b55 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/tooltip_control/tooltip_control.test.tsx +++ b/x-pack/plugins/maps/public/connected_components/mb_map/tooltip_control/tooltip_control.test.tsx @@ -38,6 +38,9 @@ const mockLayer = { canShowTooltip: () => { return true; }, + areTooltipsDisabled: () => { + return false; + }, getMbTooltipLayerIds: () => { return ['foo', 'bar']; }, diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/tooltip_control/tooltip_control.tsx b/x-pack/plugins/maps/public/connected_components/mb_map/tooltip_control/tooltip_control.tsx index 41a69b4d3c0651..70def963d01dd9 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/tooltip_control/tooltip_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/mb_map/tooltip_control/tooltip_control.tsx @@ -178,13 +178,13 @@ export class TooltipControl extends Component { for (let i = 0; i < mbFeatures.length; i++) { const mbFeature = mbFeatures[i]; const layer = this._getLayerByMbLayerId(mbFeature.layer.id); - if (!layer) { - break; + if (!layer || !layer.canShowTooltip() || layer.areTooltipsDisabled()) { + continue; } const featureId = layer.getFeatureId(mbFeature); if (featureId === undefined) { - break; + continue; } const layerId = layer.getId(); let match = false; @@ -192,7 +192,7 @@ export class TooltipControl extends Component { const uniqueFeature = uniqueFeatures[j]; if (featureId === uniqueFeature.id && layerId === uniqueFeature.layerId) { match = true; - break; + continue; } } if (!match) { diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.test.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.test.tsx index 4601b5c5692909..443dd7b47a0693 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.test.tsx +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.test.tsx @@ -12,14 +12,6 @@ import { ToolsControl } from './tools_control'; const defaultProps = { initiateDraw: () => {}, cancelDraw: () => {}, - geoFields: [ - { - geoFieldName: 'location', - geoFieldType: 'geo_point', - indexPatternTitle: 'my_index', - indexPatternId: '1', - }, - ], filterModeActive: false, activateDrawFilterMode: () => {}, deactivateDrawMode: () => {}, diff --git a/x-pack/plugins/maps/public/embeddable/map_component.tsx b/x-pack/plugins/maps/public/embeddable/map_component.tsx index 4709255927734b..bb331ccf38c0e5 100644 --- a/x-pack/plugins/maps/public/embeddable/map_component.tsx +++ b/x-pack/plugins/maps/public/embeddable/map_component.tsx @@ -16,6 +16,7 @@ import type { LazyLoadedMapModules } from '../lazy_load_bundle'; import { lazyLoadMapModules } from '../lazy_load_bundle'; interface Props { + title: string; filters?: Filter[]; query?: Query; timeRange?: TimeRange; @@ -81,7 +82,7 @@ export class MapComponent extends Component { { id: uuid(), attributes: { - title: '', + title: this.props.title, layerListJSON: JSON.stringify([ mapModules.createBasemapLayerDescriptor(), ...this.props.getLayerDescriptors({ diff --git a/x-pack/plugins/maps/public/lazy_load_bundle/index.ts b/x-pack/plugins/maps/public/lazy_load_bundle/index.ts index cbd1b3aa4b4c85..cdf61a6ab9173f 100644 --- a/x-pack/plugins/maps/public/lazy_load_bundle/index.ts +++ b/x-pack/plugins/maps/public/lazy_load_bundle/index.ts @@ -51,7 +51,6 @@ export interface LazyLoadedMapModules { termsSize, colorSchema, indexPatternId, - indexPatternTitle, metricAgg, metricFieldName, }: CreateRegionMapLayerDescriptorParams) => LayerDescriptor | null; diff --git a/x-pack/plugins/maps/public/legacy_visualizations/index.ts b/x-pack/plugins/maps/public/legacy_visualizations/index.ts index a01e0ebefb5ad5..f6e154949390e0 100644 --- a/x-pack/plugins/maps/public/legacy_visualizations/index.ts +++ b/x-pack/plugins/maps/public/legacy_visualizations/index.ts @@ -7,3 +7,4 @@ export { createRegionMapFn, regionMapRenderer, regionMapVisType } from './region_map'; export { createTileMapFn, tileMapRenderer, tileMapVisType } from './tile_map'; +export { isLegacyMap } from './is_legacy_map'; diff --git a/x-pack/plugins/maps/public/legacy_visualizations/is_legacy_map.ts b/x-pack/plugins/maps/public/legacy_visualizations/is_legacy_map.ts new file mode 100644 index 00000000000000..2a5fc483027e78 --- /dev/null +++ b/x-pack/plugins/maps/public/legacy_visualizations/is_legacy_map.ts @@ -0,0 +1,17 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { Embeddable } from '@kbn/embeddable-plugin/public'; +import type { VisualizeEmbeddable } from '@kbn/visualizations-plugin/public'; + +export function isLegacyMap(embeddable: Embeddable) { + return ( + embeddable.type === 'visualization' && + typeof (embeddable as VisualizeEmbeddable).getVis === 'function' && + ['region_map', 'tile_map'].includes((embeddable as VisualizeEmbeddable).getVis()?.type?.name) + ); +} diff --git a/x-pack/plugins/maps/public/legacy_visualizations/region_map/region_map_visualization.tsx b/x-pack/plugins/maps/public/legacy_visualizations/region_map/region_map_visualization.tsx index 2334b9af1996c2..b6945995da9d9f 100644 --- a/x-pack/plugins/maps/public/legacy_visualizations/region_map/region_map_visualization.tsx +++ b/x-pack/plugins/maps/public/legacy_visualizations/region_map/region_map_visualization.tsx @@ -36,6 +36,7 @@ function RegionMapVisualization(props: Props) { } return ( ) { leftFieldName: vis.params.selectedLayer.isEMS ? vis.params.selectedJoinField.name : undefined, colorSchema: vis.params.colorSchema, indexPatternId: vis.data.indexPattern?.id, - indexPatternTitle: vis.data.indexPattern?.title, metricAgg: 'count', }; diff --git a/x-pack/plugins/maps/public/legacy_visualizations/tile_map/tile_map_visualization.tsx b/x-pack/plugins/maps/public/legacy_visualizations/tile_map/tile_map_visualization.tsx index fd5f916baf4c60..97a3609d765a40 100644 --- a/x-pack/plugins/maps/public/legacy_visualizations/tile_map/tile_map_visualization.tsx +++ b/x-pack/plugins/maps/public/legacy_visualizations/tile_map/tile_map_visualization.tsx @@ -36,6 +36,7 @@ function TileMapVisualization(props: Props) { } return ( ) { const decodedCustomIcons = settings.customIcons @@ -281,6 +281,8 @@ export class SavedMap { return; } + const mapSettingsStatsCollector = new MapSettingsCollector(this._attributes); + const layerStatsCollector = new LayerStatsCollector(this._attributes); const uiCounterEvents = { @@ -289,6 +291,9 @@ export class SavedMap { resolution: layerStatsCollector.getResolutionCounts(), join: layerStatsCollector.getJoinCounts(), ems_basemap: layerStatsCollector.getBasemapCounts(), + settings: { + custom_icons_count: mapSettingsStatsCollector.getCustomIconsCount(), + }, }; for (const [eventType, eventTypeMetrics] of Object.entries(uiCounterEvents)) { diff --git a/x-pack/plugins/maps/public/trigger_actions/filter_by_map_extent_action.tsx b/x-pack/plugins/maps/public/trigger_actions/filter_by_map_extent_action.tsx index b9d70bf4afbf35..c2183774cf677a 100644 --- a/x-pack/plugins/maps/public/trigger_actions/filter_by_map_extent_action.tsx +++ b/x-pack/plugins/maps/public/trigger_actions/filter_by_map_extent_action.tsx @@ -10,6 +10,7 @@ import { i18n } from '@kbn/i18n'; import { Embeddable, EmbeddableInput } from '@kbn/embeddable-plugin/public'; import { createReactOverlays } from '@kbn/kibana-react-plugin/public'; import { createAction } from '@kbn/ui-actions-plugin/public'; +import { isLegacyMap } from '../legacy_visualizations'; import { MAP_SAVED_OBJECT_TYPE } from '../../common/constants'; import { getCore } from '../kibana_services'; @@ -58,7 +59,10 @@ export const filterByMapExtentAction = createAction { - return embeddable.type === MAP_SAVED_OBJECT_TYPE && !embeddable.getInput().disableTriggers; + return ( + (embeddable.type === MAP_SAVED_OBJECT_TYPE || isLegacyMap(embeddable)) && + !embeddable.getInput().disableTriggers + ); }, execute: async (context: FilterByMapExtentActionContext) => { const { FilterByMapExtentModal } = await import('./filter_by_map_extent_modal'); diff --git a/x-pack/plugins/maps/public/trigger_actions/synchronize_movement_action.tsx b/x-pack/plugins/maps/public/trigger_actions/synchronize_movement_action.tsx index e3404c628a54fa..7116e55fd521d0 100644 --- a/x-pack/plugins/maps/public/trigger_actions/synchronize_movement_action.tsx +++ b/x-pack/plugins/maps/public/trigger_actions/synchronize_movement_action.tsx @@ -11,6 +11,7 @@ import { createReactOverlays } from '@kbn/kibana-react-plugin/public'; import { Embeddable, EmbeddableInput } from '@kbn/embeddable-plugin/public'; import { createAction } from '@kbn/ui-actions-plugin/public'; import type { Embeddable as LensEmbeddable } from '@kbn/lens-plugin/public'; +import { isLegacyMap } from '../legacy_visualizations'; import { MAP_SAVED_OBJECT_TYPE } from '../../common/constants'; import { getCore } from '../kibana_services'; @@ -52,6 +53,10 @@ export const synchronizeMovementAction = createAction { diff --git a/x-pack/plugins/maps/tsconfig.json b/x-pack/plugins/maps/tsconfig.json index 57cc09dec4b169..ee28c2be8d31ca 100644 --- a/x-pack/plugins/maps/tsconfig.json +++ b/x-pack/plugins/maps/tsconfig.json @@ -32,7 +32,6 @@ { "path": "../../../src/plugins/usage_collection/tsconfig.json" }, { "path": "../../../src/plugins/kibana_react/tsconfig.json" }, { "path": "../../../src/plugins/kibana_utils/tsconfig.json" }, - { "path": "../../../src/plugins/shared_ux/tsconfig.json" }, { "path": "../../../src/plugins/screenshot_mode/tsconfig.json" }, { "path": "../cloud/tsconfig.json" }, { "path": "../features/tsconfig.json" }, diff --git a/x-pack/plugins/ml/public/application/components/chart_tooltip/chart_tooltip.tsx b/x-pack/plugins/ml/public/application/components/chart_tooltip/chart_tooltip.tsx index d5b31b418e3465..b721608d53f7e4 100644 --- a/x-pack/plugins/ml/public/application/components/chart_tooltip/chart_tooltip.tsx +++ b/x-pack/plugins/ml/public/application/components/chart_tooltip/chart_tooltip.tsx @@ -122,11 +122,14 @@ const Tooltip: FC<{ service: ChartTooltipService }> = React.memo(({ service }) = return ( = ({ children }) => { const { setHeaderActionMenu } = useContext(MlPageControlsContext); - const portalNode = useMemo(() => createPortalNode(), []); + const portalNode = useMemo(() => createHtmlPortalNode(), []); useEffect(() => { if (!setHeaderActionMenu) { diff --git a/x-pack/plugins/ml/public/application/components/ml_page/ml_page.tsx b/x-pack/plugins/ml/public/application/components/ml_page/ml_page.tsx index 90dd95dbafb711..bd12a120420c26 100644 --- a/x-pack/plugins/ml/public/application/components/ml_page/ml_page.tsx +++ b/x-pack/plugins/ml/public/application/components/ml_page/ml_page.tsx @@ -11,7 +11,7 @@ import { i18n } from '@kbn/i18n'; import { Redirect, Route, Switch } from 'react-router-dom'; import type { AppMountParameters } from '@kbn/core/public'; import { KibanaPageTemplate, RedirectAppLinks } from '@kbn/kibana-react-plugin/public'; -import { createPortalNode, PortalNode } from 'react-reverse-portal'; +import { createHtmlPortalNode, HtmlPortalNode } from 'react-reverse-portal'; import { MlPageHeaderRenderer } from '../page_header/page_header'; import { useSideNavItems } from './side_nav'; import * as routes from '../../routing/routes'; @@ -23,13 +23,13 @@ import { useActiveRoute } from '../../routing/use_active_route'; import { useDocTitle } from '../../routing/use_doc_title'; export const MlPageControlsContext = createContext<{ - headerPortal: PortalNode; + headerPortal: HtmlPortalNode; setHeaderActionMenu?: AppMountParameters['setHeaderActionMenu']; setIsHeaderMounted: (v: boolean) => void; isHeaderMounted: boolean; }>({ setHeaderActionMenu: () => {}, - headerPortal: createPortalNode(), + headerPortal: createHtmlPortalNode(), isHeaderMounted: false, setIsHeaderMounted: () => {}, }); @@ -46,7 +46,7 @@ export const MlPage: FC<{ pageDeps: PageDependencies }> = React.memo(({ pageDeps }, } = useMlKibana(); - const headerPortalNode = useMemo(() => createPortalNode(), []); + const headerPortalNode = useMemo(() => createHtmlPortalNode(), []); const [isHeaderMounted, setIsHeaderMounted] = useState(false); const routeList = useMemo( @@ -114,7 +114,7 @@ interface CommonPageWrapperProps { setIsHeaderMounted: (v: boolean) => void; pageDeps: PageDependencies; routeList: MlRoute[]; - headerPortal: PortalNode; + headerPortal: HtmlPortalNode; } const CommonPageWrapper: FC = React.memo(({ pageDeps, routeList }) => { diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/security_windows/ml/v3_windows_anomalous_script.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/security_windows/ml/v3_windows_anomalous_script.json index 022695bcf5a7d9..af8bd86005dd92 100644 --- a/x-pack/plugins/ml/server/models/data_recognizer/modules/security_windows/ml/v3_windows_anomalous_script.json +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/security_windows/ml/v3_windows_anomalous_script.json @@ -21,7 +21,7 @@ "influencers": [ "host.name", "user.name", - "file.Path" + "file.path" ] }, "allow_lazy_open": true, diff --git a/x-pack/plugins/monitoring/public/application/hooks/use_breadcrumbs.ts b/x-pack/plugins/monitoring/public/application/hooks/use_breadcrumbs.ts index 95cae1720fd07f..7654e2d734e4c3 100644 --- a/x-pack/plugins/monitoring/public/application/hooks/use_breadcrumbs.ts +++ b/x-pack/plugins/monitoring/public/application/hooks/use_breadcrumbs.ts @@ -301,4 +301,4 @@ export const useBreadcrumbs = ({ history }: { history: History }) => { }; }; -export const BreadcrumbContainer = createContainer(useBreadcrumbs); +export const [BreadcrumbContainer, useBreadcrumbContainerContext] = createContainer(useBreadcrumbs); diff --git a/x-pack/plugins/monitoring/public/application/hooks/use_charts.tsx b/x-pack/plugins/monitoring/public/application/hooks/use_charts.tsx index c37fae742d0caa..f456b62312ec6d 100644 --- a/x-pack/plugins/monitoring/public/application/hooks/use_charts.tsx +++ b/x-pack/plugins/monitoring/public/application/hooks/use_charts.tsx @@ -5,15 +5,15 @@ * 2.0. */ import moment from 'moment'; -import { useContext, useState, useEffect, useRef } from 'react'; +import { useState, useEffect, useRef } from 'react'; import { useHistory } from 'react-router-dom'; import { useKibana } from '@kbn/kibana-react-plugin/public'; -import { MonitoringTimeContainer } from './use_monitoring_time'; +import { useMonitoringTimeContainerContext } from './use_monitoring_time'; export function useCharts() { const { services } = useKibana<{ data: any }>(); const history = useHistory(); - const { handleTimeChange } = useContext(MonitoringTimeContainer.Context); + const { handleTimeChange } = useMonitoringTimeContainerContext(); const [zoomInLevel, setZoomInLevel] = useState(0); diff --git a/x-pack/plugins/monitoring/public/application/hooks/use_monitoring_time.ts b/x-pack/plugins/monitoring/public/application/hooks/use_monitoring_time.ts index 13f40fc89a704c..74807fa957e6ac 100644 --- a/x-pack/plugins/monitoring/public/application/hooks/use_monitoring_time.ts +++ b/x-pack/plugins/monitoring/public/application/hooks/use_monitoring_time.ts @@ -75,4 +75,5 @@ export const useMonitoringTime = () => { }; }; -export const MonitoringTimeContainer = createContainer(useMonitoringTime); +export const [MonitoringTimeContainer, useMonitoringTimeContainerContext] = + createContainer(useMonitoringTime); diff --git a/x-pack/plugins/monitoring/public/application/index.tsx b/x-pack/plugins/monitoring/public/application/index.tsx index 3fd12c312d13fe..b3139928630238 100644 --- a/x-pack/plugins/monitoring/public/application/index.tsx +++ b/x-pack/plugins/monitoring/public/application/index.tsx @@ -107,8 +107,8 @@ const MonitoringApp: React.FC<{ uiSettings={core.uiSettings} > - - + + @@ -336,8 +336,8 @@ const MonitoringApp: React.FC<{ /> - - + + diff --git a/x-pack/plugins/monitoring/public/application/pages/apm/instance.tsx b/x-pack/plugins/monitoring/public/application/pages/apm/instance.tsx index 97f19f3cf92040..e4340d6fdaa67f 100644 --- a/x-pack/plugins/monitoring/public/application/pages/apm/instance.tsx +++ b/x-pack/plugins/monitoring/public/application/pages/apm/instance.tsx @@ -13,7 +13,7 @@ import { useKibana } from '@kbn/kibana-react-plugin/public'; import { ComponentProps } from '../../route_init'; import { GlobalStateContext } from '../../contexts/global_state_context'; import { useCharts } from '../../hooks/use_charts'; -import { BreadcrumbContainer } from '../../hooks/use_breadcrumbs'; +import { useBreadcrumbContainerContext } from '../../hooks/use_breadcrumbs'; import { PageTemplate } from '../page_template'; // @ts-ignore import { ApmServerInstance } from '../../../components/apm/instance'; @@ -23,7 +23,7 @@ export const ApmInstancePage: React.FC = ({ clusters }) => { const globalState = useContext(GlobalStateContext); const { services } = useKibana<{ data: any }>(); - const { generate: generateBreadcrumbs } = useContext(BreadcrumbContainer.Context); + const { generate: generateBreadcrumbs } = useBreadcrumbContainerContext(); const { zoomInfo, onBrush } = useCharts(); const clusterUuid = globalState.cluster_uuid; const ccs = globalState.ccs; diff --git a/x-pack/plugins/monitoring/public/application/pages/apm/instances.tsx b/x-pack/plugins/monitoring/public/application/pages/apm/instances.tsx index 29f6a1f9e056ee..e86ae43034af43 100644 --- a/x-pack/plugins/monitoring/public/application/pages/apm/instances.tsx +++ b/x-pack/plugins/monitoring/public/application/pages/apm/instances.tsx @@ -17,7 +17,7 @@ import { ApmTemplate } from './apm_template'; import { ApmServerInstances } from '../../../components/apm/instances'; import { SetupModeRenderer } from '../../../components/renderers/setup_mode'; import { SetupModeContext } from '../../../components/setup_mode/setup_mode_context'; -import { BreadcrumbContainer } from '../../hooks/use_breadcrumbs'; +import { useBreadcrumbContainerContext } from '../../hooks/use_breadcrumbs'; import { APM_SYSTEM_ID } from '../../../../common/constants'; interface SetupModeProps { @@ -29,7 +29,7 @@ interface SetupModeProps { export const ApmInstancesPage: React.FC = ({ clusters }) => { const globalState = useContext(GlobalStateContext); const { services } = useKibana<{ data: any }>(); - const { generate: generateBreadcrumbs } = useContext(BreadcrumbContainer.Context); + const { generate: generateBreadcrumbs } = useBreadcrumbContainerContext(); const { updateTotalItemCount, getPaginationTableProps } = useTable('apm.instances'); const clusterUuid = globalState.cluster_uuid; const ccs = globalState.ccs; diff --git a/x-pack/plugins/monitoring/public/application/pages/apm/overview.tsx b/x-pack/plugins/monitoring/public/application/pages/apm/overview.tsx index 1cf264daaeea36..39890954c877cd 100644 --- a/x-pack/plugins/monitoring/public/application/pages/apm/overview.tsx +++ b/x-pack/plugins/monitoring/public/application/pages/apm/overview.tsx @@ -13,7 +13,7 @@ import { ComponentProps } from '../../route_init'; import { ApmTemplate } from './apm_template'; import { GlobalStateContext } from '../../contexts/global_state_context'; import { useCharts } from '../../hooks/use_charts'; -import { BreadcrumbContainer } from '../../hooks/use_breadcrumbs'; +import { useBreadcrumbContainerContext } from '../../hooks/use_breadcrumbs'; // @ts-ignore import { ApmOverview } from '../../../components/apm/overview'; @@ -23,7 +23,7 @@ export const ApmOverviewPage: React.FC = ({ clusters }) => { const { services } = useKibana<{ data: any }>(); const clusterUuid = globalState.cluster_uuid; const ccs = globalState.ccs; - const { generate: generateBreadcrumbs } = useContext(BreadcrumbContainer.Context); + const { generate: generateBreadcrumbs } = useBreadcrumbContainerContext(); const cluster = find(clusters, { cluster_uuid: clusterUuid, }) as any; diff --git a/x-pack/plugins/monitoring/public/application/pages/beats/instance.tsx b/x-pack/plugins/monitoring/public/application/pages/beats/instance.tsx index 68345db40caf2b..f9b4794e44fed9 100644 --- a/x-pack/plugins/monitoring/public/application/pages/beats/instance.tsx +++ b/x-pack/plugins/monitoring/public/application/pages/beats/instance.tsx @@ -15,7 +15,7 @@ import { GlobalStateContext } from '../../contexts/global_state_context'; import { useCharts } from '../../hooks/use_charts'; // @ts-ignore import { Beat } from '../../../components/beats/beat'; -import { BreadcrumbContainer } from '../../hooks/use_breadcrumbs'; +import { useBreadcrumbContainerContext } from '../../hooks/use_breadcrumbs'; import { BeatsTemplate } from './beats_template'; export const BeatsInstancePage: React.FC = ({ clusters }) => { @@ -23,7 +23,7 @@ export const BeatsInstancePage: React.FC = ({ clusters }) => { const globalState = useContext(GlobalStateContext); const { services } = useKibana<{ data: any }>(); - const { generate: generateBreadcrumbs } = useContext(BreadcrumbContainer.Context); + const { generate: generateBreadcrumbs } = useBreadcrumbContainerContext(); const { zoomInfo, onBrush } = useCharts(); const clusterUuid = globalState.cluster_uuid; const ccs = globalState.ccs; diff --git a/x-pack/plugins/monitoring/public/application/pages/beats/instances.tsx b/x-pack/plugins/monitoring/public/application/pages/beats/instances.tsx index ea4f04151e83a0..6fce1668fc98a8 100644 --- a/x-pack/plugins/monitoring/public/application/pages/beats/instances.tsx +++ b/x-pack/plugins/monitoring/public/application/pages/beats/instances.tsx @@ -17,13 +17,13 @@ import { BeatsTemplate } from './beats_template'; import { Listing } from '../../../components/beats/listing'; import { SetupModeRenderer, SetupModeProps } from '../../../components/renderers/setup_mode'; import { SetupModeContext } from '../../../components/setup_mode/setup_mode_context'; -import { BreadcrumbContainer } from '../../hooks/use_breadcrumbs'; +import { useBreadcrumbContainerContext } from '../../hooks/use_breadcrumbs'; import { BEATS_SYSTEM_ID } from '../../../../common/constants'; export const BeatsInstancesPage: React.FC = ({ clusters }) => { const globalState = useContext(GlobalStateContext); const { services } = useKibana<{ data: any }>(); - const { generate: generateBreadcrumbs } = useContext(BreadcrumbContainer.Context); + const { generate: generateBreadcrumbs } = useBreadcrumbContainerContext(); const { updateTotalItemCount, getPaginationTableProps } = useTable('beats.instances'); const clusterUuid = globalState.cluster_uuid; const ccs = globalState.ccs; diff --git a/x-pack/plugins/monitoring/public/application/pages/beats/overview.tsx b/x-pack/plugins/monitoring/public/application/pages/beats/overview.tsx index 610fbe7ce2daf0..4a142a8abd4251 100644 --- a/x-pack/plugins/monitoring/public/application/pages/beats/overview.tsx +++ b/x-pack/plugins/monitoring/public/application/pages/beats/overview.tsx @@ -15,7 +15,7 @@ import { GlobalStateContext } from '../../contexts/global_state_context'; import { useCharts } from '../../hooks/use_charts'; // @ts-ignore import { BeatsOverview } from '../../../components/beats/overview'; -import { BreadcrumbContainer } from '../../hooks/use_breadcrumbs'; +import { useBreadcrumbContainerContext } from '../../hooks/use_breadcrumbs'; export const BeatsOverviewPage: React.FC = ({ clusters }) => { const globalState = useContext(GlobalStateContext); @@ -23,7 +23,7 @@ export const BeatsOverviewPage: React.FC = ({ clusters }) => { const { services } = useKibana<{ data: any }>(); const clusterUuid = globalState.cluster_uuid; const ccs = globalState.ccs; - const { generate: generateBreadcrumbs } = useContext(BreadcrumbContainer.Context); + const { generate: generateBreadcrumbs } = useBreadcrumbContainerContext(); const cluster = find(clusters, { cluster_uuid: clusterUuid, }) as any; diff --git a/x-pack/plugins/monitoring/public/application/pages/cluster/overview_page.tsx b/x-pack/plugins/monitoring/public/application/pages/cluster/overview_page.tsx index d128beee7ce876..993cabad38af0e 100644 --- a/x-pack/plugins/monitoring/public/application/pages/cluster/overview_page.tsx +++ b/x-pack/plugins/monitoring/public/application/pages/cluster/overview_page.tsx @@ -16,7 +16,7 @@ import { Overview } from '../../../components/cluster/overview'; import { ExternalConfigContext } from '../../contexts/external_config_context'; import { SetupModeRenderer, SetupModeProps } from '../../../components/renderers/setup_mode'; import { SetupModeContext } from '../../../components/setup_mode/setup_mode_context'; -import { BreadcrumbContainer } from '../../hooks/use_breadcrumbs'; +import { useBreadcrumbContainerContext } from '../../hooks/use_breadcrumbs'; import { fetchClusters } from '../../../lib/fetch_clusters'; import { AlertsByName } from '../../../alerts/types'; import { fetchAlerts } from '../../../lib/fetch_alerts'; @@ -33,7 +33,7 @@ export const ClusterOverview: React.FC<{}> = () => { const [clusters, setClusters] = useState([] as any); const [alerts, setAlerts] = useState({}); const [loaded, setLoaded] = useState(false); - const { generate: generateBreadcrumbs } = useContext(BreadcrumbContainer.Context); + const { generate: generateBreadcrumbs } = useBreadcrumbContainerContext(); let tabs: TabMenuItem[] = []; diff --git a/x-pack/plugins/monitoring/public/application/pages/elasticsearch/ccr_page.tsx b/x-pack/plugins/monitoring/public/application/pages/elasticsearch/ccr_page.tsx index cc0113acb3b5f3..9018d2ab2071d0 100644 --- a/x-pack/plugins/monitoring/public/application/pages/elasticsearch/ccr_page.tsx +++ b/x-pack/plugins/monitoring/public/application/pages/elasticsearch/ccr_page.tsx @@ -18,7 +18,7 @@ import { SetupModeContext } from '../../../components/setup_mode/setup_mode_cont import { AlertsByName } from '../../../alerts/types'; import { fetchAlerts } from '../../../lib/fetch_alerts'; import { ELASTICSEARCH_SYSTEM_ID, RULE_CCR_READ_EXCEPTIONS } from '../../../../common/constants'; -import { BreadcrumbContainer } from '../../hooks/use_breadcrumbs'; +import { useBreadcrumbContainerContext } from '../../hooks/use_breadcrumbs'; interface SetupModeProps { setupMode: any; flyoutComponent: any; @@ -27,7 +27,7 @@ interface SetupModeProps { export const ElasticsearchCcrPage: React.FC = ({ clusters }) => { const globalState = useContext(GlobalStateContext); - const { generate: generateBreadcrumbs } = useContext(BreadcrumbContainer.Context); + const { generate: generateBreadcrumbs } = useBreadcrumbContainerContext(); const { services } = useKibana<{ data: any }>(); const clusterUuid = globalState.cluster_uuid; diff --git a/x-pack/plugins/monitoring/public/application/pages/elasticsearch/ccr_shard_page.tsx b/x-pack/plugins/monitoring/public/application/pages/elasticsearch/ccr_shard_page.tsx index 925baa5edd052b..3db3c25fd1f39b 100644 --- a/x-pack/plugins/monitoring/public/application/pages/elasticsearch/ccr_shard_page.tsx +++ b/x-pack/plugins/monitoring/public/application/pages/elasticsearch/ccr_shard_page.tsx @@ -20,7 +20,7 @@ import { SetupModeContext } from '../../../components/setup_mode/setup_mode_cont import { AlertsByName } from '../../../alerts/types'; import { fetchAlerts } from '../../../lib/fetch_alerts'; import { ELASTICSEARCH_SYSTEM_ID, RULE_CCR_READ_EXCEPTIONS } from '../../../../common/constants'; -import { BreadcrumbContainer } from '../../hooks/use_breadcrumbs'; +import { useBreadcrumbContainerContext } from '../../hooks/use_breadcrumbs'; interface SetupModeProps { setupMode: any; @@ -33,7 +33,7 @@ export const ElasticsearchCcrShardPage: React.FC = ({ clusters } const { services } = useKibana<{ data: any }>(); const [data, setData] = useState({} as any); const { index, shardId }: { index: string; shardId: string } = useParams(); - const { generate: generateBreadcrumbs } = useContext(BreadcrumbContainer.Context); + const { generate: generateBreadcrumbs } = useBreadcrumbContainerContext(); const clusterUuid = globalState.cluster_uuid; const cluster = find(clusters, { diff --git a/x-pack/plugins/monitoring/public/application/pages/elasticsearch/index_advanced_page.tsx b/x-pack/plugins/monitoring/public/application/pages/elasticsearch/index_advanced_page.tsx index 410a909a9c4ab8..0dab4a4d4bc52f 100644 --- a/x-pack/plugins/monitoring/public/application/pages/elasticsearch/index_advanced_page.tsx +++ b/x-pack/plugins/monitoring/public/application/pages/elasticsearch/index_advanced_page.tsx @@ -20,11 +20,11 @@ import { AdvancedIndex } from '../../../components/elasticsearch/index/advanced' import { AlertsByName } from '../../../alerts/types'; import { fetchAlerts } from '../../../lib/fetch_alerts'; import { ELASTICSEARCH_SYSTEM_ID, RULE_LARGE_SHARD_SIZE } from '../../../../common/constants'; -import { BreadcrumbContainer } from '../../hooks/use_breadcrumbs'; +import { useBreadcrumbContainerContext } from '../../hooks/use_breadcrumbs'; export const ElasticsearchIndexAdvancedPage: React.FC = ({ clusters }) => { const globalState = useContext(GlobalStateContext); - const { generate: generateBreadcrumbs } = useContext(BreadcrumbContainer.Context); + const { generate: generateBreadcrumbs } = useBreadcrumbContainerContext(); const { services } = useKibana<{ data: any }>(); const { index }: { index: string } = useParams(); const { zoomInfo, onBrush } = useCharts(); diff --git a/x-pack/plugins/monitoring/public/application/pages/elasticsearch/index_page.tsx b/x-pack/plugins/monitoring/public/application/pages/elasticsearch/index_page.tsx index dc2f718e647005..73c32fe0a42f34 100644 --- a/x-pack/plugins/monitoring/public/application/pages/elasticsearch/index_page.tsx +++ b/x-pack/plugins/monitoring/public/application/pages/elasticsearch/index_page.tsx @@ -24,11 +24,11 @@ import { labels } from '../../../components/elasticsearch/shard_allocation/lib/l import { AlertsByName } from '../../../alerts/types'; import { fetchAlerts } from '../../../lib/fetch_alerts'; import { ELASTICSEARCH_SYSTEM_ID, RULE_LARGE_SHARD_SIZE } from '../../../../common/constants'; -import { BreadcrumbContainer } from '../../hooks/use_breadcrumbs'; +import { useBreadcrumbContainerContext } from '../../hooks/use_breadcrumbs'; export const ElasticsearchIndexPage: React.FC = ({ clusters }) => { const globalState = useContext(GlobalStateContext); - const { generate: generateBreadcrumbs } = useContext(BreadcrumbContainer.Context); + const { generate: generateBreadcrumbs } = useBreadcrumbContainerContext(); const { services } = useKibana<{ data: any }>(); const { index }: { index: string } = useParams(); const { zoomInfo, onBrush } = useCharts(); diff --git a/x-pack/plugins/monitoring/public/application/pages/elasticsearch/indices_page.tsx b/x-pack/plugins/monitoring/public/application/pages/elasticsearch/indices_page.tsx index d14015532167ef..49be26854571ec 100644 --- a/x-pack/plugins/monitoring/public/application/pages/elasticsearch/indices_page.tsx +++ b/x-pack/plugins/monitoring/public/application/pages/elasticsearch/indices_page.tsx @@ -19,11 +19,11 @@ import { useLocalStorage } from '../../hooks/use_local_storage'; import { AlertsByName } from '../../../alerts/types'; import { fetchAlerts } from '../../../lib/fetch_alerts'; import { ELASTICSEARCH_SYSTEM_ID, RULE_LARGE_SHARD_SIZE } from '../../../../common/constants'; -import { BreadcrumbContainer } from '../../hooks/use_breadcrumbs'; +import { useBreadcrumbContainerContext } from '../../hooks/use_breadcrumbs'; export const ElasticsearchIndicesPage: React.FC = ({ clusters }) => { const globalState = useContext(GlobalStateContext); - const { generate: generateBreadcrumbs } = useContext(BreadcrumbContainer.Context); + const { generate: generateBreadcrumbs } = useBreadcrumbContainerContext(); const { services } = useKibana<{ data: any }>(); const { getPaginationTableProps } = useTable('elasticsearch.indices'); const clusterUuid = globalState.cluster_uuid; diff --git a/x-pack/plugins/monitoring/public/application/pages/elasticsearch/ml_jobs_page.tsx b/x-pack/plugins/monitoring/public/application/pages/elasticsearch/ml_jobs_page.tsx index 5c7fd227a0a53d..0f9fe473ae4aff 100644 --- a/x-pack/plugins/monitoring/public/application/pages/elasticsearch/ml_jobs_page.tsx +++ b/x-pack/plugins/monitoring/public/application/pages/elasticsearch/ml_jobs_page.tsx @@ -16,7 +16,7 @@ import { SetupModeRenderer } from '../../../components/renderers/setup_mode'; import { SetupModeContext } from '../../../components/setup_mode/setup_mode_context'; import { useTable } from '../../hooks/use_table'; import type { MLJobs } from '../../../types'; -import { BreadcrumbContainer } from '../../hooks/use_breadcrumbs'; +import { useBreadcrumbContainerContext } from '../../hooks/use_breadcrumbs'; import { ELASTICSEARCH_SYSTEM_ID } from '../../../../common/constants'; interface SetupModeProps { @@ -27,7 +27,7 @@ interface SetupModeProps { export const ElasticsearchMLJobsPage: React.FC = ({ clusters }) => { const globalState = useContext(GlobalStateContext); - const { generate: generateBreadcrumbs } = useContext(BreadcrumbContainer.Context); + const { generate: generateBreadcrumbs } = useBreadcrumbContainerContext(); const { services } = useKibana<{ data: any }>(); const { getPaginationTableProps } = useTable('elasticsearch.mlJobs'); const clusterUuid = globalState.cluster_uuid; diff --git a/x-pack/plugins/monitoring/public/application/pages/elasticsearch/node_advanced_page.tsx b/x-pack/plugins/monitoring/public/application/pages/elasticsearch/node_advanced_page.tsx index 05394a6d36aec8..bf4b6c48b551e2 100644 --- a/x-pack/plugins/monitoring/public/application/pages/elasticsearch/node_advanced_page.tsx +++ b/x-pack/plugins/monitoring/public/application/pages/elasticsearch/node_advanced_page.tsx @@ -25,11 +25,11 @@ import { RULE_DISK_USAGE, RULE_MEMORY_USAGE, } from '../../../../common/constants'; -import { BreadcrumbContainer } from '../../hooks/use_breadcrumbs'; +import { useBreadcrumbContainerContext } from '../../hooks/use_breadcrumbs'; export const ElasticsearchNodeAdvancedPage: React.FC = ({ clusters }) => { const globalState = useContext(GlobalStateContext); - const { generate: generateBreadcrumbs } = useContext(BreadcrumbContainer.Context); + const { generate: generateBreadcrumbs } = useBreadcrumbContainerContext(); const { zoomInfo, onBrush } = useCharts(); const [data, setData] = useState({} as any); diff --git a/x-pack/plugins/monitoring/public/application/pages/elasticsearch/node_page.tsx b/x-pack/plugins/monitoring/public/application/pages/elasticsearch/node_page.tsx index e41e921985015b..b6682a2da876d0 100644 --- a/x-pack/plugins/monitoring/public/application/pages/elasticsearch/node_page.tsx +++ b/x-pack/plugins/monitoring/public/application/pages/elasticsearch/node_page.tsx @@ -31,11 +31,11 @@ import { RULE_DISK_USAGE, RULE_MEMORY_USAGE, } from '../../../../common/constants'; -import { BreadcrumbContainer } from '../../hooks/use_breadcrumbs'; +import { useBreadcrumbContainerContext } from '../../hooks/use_breadcrumbs'; export const ElasticsearchNodePage: React.FC = ({ clusters }) => { const globalState = useContext(GlobalStateContext); - const { generate: generateBreadcrumbs } = useContext(BreadcrumbContainer.Context); + const { generate: generateBreadcrumbs } = useBreadcrumbContainerContext(); const { zoomInfo, onBrush } = useCharts(); const [showSystemIndices, setShowSystemIndices] = useLocalStorage( 'showSystemIndices', diff --git a/x-pack/plugins/monitoring/public/application/pages/elasticsearch/nodes_page.tsx b/x-pack/plugins/monitoring/public/application/pages/elasticsearch/nodes_page.tsx index 156d8463b80beb..b258361474a611 100644 --- a/x-pack/plugins/monitoring/public/application/pages/elasticsearch/nodes_page.tsx +++ b/x-pack/plugins/monitoring/public/application/pages/elasticsearch/nodes_page.tsx @@ -16,7 +16,7 @@ import { ComponentProps } from '../../route_init'; import { SetupModeRenderer, SetupModeProps } from '../../../components/renderers/setup_mode'; import { SetupModeContext } from '../../../components/setup_mode/setup_mode_context'; import { useTable } from '../../hooks/use_table'; -import { BreadcrumbContainer } from '../../hooks/use_breadcrumbs'; +import { useBreadcrumbContainerContext } from '../../hooks/use_breadcrumbs'; import { AlertsByName } from '../../../alerts/types'; import { fetchAlerts } from '../../../lib/fetch_alerts'; import { @@ -34,7 +34,7 @@ export const ElasticsearchNodesPage: React.FC = ({ clusters }) = const { showCgroupMetricsElasticsearch } = useContext(ExternalConfigContext); const { services } = useKibana<{ data: any }>(); const [isLoading, setIsLoading] = React.useState(false); - const { generate: generateBreadcrumbs } = useContext(BreadcrumbContainer.Context); + const { generate: generateBreadcrumbs } = useBreadcrumbContainerContext(); const { getPaginationRouteOptions, updateTotalItemCount, getPaginationTableProps } = useTable('elasticsearch.nodes'); const clusterUuid = globalState.cluster_uuid; diff --git a/x-pack/plugins/monitoring/public/application/pages/elasticsearch/overview.tsx b/x-pack/plugins/monitoring/public/application/pages/elasticsearch/overview.tsx index c4524bb1610409..4e213405cfd080 100644 --- a/x-pack/plugins/monitoring/public/application/pages/elasticsearch/overview.tsx +++ b/x-pack/plugins/monitoring/public/application/pages/elasticsearch/overview.tsx @@ -14,13 +14,13 @@ import { GlobalStateContext } from '../../contexts/global_state_context'; import { ElasticsearchOverview } from '../../../components/elasticsearch'; import { ComponentProps } from '../../route_init'; import { useCharts } from '../../hooks/use_charts'; -import { BreadcrumbContainer } from '../../hooks/use_breadcrumbs'; +import { useBreadcrumbContainerContext } from '../../hooks/use_breadcrumbs'; export const ElasticsearchOverviewPage: React.FC = ({ clusters }) => { const globalState = useContext(GlobalStateContext); const { zoomInfo, onBrush } = useCharts(); const { services } = useKibana<{ data: any }>(); - const { generate: generateBreadcrumbs } = useContext(BreadcrumbContainer.Context); + const { generate: generateBreadcrumbs } = useBreadcrumbContainerContext(); const clusterUuid = globalState.cluster_uuid; const ccs = globalState.ccs; const cluster = find(clusters, { diff --git a/x-pack/plugins/monitoring/public/application/pages/enterprise_search/overview.tsx b/x-pack/plugins/monitoring/public/application/pages/enterprise_search/overview.tsx index 75d2d2f89fae14..0cd97166dcf5d5 100644 --- a/x-pack/plugins/monitoring/public/application/pages/enterprise_search/overview.tsx +++ b/x-pack/plugins/monitoring/public/application/pages/enterprise_search/overview.tsx @@ -14,7 +14,7 @@ import { EntSearchTemplate } from './ent_search_template'; import { GlobalStateContext } from '../../contexts/global_state_context'; import { useCharts } from '../../hooks/use_charts'; import { EnterpriseSearchOverview } from '../../../components/enterprise_search/overview'; -import { BreadcrumbContainer } from '../../hooks/use_breadcrumbs'; +import { useBreadcrumbContainerContext } from '../../hooks/use_breadcrumbs'; export const EntSearchOverviewPage: React.FC = ({ clusters }) => { const globalState = useContext(GlobalStateContext); @@ -22,7 +22,7 @@ export const EntSearchOverviewPage: React.FC = ({ clusters }) => const { services } = useKibana<{ data: any }>(); const clusterUuid = globalState.cluster_uuid; const ccs = globalState.ccs; - const { generate: generateBreadcrumbs } = useContext(BreadcrumbContainer.Context); + const { generate: generateBreadcrumbs } = useBreadcrumbContainerContext(); const cluster = find(clusters, { cluster_uuid: clusterUuid, }) as any; diff --git a/x-pack/plugins/monitoring/public/application/pages/home/cluster_listing.tsx b/x-pack/plugins/monitoring/public/application/pages/home/cluster_listing.tsx index 80c46342294f51..45ed6172d42622 100644 --- a/x-pack/plugins/monitoring/public/application/pages/home/cluster_listing.tsx +++ b/x-pack/plugins/monitoring/public/application/pages/home/cluster_listing.tsx @@ -17,7 +17,7 @@ import { ExternalConfigContext } from '../../contexts/external_config_context'; import { ComponentProps } from '../../route_init'; import { useTable } from '../../hooks/use_table'; import { PageTemplate, TabMenuItem } from '../page_template'; -import { BreadcrumbContainer } from '../../hooks/use_breadcrumbs'; +import { useBreadcrumbContainerContext } from '../../hooks/use_breadcrumbs'; import { fetchClusters } from '../../../lib/fetch_clusters'; const pageTitle = i18n.translate('xpack.monitoring.cluster.listing.pageTitle', { @@ -40,7 +40,7 @@ export const ClusterListing: React.FC = () => { const externalConfig = useContext(ExternalConfigContext); const { services } = useKibana<{ data: any }>(); const [clusters, setClusters] = useState([] as any); - const { update: updateBreadcrumbs } = useContext(BreadcrumbContainer.Context); + const { update: updateBreadcrumbs } = useBreadcrumbContainerContext(); const fakeScope = { $evalAsync: (fn: () => void) => fn(), diff --git a/x-pack/plugins/monitoring/public/application/pages/kibana/instance.tsx b/x-pack/plugins/monitoring/public/application/pages/kibana/instance.tsx index c1dfecd69d2a89..56d8b6742c2824 100644 --- a/x-pack/plugins/monitoring/public/application/pages/kibana/instance.tsx +++ b/x-pack/plugins/monitoring/public/application/pages/kibana/instance.tsx @@ -23,7 +23,7 @@ import { ComponentProps } from '../../route_init'; import { GlobalStateContext } from '../../contexts/global_state_context'; import { useCharts } from '../../hooks/use_charts'; // @ts-ignore -import { BreadcrumbContainer } from '../../hooks/use_breadcrumbs'; +import { useBreadcrumbContainerContext } from '../../hooks/use_breadcrumbs'; // @ts-ignore import { MonitoringTimeseriesContainer } from '../../../components/chart'; // @ts-ignore @@ -148,7 +148,7 @@ export const KibanaInstancePage: React.FC = ({ clusters }) => { const globalState = useContext(GlobalStateContext); const { services } = useKibana<{ data: any }>(); - const { generate: generateBreadcrumbs } = useContext(BreadcrumbContainer.Context); + const { generate: generateBreadcrumbs } = useBreadcrumbContainerContext(); const clusterUuid = globalState.cluster_uuid; const ccs = globalState.ccs; const cluster = find(clusters, { diff --git a/x-pack/plugins/monitoring/public/application/pages/kibana/instances.tsx b/x-pack/plugins/monitoring/public/application/pages/kibana/instances.tsx index 6f1f822b8488f6..5d272be8be30c0 100644 --- a/x-pack/plugins/monitoring/public/application/pages/kibana/instances.tsx +++ b/x-pack/plugins/monitoring/public/application/pages/kibana/instances.tsx @@ -18,7 +18,7 @@ import { KibanaInstances } from '../../../components/kibana/instances'; // @ts-ignore import { SetupModeRenderer, SetupModeProps } from '../../../components/renderers/setup_mode'; import { SetupModeContext } from '../../../components/setup_mode/setup_mode_context'; -import { BreadcrumbContainer } from '../../hooks/use_breadcrumbs'; +import { useBreadcrumbContainerContext } from '../../hooks/use_breadcrumbs'; import { AlertsByName } from '../../../alerts/types'; import { fetchAlerts } from '../../../lib/fetch_alerts'; import { KIBANA_SYSTEM_ID, RULE_KIBANA_VERSION_MISMATCH } from '../../../../common/constants'; @@ -26,7 +26,7 @@ import { KIBANA_SYSTEM_ID, RULE_KIBANA_VERSION_MISMATCH } from '../../../../comm export const KibanaInstancesPage: React.FC = ({ clusters }) => { const { cluster_uuid: clusterUuid, ccs } = useContext(GlobalStateContext); const { services } = useKibana<{ data: any }>(); - const { generate: generateBreadcrumbs } = useContext(BreadcrumbContainer.Context); + const { generate: generateBreadcrumbs } = useBreadcrumbContainerContext(); const { updateTotalItemCount, getPaginationTableProps } = useTable('kibana.instances'); const cluster = find(clusters, { cluster_uuid: clusterUuid, diff --git a/x-pack/plugins/monitoring/public/application/pages/kibana/overview.tsx b/x-pack/plugins/monitoring/public/application/pages/kibana/overview.tsx index 5ae89fd929eb45..dd31acec85e118 100644 --- a/x-pack/plugins/monitoring/public/application/pages/kibana/overview.tsx +++ b/x-pack/plugins/monitoring/public/application/pages/kibana/overview.tsx @@ -25,7 +25,7 @@ import { ComponentProps } from '../../route_init'; import { MonitoringTimeseriesContainer } from '../../../components/chart'; // @ts-ignore import { ClusterStatus } from '../../../components/kibana/cluster_status'; -import { BreadcrumbContainer } from '../../hooks/use_breadcrumbs'; +import { useBreadcrumbContainerContext } from '../../hooks/use_breadcrumbs'; import { useCharts } from '../../hooks/use_charts'; const KibanaOverview = ({ data }: { data: any }) => { @@ -107,7 +107,7 @@ const KibanaOverview = ({ data }: { data: any }) => { export const KibanaOverviewPage: React.FC = ({ clusters }) => { const globalState = useContext(GlobalStateContext); const { services } = useKibana<{ data: any }>(); - const { generate: generateBreadcrumbs } = useContext(BreadcrumbContainer.Context); + const { generate: generateBreadcrumbs } = useBreadcrumbContainerContext(); const [data, setData] = useState(); const clusterUuid = globalState.cluster_uuid; const cluster = find(clusters, { diff --git a/x-pack/plugins/monitoring/public/application/pages/license_page.tsx b/x-pack/plugins/monitoring/public/application/pages/license_page.tsx index 2f0e424d142388..b7288ce1b872ba 100644 --- a/x-pack/plugins/monitoring/public/application/pages/license_page.tsx +++ b/x-pack/plugins/monitoring/public/application/pages/license_page.tsx @@ -13,7 +13,7 @@ import { PageTemplate } from './page_template'; import { License } from '../../components'; import { GlobalStateContext } from '../contexts/global_state_context'; import { CODE_PATH_LICENSE, STANDALONE_CLUSTER_CLUSTER_UUID } from '../../../common/constants'; -import { MonitoringTimeContainer } from '../hooks/use_monitoring_time'; +import { useMonitoringTimeContainerContext } from '../hooks/use_monitoring_time'; const CODE_PATHS = [CODE_PATH_LICENSE]; @@ -22,7 +22,7 @@ export const LicensePage: React.FC<{}> = () => { defaultMessage: 'License', }); - const { setIsDisabled } = useContext(MonitoringTimeContainer.Context); + const { setIsDisabled } = useMonitoringTimeContainerContext(); useEffect(() => { setIsDisabled(true); return () => { diff --git a/x-pack/plugins/monitoring/public/application/pages/logstash/advanced.tsx b/x-pack/plugins/monitoring/public/application/pages/logstash/advanced.tsx index 29b2e4f6c1e443..f89d7b5df37266 100644 --- a/x-pack/plugins/monitoring/public/application/pages/logstash/advanced.tsx +++ b/x-pack/plugins/monitoring/public/application/pages/logstash/advanced.tsx @@ -30,7 +30,7 @@ import { useCharts } from '../../hooks/use_charts'; import { AlertsByName } from '../../../alerts/types'; import { fetchAlerts } from '../../../lib/fetch_alerts'; import { RULE_LOGSTASH_VERSION_MISMATCH } from '../../../../common/constants'; -import { BreadcrumbContainer } from '../../hooks/use_breadcrumbs'; +import { useBreadcrumbContainerContext } from '../../hooks/use_breadcrumbs'; export const LogStashNodeAdvancedPage: React.FC = ({ clusters }) => { const globalState = useContext(GlobalStateContext); @@ -43,7 +43,7 @@ export const LogStashNodeAdvancedPage: React.FC = ({ clusters }) cluster_uuid: clusterUuid, }) as any; - const { generate: generateBreadcrumbs } = useContext(BreadcrumbContainer.Context); + const { generate: generateBreadcrumbs } = useBreadcrumbContainerContext(); const [data, setData] = useState({} as any); const [alerts, setAlerts] = useState({}); diff --git a/x-pack/plugins/monitoring/public/application/pages/logstash/node.tsx b/x-pack/plugins/monitoring/public/application/pages/logstash/node.tsx index 772bf5718c4ec3..75d752b696fd93 100644 --- a/x-pack/plugins/monitoring/public/application/pages/logstash/node.tsx +++ b/x-pack/plugins/monitoring/public/application/pages/logstash/node.tsx @@ -31,13 +31,13 @@ import { useCharts } from '../../hooks/use_charts'; import { AlertsByName } from '../../../alerts/types'; import { fetchAlerts } from '../../../lib/fetch_alerts'; import { RULE_LOGSTASH_VERSION_MISMATCH } from '../../../../common/constants'; -import { BreadcrumbContainer } from '../../hooks/use_breadcrumbs'; +import { useBreadcrumbContainerContext } from '../../hooks/use_breadcrumbs'; export const LogStashNodePage: React.FC = ({ clusters }) => { const match = useRouteMatch<{ uuid: string | undefined }>(); const globalState = useContext(GlobalStateContext); const { services } = useKibana<{ data: any }>(); - const { generate: generateBreadcrumbs } = useContext(BreadcrumbContainer.Context); + const { generate: generateBreadcrumbs } = useBreadcrumbContainerContext(); const clusterUuid = globalState.cluster_uuid; const ccs = globalState.ccs; const cluster = find(clusters, { diff --git a/x-pack/plugins/monitoring/public/application/pages/logstash/node_pipelines.tsx b/x-pack/plugins/monitoring/public/application/pages/logstash/node_pipelines.tsx index 90c8421a31eb00..6c97661e915cbd 100644 --- a/x-pack/plugins/monitoring/public/application/pages/logstash/node_pipelines.tsx +++ b/x-pack/plugins/monitoring/public/application/pages/logstash/node_pipelines.tsx @@ -20,7 +20,7 @@ import { useTable } from '../../hooks/use_table'; // @ts-expect-error import { PipelineListing } from '../../../components/logstash/pipeline_listing/pipeline_listing'; import { useCharts } from '../../hooks/use_charts'; -import { BreadcrumbContainer } from '../../hooks/use_breadcrumbs'; +import { useBreadcrumbContainerContext } from '../../hooks/use_breadcrumbs'; export const LogStashNodePipelinesPage: React.FC = ({ clusters }) => { const globalState = useContext(GlobalStateContext); @@ -33,7 +33,7 @@ export const LogStashNodePipelinesPage: React.FC = ({ clusters } cluster_uuid: clusterUuid, }) as any; - const { generate: generateBreadcrumbs } = useContext(BreadcrumbContainer.Context); + const { generate: generateBreadcrumbs } = useBreadcrumbContainerContext(); const { getPaginationTableProps, getPaginationRouteOptions, updateTotalItemCount } = useTable('logstash.pipelines'); diff --git a/x-pack/plugins/monitoring/public/application/pages/logstash/nodes.tsx b/x-pack/plugins/monitoring/public/application/pages/logstash/nodes.tsx index b350f057aae96d..d3097ecc4a1458 100644 --- a/x-pack/plugins/monitoring/public/application/pages/logstash/nodes.tsx +++ b/x-pack/plugins/monitoring/public/application/pages/logstash/nodes.tsx @@ -19,7 +19,7 @@ import { useTable } from '../../hooks/use_table'; import { LOGSTASH_SYSTEM_ID, RULE_LOGSTASH_VERSION_MISMATCH } from '../../../../common/constants'; import { AlertsByName } from '../../../alerts/types'; import { fetchAlerts } from '../../../lib/fetch_alerts'; -import { BreadcrumbContainer } from '../../hooks/use_breadcrumbs'; +import { useBreadcrumbContainerContext } from '../../hooks/use_breadcrumbs'; interface SetupModeProps { setupMode: any; @@ -32,7 +32,7 @@ export const LogStashNodesPage: React.FC = ({ clusters }) => { const { services } = useKibana<{ data: any }>(); const clusterUuid = globalState.cluster_uuid; const ccs = globalState.ccs; - const { generate: generateBreadcrumbs } = useContext(BreadcrumbContainer.Context); + const { generate: generateBreadcrumbs } = useBreadcrumbContainerContext(); const cluster = find(clusters, { cluster_uuid: clusterUuid, }) as any; diff --git a/x-pack/plugins/monitoring/public/application/pages/logstash/overview.tsx b/x-pack/plugins/monitoring/public/application/pages/logstash/overview.tsx index e8b9dda7587136..20e7339e2b580e 100644 --- a/x-pack/plugins/monitoring/public/application/pages/logstash/overview.tsx +++ b/x-pack/plugins/monitoring/public/application/pages/logstash/overview.tsx @@ -14,7 +14,7 @@ import { useCharts } from '../../hooks/use_charts'; // @ts-ignore import { Overview } from '../../../components/logstash/overview'; import { LogstashTemplate } from './logstash_template'; -import { BreadcrumbContainer } from '../../hooks/use_breadcrumbs'; +import { useBreadcrumbContainerContext } from '../../hooks/use_breadcrumbs'; export const LogStashOverviewPage: React.FC = ({ clusters }) => { const globalState = useContext(GlobalStateContext); @@ -25,7 +25,7 @@ export const LogStashOverviewPage: React.FC = ({ clusters }) => const cluster = find(clusters, { cluster_uuid: clusterUuid, }) as any; - const { generate: generateBreadcrumbs } = useContext(BreadcrumbContainer.Context); + const { generate: generateBreadcrumbs } = useBreadcrumbContainerContext(); const [data, setData] = useState(null); // const [showShardActivityHistory, setShowShardActivityHistory] = useState(false); diff --git a/x-pack/plugins/monitoring/public/application/pages/logstash/pipeline.tsx b/x-pack/plugins/monitoring/public/application/pages/logstash/pipeline.tsx index af68390aa4e769..c3c229458da089 100644 --- a/x-pack/plugins/monitoring/public/application/pages/logstash/pipeline.tsx +++ b/x-pack/plugins/monitoring/public/application/pages/logstash/pipeline.tsx @@ -29,7 +29,7 @@ import { formatTimestampToDuration } from '../../../../common'; import { CALCULATE_DURATION_SINCE } from '../../../../common/constants'; import { getSafeForExternalLink } from '../../../lib/get_safe_for_external_link'; import { PipelineVersions } from './pipeline_versions_dropdown'; -import { BreadcrumbContainer } from '../../hooks/use_breadcrumbs'; +import { useBreadcrumbContainerContext } from '../../hooks/use_breadcrumbs'; export const LogStashPipelinePage: React.FC = ({ clusters }) => { const match = useRouteMatch<{ id: string | undefined; hash: string | undefined }>(); @@ -126,7 +126,7 @@ export const LogStashPipelinePage: React.FC = ({ clusters }) => }, [data]); const timeseriesTooltipXValueFormatter = (xValue: any) => moment(xValue).format(dateFormat); - const { generate: generateBreadcrumbs } = useContext(BreadcrumbContainer.Context); + const { generate: generateBreadcrumbs } = useBreadcrumbContainerContext(); const onVertexChange = useCallback((vertex: any) => { if (!vertex) { diff --git a/x-pack/plugins/monitoring/public/application/pages/logstash/pipelines.tsx b/x-pack/plugins/monitoring/public/application/pages/logstash/pipelines.tsx index a669b06ac8bcf7..19d5277f1a85a4 100644 --- a/x-pack/plugins/monitoring/public/application/pages/logstash/pipelines.tsx +++ b/x-pack/plugins/monitoring/public/application/pages/logstash/pipelines.tsx @@ -17,7 +17,7 @@ import { isPipelineMonitoringSupportedInVersion } from '../../../lib/logstash/pi import { PipelineListing } from '../../../components/logstash/pipeline_listing/pipeline_listing'; import { LogstashTemplate } from './logstash_template'; import { useTable } from '../../hooks/use_table'; -import { BreadcrumbContainer } from '../../hooks/use_breadcrumbs'; +import { useBreadcrumbContainerContext } from '../../hooks/use_breadcrumbs'; export const LogStashPipelinesPage: React.FC = ({ clusters }) => { const globalState = useContext(GlobalStateContext); @@ -43,7 +43,7 @@ export const LogStashPipelinesPage: React.FC = ({ clusters }) => defaultMessage: 'Logstash pipelines', }); - const { generate: generateBreadcrumbs } = useContext(BreadcrumbContainer.Context); + const { generate: generateBreadcrumbs } = useBreadcrumbContainerContext(); const getPageData = useCallback(async () => { const bounds = services.data?.query.timefilter.timefilter.getBounds(); diff --git a/x-pack/plugins/monitoring/public/application/pages/no_data/no_data_page.tsx b/x-pack/plugins/monitoring/public/application/pages/no_data/no_data_page.tsx index d0806c1d86c026..ef6707a61d359f 100644 --- a/x-pack/plugins/monitoring/public/application/pages/no_data/no_data_page.tsx +++ b/x-pack/plugins/monitoring/public/application/pages/no_data/no_data_page.tsx @@ -16,7 +16,7 @@ import { PageTemplate } from '../page_template'; import { CODE_PATH_LICENSE, STANDALONE_CLUSTER_CLUSTER_UUID } from '../../../../common/constants'; import { Legacy } from '../../../legacy_shims'; import { Enabler } from './enabler'; -import { BreadcrumbContainer } from '../../hooks/use_breadcrumbs'; +import { useBreadcrumbContainerContext } from '../../hooks/use_breadcrumbs'; import { initSetupModeState } from '../../../lib/setup_mode'; import { GlobalStateContext } from '../../contexts/global_state_context'; import { useRequestErrorHandler } from '../../hooks/use_request_error_handler'; @@ -67,7 +67,7 @@ export const NoDataPage = () => { isCollectionIntervalUpdated: false, } as any); - const { update: updateBreadcrumbs } = useContext(BreadcrumbContainer.Context); + const { update: updateBreadcrumbs } = useBreadcrumbContainerContext(); updateBreadcrumbs([ { 'data-test-subj': 'breadcrumbClusters', diff --git a/x-pack/plugins/monitoring/public/application/pages/page_template.tsx b/x-pack/plugins/monitoring/public/application/pages/page_template.tsx index 8e07d196ce5880..842c86cc4ab957 100644 --- a/x-pack/plugins/monitoring/public/application/pages/page_template.tsx +++ b/x-pack/plugins/monitoring/public/application/pages/page_template.tsx @@ -20,7 +20,7 @@ import type { IHttpFetchError, ResponseErrorBody } from '@kbn/core-http-browser' import { HeaderMenuPortal } from '@kbn/observability-plugin/public'; import { useTitle } from '../hooks/use_title'; import { MonitoringToolbar } from '../../components/shared/toolbar'; -import { MonitoringTimeContainer } from '../hooks/use_monitoring_time'; +import { useMonitoringTimeContainerContext } from '../hooks/use_monitoring_time'; import { PageLoading } from '../../components'; import { getSetupModeState, @@ -58,7 +58,7 @@ export const PageTemplate: React.FC = ({ }) => { useTitle('', title); - const { currentTimerange } = useContext(MonitoringTimeContainer.Context); + const { currentTimerange } = useMonitoringTimeContainerContext(); const [loaded, setLoaded] = useState(false); const [isRequestPending, setIsRequestPending] = useState(false); const history = useHistory(); diff --git a/x-pack/plugins/monitoring/public/components/shared/toolbar.tsx b/x-pack/plugins/monitoring/public/components/shared/toolbar.tsx index 200ce9f8494331..ae90a304a019f9 100644 --- a/x-pack/plugins/monitoring/public/components/shared/toolbar.tsx +++ b/x-pack/plugins/monitoring/public/components/shared/toolbar.tsx @@ -9,7 +9,7 @@ import { EuiPageHeader, EuiSuperDatePicker, OnRefreshChangeProps } from '@elasti import React, { useContext, useCallback, useMemo } from 'react'; import { useKibana } from '@kbn/kibana-react-plugin/public'; import { UI_SETTINGS } from '@kbn/data-plugin/common'; -import { MonitoringTimeContainer } from '../../application/hooks/use_monitoring_time'; +import { useMonitoringTimeContainerContext } from '../../application/hooks/use_monitoring_time'; import { GlobalStateContext } from '../../application/contexts/global_state_context'; import { Legacy } from '../../legacy_shims'; import { MonitoringStartServices } from '../../types'; @@ -49,7 +49,7 @@ export const MonitoringToolbar: React.FC = ({ pageTitle, setIsPaused, isPaused, isDisabled, - } = useContext(MonitoringTimeContainer.Context); + } = useMonitoringTimeContainerContext(); const state = useContext(GlobalStateContext); const onTimeChange = useCallback( diff --git a/x-pack/plugins/monitoring/public/components/table/storage.ts b/x-pack/plugins/monitoring/public/components/table/storage.ts index 7d4d3129650ae0..3c28be3fe6114e 100644 --- a/x-pack/plugins/monitoring/public/components/table/storage.ts +++ b/x-pack/plugins/monitoring/public/components/table/storage.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { set } from '@elastic/safer-lodash-set'; +import { set } from '@kbn/safer-lodash-set'; import { get } from 'lodash'; import { Storage } from '@kbn/kibana-utils-plugin/public'; import { STORAGE_KEY } from '../../../common/constants'; diff --git a/x-pack/plugins/monitoring/public/lib/calculate_shard_stats.js b/x-pack/plugins/monitoring/public/lib/calculate_shard_stats.js index f74fd30fde84b9..cb01c182694b49 100644 --- a/x-pack/plugins/monitoring/public/lib/calculate_shard_stats.js +++ b/x-pack/plugins/monitoring/public/lib/calculate_shard_stats.js @@ -5,7 +5,7 @@ * 2.0. */ -import { set } from '@elastic/safer-lodash-set'; +import { set } from '@kbn/safer-lodash-set'; import { get, each } from 'lodash'; function addOne(obj, key) { diff --git a/x-pack/plugins/monitoring/server/lib/cluster/get_clusters_from_request.ts b/x-pack/plugins/monitoring/server/lib/cluster/get_clusters_from_request.ts index d8bf8487cee09e..dd696694050980 100644 --- a/x-pack/plugins/monitoring/server/lib/cluster/get_clusters_from_request.ts +++ b/x-pack/plugins/monitoring/server/lib/cluster/get_clusters_from_request.ts @@ -7,7 +7,7 @@ import { notFound } from '@hapi/boom'; import { get, omit } from 'lodash'; -import { set } from '@elastic/safer-lodash-set'; +import { set } from '@kbn/safer-lodash-set'; import { i18n } from '@kbn/i18n'; import { getClustersStats } from './get_clusters_stats'; import { flagSupportedClusters } from './flag_supported_clusters'; diff --git a/x-pack/plugins/monitoring/server/lib/cluster/get_clusters_state.test.js b/x-pack/plugins/monitoring/server/lib/cluster/get_clusters_state.test.js index 6b35012c9d55b7..1b9e40e4d63005 100644 --- a/x-pack/plugins/monitoring/server/lib/cluster/get_clusters_state.test.js +++ b/x-pack/plugins/monitoring/server/lib/cluster/get_clusters_state.test.js @@ -7,7 +7,7 @@ import { handleResponse } from './get_clusters_state'; import moment from 'moment'; -import { set } from '@elastic/safer-lodash-set'; +import { set } from '@kbn/safer-lodash-set'; const clusters = [ { diff --git a/x-pack/plugins/monitoring/server/lib/elasticsearch/get_ml_jobs.test.js b/x-pack/plugins/monitoring/server/lib/elasticsearch/get_ml_jobs.test.js index a04e53fdbbe9df..9ddcecb0cbbd0a 100644 --- a/x-pack/plugins/monitoring/server/lib/elasticsearch/get_ml_jobs.test.js +++ b/x-pack/plugins/monitoring/server/lib/elasticsearch/get_ml_jobs.test.js @@ -5,7 +5,7 @@ * 2.0. */ -import { set } from '@elastic/safer-lodash-set'; +import { set } from '@kbn/safer-lodash-set'; import { handleResponse } from './get_ml_jobs'; describe('Get ML Jobs', () => { diff --git a/x-pack/plugins/monitoring/server/lib/elasticsearch/nodes/calculate_node_type.test.js b/x-pack/plugins/monitoring/server/lib/elasticsearch/nodes/calculate_node_type.test.js index d249bc82b93870..915c305d294c72 100644 --- a/x-pack/plugins/monitoring/server/lib/elasticsearch/nodes/calculate_node_type.test.js +++ b/x-pack/plugins/monitoring/server/lib/elasticsearch/nodes/calculate_node_type.test.js @@ -5,7 +5,7 @@ * 2.0. */ -import { set } from '@elastic/safer-lodash-set'; +import { set } from '@kbn/safer-lodash-set'; import { calculateNodeType } from './calculate_node_type'; const masterNodeId = 'def456'; diff --git a/x-pack/plugins/monitoring/server/telemetry_collection/create_query.test.ts b/x-pack/plugins/monitoring/server/telemetry_collection/create_query.test.ts index 236b9280c3b05d..c24efe86e48ffb 100644 --- a/x-pack/plugins/monitoring/server/telemetry_collection/create_query.test.ts +++ b/x-pack/plugins/monitoring/server/telemetry_collection/create_query.test.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { set } from '@elastic/safer-lodash-set'; +import { set } from '@kbn/safer-lodash-set'; import { createTypeFilter, createQuery } from './create_query'; describe('Create Type Filter', () => { diff --git a/x-pack/plugins/monitoring/server/telemetry_collection/get_all_stats.ts b/x-pack/plugins/monitoring/server/telemetry_collection/get_all_stats.ts index f1c36f848ca985..f74c712fb055a2 100644 --- a/x-pack/plugins/monitoring/server/telemetry_collection/get_all_stats.ts +++ b/x-pack/plugins/monitoring/server/telemetry_collection/get_all_stats.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { set } from '@elastic/safer-lodash-set'; +import { set } from '@kbn/safer-lodash-set'; import { get, merge } from 'lodash'; import moment from 'moment'; diff --git a/x-pack/plugins/observability/common/index.ts b/x-pack/plugins/observability/common/index.ts index 794275c380c97e..379404c3a48a1d 100644 --- a/x-pack/plugins/observability/common/index.ts +++ b/x-pack/plugins/observability/common/index.ts @@ -15,7 +15,6 @@ export { enableInspectEsQueries, maxSuggestions, enableComparisonByDefault, - enableInfrastructureView, defaultApmServiceEnvironment, apmServiceInventoryOptimizedSorting, apmProgressiveLoading, diff --git a/x-pack/plugins/observability/common/ui_settings_keys.ts b/x-pack/plugins/observability/common/ui_settings_keys.ts index 60328a189b6969..f3c77c76d41864 100644 --- a/x-pack/plugins/observability/common/ui_settings_keys.ts +++ b/x-pack/plugins/observability/common/ui_settings_keys.ts @@ -9,7 +9,6 @@ export const enableNewSyntheticsView = 'observability:enableNewSyntheticsView'; export const enableInspectEsQueries = 'observability:enableInspectEsQueries'; export const maxSuggestions = 'observability:maxSuggestions'; export const enableComparisonByDefault = 'observability:enableComparisonByDefault'; -export const enableInfrastructureView = 'observability:enableInfrastructureView'; export const defaultApmServiceEnvironment = 'observability:apmDefaultServiceEnvironment'; export const apmProgressiveLoading = 'observability:apmProgressiveLoading'; export const enableServiceGroups = 'observability:enableServiceGroups'; diff --git a/x-pack/plugins/observability/kibana.json b/x-pack/plugins/observability/kibana.json index 5464bffccd9cd2..7754aedfe9ffca 100644 --- a/x-pack/plugins/observability/kibana.json +++ b/x-pack/plugins/observability/kibana.json @@ -31,7 +31,6 @@ "triggersActionsUi", "inspector", "unifiedSearch", - "sharedUX", "security" ], "ui": true, diff --git a/x-pack/plugins/observability/public/application/application.test.tsx b/x-pack/plugins/observability/public/application/application.test.tsx index 371be0ceb3a34e..d630988446aa61 100644 --- a/x-pack/plugins/observability/public/application/application.test.tsx +++ b/x-pack/plugins/observability/public/application/application.test.tsx @@ -11,7 +11,7 @@ import React from 'react'; import { Observable } from 'rxjs'; import { AppMountParameters, CoreStart } from '@kbn/core/public'; import { themeServiceMock } from '@kbn/core/public/mocks'; -import { KibanaPageTemplate } from '@kbn/shared-ux-components'; +import { KibanaPageTemplate } from '@kbn/shared-ux-page-kibana-template'; import { ObservabilityPublicPluginsStart } from '../plugin'; import { createObservabilityRuleTypeRegistryMock } from '../rules/observability_rule_type_registry_mock'; import { renderApp } from '.'; diff --git a/x-pack/plugins/observability/public/components/app/section/apm/index.test.tsx b/x-pack/plugins/observability/public/components/app/section/apm/index.test.tsx index 6ba0556fa01725..00b4e464e1f45f 100644 --- a/x-pack/plugins/observability/public/components/app/section/apm/index.test.tsx +++ b/x-pack/plugins/observability/public/components/app/section/apm/index.test.tsx @@ -17,7 +17,7 @@ import * as pluginContext from '../../../../hooks/use_plugin_context'; import { HasDataContextValue } from '../../../../context/has_data_context'; import { AppMountParameters } from '@kbn/core/public'; import { createObservabilityRuleTypeRegistryMock } from '../../../../rules/observability_rule_type_registry_mock'; -import { KibanaPageTemplate } from '@kbn/shared-ux-components'; +import { KibanaPageTemplate } from '@kbn/shared-ux-page-kibana-template'; jest.mock('react-router-dom', () => ({ useLocation: () => ({ diff --git a/x-pack/plugins/observability/public/components/shared/alert_status_indicator.tsx b/x-pack/plugins/observability/public/components/shared/alert_status_indicator.tsx index e8897ed92dc8cc..078d5c29767af8 100644 --- a/x-pack/plugins/observability/public/components/shared/alert_status_indicator.tsx +++ b/x-pack/plugins/observability/public/components/shared/alert_status_indicator.tsx @@ -9,18 +9,16 @@ import React from 'react'; import { i18n } from '@kbn/i18n'; import { EuiHealth, EuiText } from '@elastic/eui'; import { ALERT_STATUS_ACTIVE, AlertStatus } from '@kbn/rule-data-utils'; -import { useTheme } from '../../hooks/use_theme'; +import { LIGHT_THEME } from '@elastic/charts'; interface AlertStatusIndicatorProps { alertStatus: AlertStatus; } export function AlertStatusIndicator({ alertStatus }: AlertStatusIndicatorProps) { - const theme = useTheme(); - if (alertStatus === ALERT_STATUS_ACTIVE) { return ( - + {i18n.translate('xpack.observability.alertsTGrid.statusActiveDescription', { defaultMessage: 'Active', })} @@ -29,7 +27,7 @@ export function AlertStatusIndicator({ alertStatus }: AlertStatusIndicatorProps) } return ( - + {i18n.translate('xpack.observability.alertsTGrid.statusRecoveredDescription', { defaultMessage: 'Recovered', diff --git a/x-pack/plugins/observability/public/components/shared/header_menu_portal.tsx b/x-pack/plugins/observability/public/components/shared/header_menu_portal.tsx index 02d16c13ce4e89..dcfe8b9ce85bac 100644 --- a/x-pack/plugins/observability/public/components/shared/header_menu_portal.tsx +++ b/x-pack/plugins/observability/public/components/shared/header_menu_portal.tsx @@ -6,7 +6,7 @@ */ import React, { useEffect, useMemo } from 'react'; -import { createPortalNode, InPortal, OutPortal } from 'react-reverse-portal'; +import { createHtmlPortalNode, InPortal, OutPortal } from 'react-reverse-portal'; import { toMountPoint } from '@kbn/kibana-react-plugin/public'; import { HeaderMenuPortalProps } from './types'; @@ -16,7 +16,7 @@ export default function HeaderMenuPortal({ setHeaderActionMenu, theme$, }: HeaderMenuPortalProps) { - const portalNode = useMemo(() => createPortalNode(), []); + const portalNode = useMemo(() => createHtmlPortalNode(), []); useEffect(() => { setHeaderActionMenu((element) => { diff --git a/x-pack/plugins/observability/public/components/shared/page_template/page_template.test.tsx b/x-pack/plugins/observability/public/components/shared/page_template/page_template.test.tsx index 176e137242ebc6..89574732b5a854 100644 --- a/x-pack/plugins/observability/public/components/shared/page_template/page_template.test.tsx +++ b/x-pack/plugins/observability/public/components/shared/page_template/page_template.test.tsx @@ -10,7 +10,8 @@ import { render } from '@testing-library/react'; import { shallow } from 'enzyme'; import React from 'react'; import { of } from 'rxjs'; -import { sharedUXPluginMock } from '@kbn/shared-ux-plugin/public/mocks'; +import { getKibanaPageTemplateKibanaDependenciesMock as getPageTemplateServices } from '@kbn/shared-ux-page-kibana-template-mocks'; + import { createNavigationRegistry } from '../../../services/navigation_registry'; import { createLazyObservabilityPageTemplate } from './lazy_page_template'; import { ObservabilityPageTemplate } from './page_template'; @@ -52,7 +53,7 @@ describe('Page template', () => { getUrlForApp: () => '/test-url', navigateToApp: async () => {}, navigationSections$: navigationRegistry.sections$, - getSharedUXContext: sharedUXPluginMock.createStartContract().getContextServices, + getPageTemplateServices, }); const component = shallow( @@ -76,11 +77,11 @@ describe('Page template', () => { getUrlForApp={() => '/test-url'} navigateToApp={async () => {}} navigationSections$={navigationRegistry.sections$} - getSharedUXContext={sharedUXPluginMock.createStartContract().getContextServices} pageHeader={{ pageTitle: 'Test title', rightSideItems: [Test side item], }} + getPageTemplateServices={getPageTemplateServices} >

Test structure
@@ -97,11 +98,11 @@ describe('Page template', () => { getUrlForApp={() => '/test-url'} navigateToApp={async () => {}} navigationSections$={navigationRegistry.sections$} - getSharedUXContext={sharedUXPluginMock.createStartContract().getContextServices} pageHeader={{ pageTitle: 'Test title', rightSideItems: [Test side item], }} + getPageTemplateServices={getPageTemplateServices} >
Test structure
diff --git a/x-pack/plugins/observability/public/components/shared/page_template/page_template.tsx b/x-pack/plugins/observability/public/components/shared/page_template/page_template.tsx index ee05d2c4b59cb8..d852a8658c2e1c 100644 --- a/x-pack/plugins/observability/public/components/shared/page_template/page_template.tsx +++ b/x-pack/plugins/observability/public/components/shared/page_template/page_template.tsx @@ -12,10 +12,15 @@ import { matchPath, useLocation } from 'react-router-dom'; import useObservable from 'react-use/lib/useObservable'; import type { Observable } from 'rxjs'; import type { ApplicationStart } from '@kbn/core/public'; -import { SharedUxServicesProvider } from '@kbn/shared-ux-services'; -import type { SharedUXPluginStart } from '@kbn/shared-ux-plugin/public'; import { useKibana } from '@kbn/kibana-react-plugin/public'; -import { KibanaPageTemplate, KibanaPageTemplateProps } from '@kbn/shared-ux-components'; +import { + KibanaPageTemplate, + KibanaPageTemplateKibanaProvider, +} from '@kbn/shared-ux-page-kibana-template'; +import type { + KibanaPageTemplateProps, + KibanaPageTemplateKibanaDependencies, +} from '@kbn/shared-ux-page-kibana-template'; import type { NavigationSection } from '../../../services/navigation_registry'; import { ObservabilityTour } from '../tour'; import { NavNameWithBadge, hideBadge } from './nav_name_with_badge'; @@ -43,7 +48,7 @@ export interface ObservabilityPageTemplateDependencies { getUrlForApp: ApplicationStart['getUrlForApp']; navigateToApp: ApplicationStart['navigateToApp']; navigationSections$: Observable; - getSharedUXContext: SharedUXPluginStart['getContextServices']; + getPageTemplateServices: () => KibanaPageTemplateKibanaDependencies; } export type ObservabilityPageTemplateProps = ObservabilityPageTemplateDependencies & @@ -55,15 +60,14 @@ export function ObservabilityPageTemplate({ getUrlForApp, navigateToApp, navigationSections$, - getSharedUXContext, showSolutionNav = true, isPageDataLoaded = true, + getPageTemplateServices, ...pageTemplateProps }: ObservabilityPageTemplateProps): React.ReactElement | null { const sections = useObservable(navigationSections$, []); const currentAppId = useObservable(currentAppId$, undefined); const { pathname: currentPath } = useLocation(); - const sharedUXServices = getSharedUXContext(); const { services } = useKibana(); @@ -130,7 +134,7 @@ export function ObservabilityPageTemplate({ ); return ( - + - + ); } diff --git a/x-pack/plugins/observability/public/index.ts b/x-pack/plugins/observability/public/index.ts index 04cb8289dd2475..b4e23ce0e83adc 100644 --- a/x-pack/plugins/observability/public/index.ts +++ b/x-pack/plugins/observability/public/index.ts @@ -27,7 +27,6 @@ export type { export { enableInspectEsQueries, enableComparisonByDefault, - enableInfrastructureView, enableServiceGroups, enableNewSyntheticsView, apmServiceGroupMaxNumberOfServices, diff --git a/x-pack/plugins/observability/public/pages/cases/cases.stories.tsx b/x-pack/plugins/observability/public/pages/cases/cases.stories.tsx index b384047a1c77ba..bab4397a49a758 100644 --- a/x-pack/plugins/observability/public/pages/cases/cases.stories.tsx +++ b/x-pack/plugins/observability/public/pages/cases/cases.stories.tsx @@ -9,7 +9,7 @@ import React, { ComponentType } from 'react'; import { MemoryRouter } from 'react-router-dom'; import { AppMountParameters } from '@kbn/core/public'; import { CoreStart } from '@kbn/core/public'; -import { KibanaPageTemplate } from '@kbn/shared-ux-components'; +import { KibanaPageTemplate } from '@kbn/shared-ux-page-kibana-template'; import { createKibanaReactContext } from '@kbn/kibana-react-plugin/public'; import { casesFeatureId } from '../../../common'; import { PluginContext, PluginContextValue } from '../../context/plugin_context'; diff --git a/x-pack/plugins/observability/public/pages/overview/overview.stories.tsx b/x-pack/plugins/observability/public/pages/overview/overview.stories.tsx index aab1663482636f..2e384e83fd03db 100644 --- a/x-pack/plugins/observability/public/pages/overview/overview.stories.tsx +++ b/x-pack/plugins/observability/public/pages/overview/overview.stories.tsx @@ -12,7 +12,7 @@ import React, { ReactNode } from 'react'; import { MemoryRouter } from 'react-router-dom'; import { UI_SETTINGS } from '@kbn/data-plugin/public'; import { createKibanaReactContext } from '@kbn/kibana-react-plugin/public'; -import { KibanaPageTemplate } from '@kbn/shared-ux-components'; +import { KibanaPageTemplate } from '@kbn/shared-ux-page-kibana-template'; import { HasDataContextProvider } from '../../context/has_data_context'; import { PluginContext } from '../../context/plugin_context'; import { registerDataHandler, unregisterDataHandler } from '../../data_handler'; diff --git a/x-pack/plugins/observability/public/pages/rules/index.test.tsx b/x-pack/plugins/observability/public/pages/rules/index.test.tsx index a9bf4aff99a837..cc8a093e323331 100644 --- a/x-pack/plugins/observability/public/pages/rules/index.test.tsx +++ b/x-pack/plugins/observability/public/pages/rules/index.test.tsx @@ -14,7 +14,7 @@ import { ObservabilityPublicPluginsStart } from '../../plugin'; import { RulesPage } from '.'; import { kibanaStartMock } from '../../utils/kibana_react.mock'; import * as pluginContext from '../../hooks/use_plugin_context'; -import { KibanaPageTemplate } from '@kbn/shared-ux-components'; +import { KibanaPageTemplate } from '@kbn/shared-ux-page-kibana-template'; import { createObservabilityRuleTypeRegistryMock } from '../../rules/observability_rule_type_registry_mock'; import { AppMountParameters } from '@kbn/core/public'; import { ALERTS_FEATURE_ID } from '@kbn/alerting-plugin/common'; diff --git a/x-pack/plugins/observability/public/plugin.ts b/x-pack/plugins/observability/public/plugin.ts index 617dce2959f1eb..97b3746671c9db 100644 --- a/x-pack/plugins/observability/public/plugin.ts +++ b/x-pack/plugins/observability/public/plugin.ts @@ -26,7 +26,6 @@ import type { EmbeddableStart } from '@kbn/embeddable-plugin/public'; import type { HomePublicPluginSetup, HomePublicPluginStart } from '@kbn/home-plugin/public'; import { CasesDeepLinkId, CasesUiStart, getCasesDeepLinks } from '@kbn/cases-plugin/public'; import type { LensPublicStart } from '@kbn/lens-plugin/public'; -import type { SharedUXPluginStart } from '@kbn/shared-ux-plugin/public'; import { TriggersAndActionsUIPublicPluginSetup, TriggersAndActionsUIPublicPluginStart, @@ -72,7 +71,6 @@ export interface ObservabilityPublicPluginsStart { dataViews: DataViewsPublicPluginStart; lens: LensPublicStart; discover: DiscoverStart; - sharedUX: SharedUXPluginStart; ruleTypeRegistry: RuleTypeRegistryContract; actionTypeRegistry: ActionTypeRegistryContract; security: SecurityPluginStart; @@ -282,7 +280,7 @@ export class Plugin getUrlForApp: application.getUrlForApp, navigateToApp: application.navigateToApp, navigationSections$: this.navigationRegistry.sections$, - getSharedUXContext: pluginsStart.sharedUX.getContextServices, + getPageTemplateServices: () => ({ coreStart }), }); const getAsyncO11yAlertsTableConfiguration = async () => { diff --git a/x-pack/plugins/observability/public/utils/no_data_config.ts b/x-pack/plugins/observability/public/utils/no_data_config.ts index c71520e35bf184..be19e6658b5b6b 100644 --- a/x-pack/plugins/observability/public/utils/no_data_config.ts +++ b/x-pack/plugins/observability/public/utils/no_data_config.ts @@ -7,7 +7,7 @@ import { i18n } from '@kbn/i18n'; import { IBasePath } from '@kbn/core/public'; -import { KibanaPageTemplateProps } from '@kbn/shared-ux-components'; +import type { NoDataConfig } from '@kbn/shared-ux-page-kibana-template'; export function getNoDataConfig({ docsLink, @@ -17,7 +17,7 @@ export function getNoDataConfig({ docsLink: string; basePath: IBasePath; hasData?: boolean; -}): KibanaPageTemplateProps['noDataConfig'] { +}): NoDataConfig | undefined { if (hasData === false) { return { solution: i18n.translate('xpack.observability.noDataConfig.solutionName', { diff --git a/x-pack/plugins/observability/public/utils/test_helper.tsx b/x-pack/plugins/observability/public/utils/test_helper.tsx index d262f290d1fe12..ef197f7dfc8d5e 100644 --- a/x-pack/plugins/observability/public/utils/test_helper.tsx +++ b/x-pack/plugins/observability/public/utils/test_helper.tsx @@ -12,7 +12,7 @@ import { coreMock } from '@kbn/core/public/mocks'; import React from 'react'; import { __IntlProvider as IntlProvider } from '@kbn/i18n-react'; import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public'; -import { KibanaPageTemplate } from '@kbn/shared-ux-components'; +import { KibanaPageTemplate } from '@kbn/shared-ux-page-kibana-template'; import translations from '@kbn/translations-plugin/translations/ja-JP.json'; import { EuiThemeProvider } from '@kbn/kibana-react-plugin/common'; import { dataPluginMock } from '@kbn/data-plugin/public/mocks'; diff --git a/x-pack/plugins/observability/server/ui_settings.ts b/x-pack/plugins/observability/server/ui_settings.ts index 36fb6cd9f62ff5..f22da4b96e6b97 100644 --- a/x-pack/plugins/observability/server/ui_settings.ts +++ b/x-pack/plugins/observability/server/ui_settings.ts @@ -13,7 +13,6 @@ import { enableComparisonByDefault, enableInspectEsQueries, maxSuggestions, - enableInfrastructureView, defaultApmServiceEnvironment, apmProgressiveLoading, enableServiceGroups, @@ -84,17 +83,6 @@ export const uiSettings: Record | undefined) => - ecsMapping - ? Object.entries(ecsMapping).map((item) => ({ - key: item[0], - value: item[1], - })) - : undefined; +import type { ECSMapping } from './schemas'; export const convertECSMappingToObject = ( ecsMapping: Array<{ @@ -23,7 +16,7 @@ export const convertECSMappingToObject = ( value: string; }; }> -): Record => +): ECSMapping => reduce( ecsMapping, (acc, value) => { diff --git a/x-pack/plugins/osquery/cypress/integration/all/alerts.spec.ts b/x-pack/plugins/osquery/cypress/integration/all/alerts.spec.ts index ee4992b04b1d24..f0b07f89cde921 100644 --- a/x-pack/plugins/osquery/cypress/integration/all/alerts.spec.ts +++ b/x-pack/plugins/osquery/cypress/integration/all/alerts.spec.ts @@ -8,7 +8,6 @@ import { ArchiverMethod, runKbnArchiverScript } from '../../tasks/archiver'; import { login } from '../../tasks/login'; import { - checkResults, findAndClickButton, findFormFieldByRowsLabelAndType, inputQuery, @@ -80,7 +79,8 @@ describe('Alert Event Details', () => { cy.contains('1 agent selected.'); inputQuery('select * from uptime;'); submitQuery(); - checkResults(); + cy.contains('Results'); + cy.contains('Add to timeline investigation'); cy.contains('Save for later').click(); cy.contains('Save query'); cy.get('.euiButtonEmpty--flushLeft').contains('Cancel').click(); diff --git a/x-pack/plugins/osquery/cypress/integration/all/edit_saved_queries.spec.ts b/x-pack/plugins/osquery/cypress/integration/all/edit_saved_queries.spec.ts index 6dde0013a4bc69..42ffd48d73692b 100644 --- a/x-pack/plugins/osquery/cypress/integration/all/edit_saved_queries.spec.ts +++ b/x-pack/plugins/osquery/cypress/integration/all/edit_saved_queries.spec.ts @@ -26,15 +26,15 @@ describe('ALL - Edit saved query', () => { }); it('by changing ecs mappings and platforms', () => { + cy.getBySel('pagination-button-next').click(); cy.react('CustomItemAction', { props: { index: 1, item: { attributes: { id: SAVED_QUERY_ID } } }, }).click(); cy.contains('Custom key/value pairs.').should('exist'); cy.contains('Hours of uptime').should('exist'); - cy.react('ECSComboboxFieldComponent', { props: { field: { value: 'labels' } } }) - .parents('[data-test-subj="ECSMappingEditorForm"]') - .react('EuiButtonIcon', { props: { iconType: 'trash' } }) - .click(); + cy.react('ECSMappingEditorForm').within(() => { + cy.react('EuiButtonIcon', { props: { iconType: 'trash' } }).click(); + }); cy.react('PlatformCheckBoxGroupField').within(() => { cy.react('EuiCheckbox', { diff --git a/x-pack/plugins/osquery/cypress/integration/all/live_query.spec.ts b/x-pack/plugins/osquery/cypress/integration/all/live_query.spec.ts index 0678f3170f2341..c332e3dae5087a 100644 --- a/x-pack/plugins/osquery/cypress/integration/all/live_query.spec.ts +++ b/x-pack/plugins/osquery/cypress/integration/all/live_query.spec.ts @@ -41,6 +41,28 @@ describe('ALL - Live Query', () => { runKbnArchiverScript(ArchiverMethod.UNLOAD, 'example_pack'); }); + it('should validate the form', () => { + cy.contains('New live query').click(); + submitQuery(); + cy.contains('Agents is a required field'); + cy.contains('Query is a required field'); + selectAllAgents(); + inputQuery('select * from uptime; '); + submitQuery(); + cy.contains('Agents is a required field').should('not.exist'); + cy.contains('Query is a required field').should('not.exist'); + checkResults(); + getAdvancedButton().click(); + typeInOsqueryFieldInput('days{downArrow}{enter}'); + submitQuery(); + cy.contains('ECS field is required.'); + typeInECSFieldInput('message{downArrow}{enter}'); + submitQuery(); + cy.contains('ECS field is required.').should('not.exist'); + + checkResults(); + }); + it('should run query and enable ecs mapping', () => { const cmd = Cypress.platform === 'darwin' ? '{meta}{enter}' : '{ctrl}{enter}'; cy.contains('New live query').click(); @@ -82,7 +104,7 @@ describe('ALL - Live Query', () => { cy.contains('New live query').click(); selectAllAgents(); cy.react('SavedQueriesDropdown').type('NOMAPPING{downArrow}{enter}'); - cy.getReact('SavedQueriesDropdown').getCurrentState().should('have.length', 1); + // cy.getReact('SavedQueriesDropdown').getCurrentState().should('have.length', 1); // TODO do we need it? inputQuery('{selectall}{backspace}{selectall}{backspace}select * from users'); cy.wait(1000); submitQuery(); diff --git a/x-pack/plugins/osquery/cypress/integration/all/metrics.spec.ts b/x-pack/plugins/osquery/cypress/integration/all/metrics.spec.ts index 88145dfa46401f..0edefdc24ea420 100644 --- a/x-pack/plugins/osquery/cypress/integration/all/metrics.spec.ts +++ b/x-pack/plugins/osquery/cypress/integration/all/metrics.spec.ts @@ -46,7 +46,7 @@ describe('ALL - Inventory', () => { cy.getBySel('comboBoxInput').first().click(); cy.wait(500); - cy.getBySel('comboBoxInput').first().type('{downArrow}{enter}'); + cy.getBySel('comboBoxInput').first().type('saved{downArrow}{enter}'); submitQuery(); checkResults(); diff --git a/x-pack/plugins/osquery/cypress/integration/all/packs.spec.ts b/x-pack/plugins/osquery/cypress/integration/all/packs.spec.ts index 72fae5479a85e2..64620cf3cc08ca 100644 --- a/x-pack/plugins/osquery/cypress/integration/all/packs.spec.ts +++ b/x-pack/plugins/osquery/cypress/integration/all/packs.spec.ts @@ -77,6 +77,7 @@ describe('ALL - Packs', () => { cy.contains('Attach next query'); inputQuery('select * from uptime'); findFormFieldByRowsLabelAndType('ID', SAVED_QUERY_ID); + cy.react('EuiFlyoutFooter').react('EuiButton').contains('Save').click(); cy.contains('ID must be unique').should('exist'); findFormFieldByRowsLabelAndType('ID', NEW_QUERY_NAME); cy.contains('ID must be unique').should('not.exist'); @@ -95,6 +96,7 @@ describe('ALL - Packs', () => { cy.contains('Attach next query'); cy.contains('ID must be unique').should('not.exist'); getSavedQueriesDropdown().type(`${SAVED_QUERY_ID}{downArrow}{enter}`); + cy.react('EuiFlyoutFooter').react('EuiButton').contains('Save').click(); cy.contains('ID must be unique').should('exist'); cy.react('EuiFlyoutFooter').react('EuiButtonEmpty').contains('Cancel').click(); }); diff --git a/x-pack/plugins/osquery/cypress/integration/roles/admin.spec.ts b/x-pack/plugins/osquery/cypress/integration/roles/admin.spec.ts index a22177955c4acf..b8781df09d01f3 100644 --- a/x-pack/plugins/osquery/cypress/integration/roles/admin.spec.ts +++ b/x-pack/plugins/osquery/cypress/integration/roles/admin.spec.ts @@ -20,7 +20,6 @@ describe('Admin', () => { cy.contains('New live query').click(); selectAllAgents(); inputQuery('select * from uptime; '); - cy.wait(500); submitQuery(); checkResults(); }); diff --git a/x-pack/plugins/osquery/cypress/integration/roles/reader.spec.ts b/x-pack/plugins/osquery/cypress/integration/roles/reader.spec.ts index ddbca76efcf161..365f4d5b0eba10 100644 --- a/x-pack/plugins/osquery/cypress/integration/roles/reader.spec.ts +++ b/x-pack/plugins/osquery/cypress/integration/roles/reader.spec.ts @@ -27,6 +27,7 @@ describe('Reader - only READ', () => { it('should not be able to add nor run saved queries', () => { navigateTo('/app/osquery/saved_queries'); cy.waitForReact(1000); + cy.getBySel('pagination-button-next').click(); cy.contains(SAVED_QUERY_ID); cy.contains('Add saved query').should('be.disabled'); cy.react('PlayButtonComponent', { diff --git a/x-pack/plugins/osquery/cypress/integration/roles/t1_analyst.spec.ts b/x-pack/plugins/osquery/cypress/integration/roles/t1_analyst.spec.ts index c151cce2c2e608..d236555091b3fb 100644 --- a/x-pack/plugins/osquery/cypress/integration/roles/t1_analyst.spec.ts +++ b/x-pack/plugins/osquery/cypress/integration/roles/t1_analyst.spec.ts @@ -29,6 +29,7 @@ describe('T1 Analyst - READ + runSavedQueries ', () => { it('should be able to run saved queries but not add new ones', () => { navigateTo('/app/osquery/saved_queries'); cy.waitForReact(1000); + cy.getBySel('pagination-button-next').click(); cy.contains(SAVED_QUERY_ID); cy.contains('Add saved query').should('be.disabled'); cy.react('PlayButtonComponent', { @@ -93,6 +94,7 @@ describe('T1 Analyst - READ + runSavedQueries ', () => { cy.contains('New live query').click(); selectAllAgents(); cy.get(LIVE_QUERY_EDITOR).should('not.exist'); - cy.contains('Submit').should('be.disabled'); + submitQuery(); + cy.contains('Query is a required field'); }); }); diff --git a/x-pack/plugins/osquery/cypress/integration/roles/t2_analyst.spec.ts b/x-pack/plugins/osquery/cypress/integration/roles/t2_analyst.spec.ts index 901b18f1461c7f..63a0eb5d1619d9 100644 --- a/x-pack/plugins/osquery/cypress/integration/roles/t2_analyst.spec.ts +++ b/x-pack/plugins/osquery/cypress/integration/roles/t2_analyst.spec.ts @@ -100,16 +100,16 @@ describe('T2 Analyst - READ + Write Live/Saved + runSavedQueries ', () => { }); it('to click the edit button and edit pack', () => { navigateTo('/app/osquery/saved_queries'); + cy.getBySel('pagination-button-next').click(); cy.react('CustomItemAction', { props: { index: 1, item: { attributes: { id: SAVED_QUERY_ID } } }, }).click(); cy.contains('Custom key/value pairs.').should('exist'); cy.contains('Hours of uptime').should('exist'); - cy.react('ECSComboboxFieldComponent', { props: { field: { value: 'labels' } } }) - .parents('[data-test-subj="ECSMappingEditorForm"]') - .react('EuiButtonIcon', { props: { iconType: 'trash' } }) - .click(); + cy.react('ECSMappingEditorForm').within(() => { + cy.react('EuiButtonIcon', { props: { iconType: 'trash' } }).click(); + }); cy.react('EuiButton').contains('Update query').click(); cy.wait(5000); diff --git a/x-pack/plugins/osquery/cypress/tasks/live_query.ts b/x-pack/plugins/osquery/cypress/tasks/live_query.ts index 3a1f1b0930edf9..3c571d04ff84c0 100644 --- a/x-pack/plugins/osquery/cypress/tasks/live_query.ts +++ b/x-pack/plugins/osquery/cypress/tasks/live_query.ts @@ -8,7 +8,7 @@ import { LIVE_QUERY_EDITOR } from '../screens/live_query'; export const DEFAULT_QUERY = 'select * from processes;'; -export const BIG_QUERY = 'select * from processes, users limit 200;'; +export const BIG_QUERY = 'select * from processes, users limit 110;'; export const selectAllAgents = () => { cy.react('AgentsTable').find('input').should('not.be.disabled'); @@ -25,7 +25,10 @@ export const clearInputQuery = () => export const inputQuery = (query: string) => cy.get(LIVE_QUERY_EDITOR).type(query); -export const submitQuery = () => cy.contains('Submit').click(); +export const submitQuery = () => { + cy.wait(1000); // wait for the validation to trigger - cypress is way faster than users ;) + cy.contains('Submit').click(); +}; export const checkResults = () => cy.getBySel('dataGridRowCell', { timeout: 120000 }).should('have.lengthOf.above', 0); diff --git a/x-pack/plugins/osquery/public/action_results/action_results_summary.tsx b/x-pack/plugins/osquery/public/action_results/action_results_summary.tsx index 29d823560d6e3e..81feb53fb40128 100644 --- a/x-pack/plugins/osquery/public/action_results/action_results_summary.tsx +++ b/x-pack/plugins/osquery/public/action_results/action_results_summary.tsx @@ -53,9 +53,8 @@ const ActionResultsSummaryComponent: React.FC = ({ skip: !hasActionResultsPrivileges, }); if (expired) { - // @ts-expect-error update types edges.forEach((edge) => { - if (!edge.fields.completed_at) { + if (!edge.fields?.completed_at && edge.fields) { edge.fields['error.keyword'] = edge.fields.error = [ i18n.translate('xpack.osquery.liveQueryActionResults.table.expiredErrorText', { defaultMessage: 'The action request timed out.', diff --git a/x-pack/plugins/osquery/public/action_results/use_action_privileges.tsx b/x-pack/plugins/osquery/public/action_results/use_action_privileges.tsx index 6d0477b22edee4..83508def6a4838 100644 --- a/x-pack/plugins/osquery/public/action_results/use_action_privileges.tsx +++ b/x-pack/plugins/osquery/public/action_results/use_action_privileges.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { useQuery } from 'react-query'; +import { useQuery } from '@tanstack/react-query'; import { useKibana } from '../common/lib/kibana'; export const useActionResultsPrivileges = () => { diff --git a/x-pack/plugins/osquery/public/action_results/use_action_results.ts b/x-pack/plugins/osquery/public/action_results/use_action_results.ts index 964feb9eafb3b5..f950b4f1907c3c 100644 --- a/x-pack/plugins/osquery/public/action_results/use_action_results.ts +++ b/x-pack/plugins/osquery/public/action_results/use_action_results.ts @@ -7,7 +7,7 @@ import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import { flatten, reverse, uniqBy } from 'lodash/fp'; -import { useQuery } from 'react-query'; +import { useQuery } from '@tanstack/react-query'; import { i18n } from '@kbn/i18n'; import { lastValueFrom } from 'rxjs'; import type { InspectResponse } from '../common/helpers'; diff --git a/x-pack/plugins/osquery/public/actions/use_all_live_queries.ts b/x-pack/plugins/osquery/public/actions/use_all_live_queries.ts index f0fb0cd35ead60..a4bb5e5037a48f 100644 --- a/x-pack/plugins/osquery/public/actions/use_all_live_queries.ts +++ b/x-pack/plugins/osquery/public/actions/use_all_live_queries.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { useQuery } from 'react-query'; +import { useQuery } from '@tanstack/react-query'; import { i18n } from '@kbn/i18n'; import { createFilter } from '../common/helpers'; diff --git a/x-pack/plugins/osquery/public/actions/use_live_query_details.ts b/x-pack/plugins/osquery/public/actions/use_live_query_details.ts index a31c4934870574..b8703a8370d022 100644 --- a/x-pack/plugins/osquery/public/actions/use_live_query_details.ts +++ b/x-pack/plugins/osquery/public/actions/use_live_query_details.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { useQuery } from 'react-query'; +import { useQuery } from '@tanstack/react-query'; import { i18n } from '@kbn/i18n'; import { useKibana } from '../common/lib/kibana'; diff --git a/x-pack/plugins/osquery/public/agent_policies/use_agent_policies.ts b/x-pack/plugins/osquery/public/agent_policies/use_agent_policies.ts index 5eb70c802140cc..37f1789a964de2 100644 --- a/x-pack/plugins/osquery/public/agent_policies/use_agent_policies.ts +++ b/x-pack/plugins/osquery/public/agent_policies/use_agent_policies.ts @@ -6,7 +6,7 @@ */ import { mapKeys } from 'lodash'; -import { useQuery } from 'react-query'; +import { useQuery } from '@tanstack/react-query'; import { i18n } from '@kbn/i18n'; import type { GetAgentPoliciesResponseItem } from '@kbn/fleet-plugin/common'; diff --git a/x-pack/plugins/osquery/public/agent_policies/use_agent_policy.ts b/x-pack/plugins/osquery/public/agent_policies/use_agent_policy.ts index f629a138f70f6d..7a819e1118ad28 100644 --- a/x-pack/plugins/osquery/public/agent_policies/use_agent_policy.ts +++ b/x-pack/plugins/osquery/public/agent_policies/use_agent_policy.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { useQuery } from 'react-query'; +import { useQuery } from '@tanstack/react-query'; import { i18n } from '@kbn/i18n'; import type { AgentPolicy } from '@kbn/fleet-plugin/common'; diff --git a/x-pack/plugins/osquery/public/agents/agents_table.tsx b/x-pack/plugins/osquery/public/agents/agents_table.tsx index e11cb9b8277d9d..2d05780d6545f0 100644 --- a/x-pack/plugins/osquery/public/agents/agents_table.tsx +++ b/x-pack/plugins/osquery/public/agents/agents_table.tsx @@ -35,12 +35,13 @@ import { AGENT_GROUP_KEY } from './types'; interface AgentsTableProps { agentSelection: AgentSelection; onChange: (payload: AgentSelection) => void; + error?: string; } const perPage = 10; const DEBOUNCE_DELAY = 300; // ms -const AgentsTableComponent: React.FC = ({ agentSelection, onChange }) => { +const AgentsTableComponent: React.FC = ({ agentSelection, onChange, error }) => { // search related const [searchValue, setSearchValue] = useState(''); const [modifyingSearch, setModifyingSearch] = useState(false); @@ -185,7 +186,7 @@ const AgentsTableComponent: React.FC = ({ agentSelection, onCh return (
- + { const { http } = useKibana().services; const setErrorToast = useErrorToast(); - const agentResponse = useQueries( - policyIds.map((policyId) => ({ + const agentResponse = useQueries({ + queries: policyIds.map((policyId) => ({ queryKey: ['agentPolicy', policyId], queryFn: () => http.get(`/internal/osquery/fleet_wrapper/agent_policies/${policyId}`), enabled: policyIds.length > 0, onSuccess: () => setErrorToast(), + onError: (error: Error) => setErrorToast(error, { title: i18n.translate('xpack.osquery.action_policy_details.fetchError', { defaultMessage: 'Error while fetching policy details', }), }), - })) - ) as Array>; + })), + }) as Array>; const agentPoliciesLoading = agentResponse.some((p) => p.isLoading); const agentPolicies = agentResponse.map((p) => p.data?.item); diff --git a/x-pack/plugins/osquery/public/agents/use_agent_policy_agent_ids.ts b/x-pack/plugins/osquery/public/agents/use_agent_policy_agent_ids.ts index 4007f14ccc3e0f..cd30baf32d52d9 100644 --- a/x-pack/plugins/osquery/public/agents/use_agent_policy_agent_ids.ts +++ b/x-pack/plugins/osquery/public/agents/use_agent_policy_agent_ids.ts @@ -7,7 +7,7 @@ import { map } from 'lodash'; import { i18n } from '@kbn/i18n'; -import { useQuery } from 'react-query'; +import { useQuery } from '@tanstack/react-query'; import type { Agent } from '@kbn/fleet-plugin/common'; import { AGENTS_PREFIX } from '@kbn/fleet-plugin/common'; diff --git a/x-pack/plugins/osquery/public/agents/use_agent_status.ts b/x-pack/plugins/osquery/public/agents/use_agent_status.ts index dd733c27675cdd..bc0d4e6323f620 100644 --- a/x-pack/plugins/osquery/public/agents/use_agent_status.ts +++ b/x-pack/plugins/osquery/public/agents/use_agent_status.ts @@ -6,7 +6,7 @@ */ import { i18n } from '@kbn/i18n'; -import { useQuery } from 'react-query'; +import { useQuery } from '@tanstack/react-query'; import type { GetAgentStatusResponse } from '@kbn/fleet-plugin/common'; import { useErrorToast } from '../common/hooks/use_error_toast'; diff --git a/x-pack/plugins/osquery/public/agents/use_all_agents.ts b/x-pack/plugins/osquery/public/agents/use_all_agents.ts index c5e7c2d703bcfd..4f2aa8826f85fb 100644 --- a/x-pack/plugins/osquery/public/agents/use_all_agents.ts +++ b/x-pack/plugins/osquery/public/agents/use_all_agents.ts @@ -6,7 +6,7 @@ */ import { i18n } from '@kbn/i18n'; -import { useQuery } from 'react-query'; +import { useQuery } from '@tanstack/react-query'; import type { ListResult, Agent } from '@kbn/fleet-plugin/common'; import { useErrorToast } from '../common/hooks/use_error_toast'; diff --git a/x-pack/plugins/osquery/public/agents/use_osquery_policies.ts b/x-pack/plugins/osquery/public/agents/use_osquery_policies.ts index 9ecf5d14c6b38e..589deab5334b11 100644 --- a/x-pack/plugins/osquery/public/agents/use_osquery_policies.ts +++ b/x-pack/plugins/osquery/public/agents/use_osquery_policies.ts @@ -6,7 +6,7 @@ */ import { uniq } from 'lodash'; -import { useQuery } from 'react-query'; +import { useQuery } from '@tanstack/react-query'; import { i18n } from '@kbn/i18n'; import { useKibana } from '../common/lib/kibana'; import { useErrorToast } from '../common/hooks/use_error_toast'; diff --git a/x-pack/plugins/osquery/public/application.tsx b/x-pack/plugins/osquery/public/application.tsx index c57a9cb46795f0..b8f8f504a5b5af 100644 --- a/x-pack/plugins/osquery/public/application.tsx +++ b/x-pack/plugins/osquery/public/application.tsx @@ -12,8 +12,8 @@ import ReactDOM from 'react-dom'; import { Router } from 'react-router-dom'; import { I18nProvider } from '@kbn/i18n-react'; import { ThemeProvider } from 'styled-components'; -import { QueryClientProvider } from 'react-query'; -import { ReactQueryDevtools } from 'react-query/devtools'; +import { QueryClientProvider } from '@tanstack/react-query'; +import { ReactQueryDevtools } from '@tanstack/react-query-devtools'; import type { Storage } from '@kbn/kibana-utils-plugin/public'; import type { AppMountParameters, CoreStart } from '@kbn/core/public'; diff --git a/x-pack/plugins/osquery/public/assets/use_assets_status.ts b/x-pack/plugins/osquery/public/assets/use_assets_status.ts index 28e752df6b2f42..0d082f29b01751 100644 --- a/x-pack/plugins/osquery/public/assets/use_assets_status.ts +++ b/x-pack/plugins/osquery/public/assets/use_assets_status.ts @@ -6,7 +6,7 @@ */ import type { SavedObject } from '@kbn/core/public'; -import { useQuery } from 'react-query'; +import { useQuery } from '@tanstack/react-query'; import { useKibana } from '../common/lib/kibana'; import { INTEGRATION_ASSETS_STATUS_ID } from './constants'; diff --git a/x-pack/plugins/osquery/public/assets/use_import_assets.ts b/x-pack/plugins/osquery/public/assets/use_import_assets.ts index feb2c48041567f..4ae6d8549d6fa6 100644 --- a/x-pack/plugins/osquery/public/assets/use_import_assets.ts +++ b/x-pack/plugins/osquery/public/assets/use_import_assets.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { useMutation, useQueryClient } from 'react-query'; +import { useMutation, useQueryClient } from '@tanstack/react-query'; import { useKibana } from '../common/lib/kibana'; import { useErrorToast } from '../common/hooks/use_error_toast'; import { PACKS_ID } from '../packs/constants'; @@ -26,8 +26,8 @@ export const useImportAssets = ({ successToastText }: UseImportAssetsProps) => { return useMutation(() => http.post('/internal/osquery/assets/update'), { onSuccess: () => { setErrorToast(); - queryClient.invalidateQueries(PACKS_ID); - queryClient.invalidateQueries(INTEGRATION_ASSETS_STATUS_ID); + queryClient.invalidateQueries([PACKS_ID]); + queryClient.invalidateQueries([INTEGRATION_ASSETS_STATUS_ID]); toasts.addSuccess(successToastText); }, onError: (error) => { diff --git a/x-pack/plugins/osquery/public/common/helpers.ts b/x-pack/plugins/osquery/public/common/helpers.ts index 6b0a5f2a51c39c..6ac79d9ed8870b 100644 --- a/x-pack/plugins/osquery/public/common/helpers.ts +++ b/x-pack/plugins/osquery/public/common/helpers.ts @@ -15,7 +15,6 @@ import type { } from '../../common/search_strategy'; import type { ESQuery } from '../../common/typed_json'; -import type { ArrayItem } from '../shared_imports'; export const createFilter = (filterQuery: ESQuery | string | undefined) => isString(filterQuery) ? filterQuery : JSON.stringify(filterQuery); @@ -44,7 +43,7 @@ export const getInspectResponse = ( response != null ? [JSON.stringify(response.rawResponse, null, 2)] : prevResponse?.response, }); -export const prepareEcsFieldsToValidate = (ecsMapping: ArrayItem[]): string[] => +export const prepareEcsFieldsToValidate = (ecsMapping: Array<{ id: string }>): string[] => ecsMapping ?.map((_: unknown, index: number) => [ `ecs_mapping[${index}].result.value`, diff --git a/x-pack/plugins/osquery/public/common/hooks/use_logs_data_view.tsx b/x-pack/plugins/osquery/public/common/hooks/use_logs_data_view.tsx index 1ac76a54b6729d..cf5a9e42d89117 100644 --- a/x-pack/plugins/osquery/public/common/hooks/use_logs_data_view.tsx +++ b/x-pack/plugins/osquery/public/common/hooks/use_logs_data_view.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { useQuery } from 'react-query'; +import { useQuery } from '@tanstack/react-query'; import type { DataView } from '@kbn/data-plugin/common'; import { useKibana } from '../lib/kibana'; diff --git a/x-pack/plugins/osquery/public/common/hooks/use_osquery_integration.tsx b/x-pack/plugins/osquery/public/common/hooks/use_osquery_integration.tsx index 92f32d6535b4c9..4602b8df24d788 100644 --- a/x-pack/plugins/osquery/public/common/hooks/use_osquery_integration.tsx +++ b/x-pack/plugins/osquery/public/common/hooks/use_osquery_integration.tsx @@ -6,7 +6,7 @@ */ import { i18n } from '@kbn/i18n'; -import { useQuery } from 'react-query'; +import { useQuery } from '@tanstack/react-query'; import { useKibana } from '../lib/kibana'; import { useErrorToast } from './use_error_toast'; @@ -16,7 +16,7 @@ export const useOsqueryIntegrationStatus = () => { const setErrorToast = useErrorToast(); return useQuery( - 'integration', + ['integration'], () => http.get<{ name: string; version: string; title: string; install_status: string }>( '/internal/osquery/status' diff --git a/x-pack/plugins/osquery/public/common/validations.ts b/x-pack/plugins/osquery/public/common/validations.ts deleted file mode 100644 index 4a29d274fcc0c5..00000000000000 --- a/x-pack/plugins/osquery/public/common/validations.ts +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { i18n } from '@kbn/i18n'; - -import type { FormData, ValidationFunc } from '../shared_imports'; -import { fieldValidators } from '../shared_imports'; - -export const queryFieldValidation: ValidationFunc = - fieldValidators.emptyField( - i18n.translate('xpack.osquery.pack.queryFlyoutForm.emptyQueryError', { - defaultMessage: 'Query is a required field', - }) - ); diff --git a/x-pack/plugins/osquery/public/editor/index.tsx b/x-pack/plugins/osquery/public/editor/index.tsx index 2c6a505af55cda..583e3558354e81 100644 --- a/x-pack/plugins/osquery/public/editor/index.tsx +++ b/x-pack/plugins/osquery/public/editor/index.tsx @@ -7,12 +7,12 @@ import React, { useEffect, useState } from 'react'; import useDebounce from 'react-use/lib/useDebounce'; -import 'brace/theme/tomorrow'; import type { EuiCodeEditorProps } from '../shared_imports'; import { EuiCodeEditor } from '../shared_imports'; import './osquery_mode'; +import 'brace/theme/tomorrow'; const EDITOR_SET_OPTIONS = { enableBasicAutocompletion: true, diff --git a/x-pack/plugins/osquery/public/form/index.ts b/x-pack/plugins/osquery/public/form/index.ts new file mode 100644 index 00000000000000..31ea2ac171c884 --- /dev/null +++ b/x-pack/plugins/osquery/public/form/index.ts @@ -0,0 +1,12 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { VersionField } from './version_field'; +export { QueryDescriptionField } from './query_description_field'; +export { IntervalField } from './interval_field'; +export { QueryIdField } from './query_id_field'; +export type { FormField } from './types'; diff --git a/x-pack/plugins/osquery/public/form/interval_field.tsx b/x-pack/plugins/osquery/public/form/interval_field.tsx new file mode 100644 index 00000000000000..d8d1a01804d657 --- /dev/null +++ b/x-pack/plugins/osquery/public/form/interval_field.tsx @@ -0,0 +1,82 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import React, { useCallback, useMemo } from 'react'; + +import { useController } from 'react-hook-form'; +import type { EuiFieldNumberProps } from '@elastic/eui'; +import { EuiFieldNumber, EuiFormRow } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; + +const intervalFieldValidations = { + required: { + message: i18n.translate('xpack.osquery.pack.queryFlyoutForm.intervalFieldMinNumberError', { + defaultMessage: 'A positive interval value is required', + }), + value: true, + }, + min: { + message: i18n.translate('xpack.osquery.pack.queryFlyoutForm.intervalFieldMinNumberError', { + defaultMessage: 'A positive interval value is required', + }), + value: 1, + }, + max: { + message: i18n.translate('xpack.osquery.pack.queryFlyoutForm.intervalFieldMaxNumberError', { + defaultMessage: 'An interval value must be lower than {than}', + values: { than: 604800 }, + }), + value: 604800, + }, +}; + +interface IntervalFieldProps { + euiFieldProps?: Record; +} + +const IntervalFieldComponent = ({ euiFieldProps }: IntervalFieldProps) => { + const { + field: { onChange, value }, + fieldState: { error }, + } = useController({ + name: 'interval', + defaultValue: 3600, + rules: { + ...intervalFieldValidations, + }, + }); + const handleChange = useCallback( + (e: React.ChangeEvent) => { + const numberValue = e.target.valueAsNumber ? e.target.valueAsNumber : 0; + onChange(numberValue); + }, + [onChange] + ); + const hasError = useMemo(() => !!error?.message, [error?.message]); + + return ( + + + + ); +}; + +export const IntervalField = React.memo(IntervalFieldComponent); diff --git a/x-pack/plugins/osquery/public/form/query_description_field.tsx b/x-pack/plugins/osquery/public/form/query_description_field.tsx new file mode 100644 index 00000000000000..ae4a216b603f57 --- /dev/null +++ b/x-pack/plugins/osquery/public/form/query_description_field.tsx @@ -0,0 +1,49 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import React, { useMemo } from 'react'; +import { useController } from 'react-hook-form'; +import { EuiFieldText, EuiFormRow } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; + +interface QueryDescriptionFieldProps { + euiFieldProps?: Record; +} + +const QueryDescriptionFieldComponentn = ({ euiFieldProps }: QueryDescriptionFieldProps) => { + const { + field: { onChange, value, name: fieldName }, + fieldState: { error }, + } = useController({ + name: 'description', + defaultValue: '', + }); + + const hasError = useMemo(() => !!error?.message, [error?.message]); + + return ( + + + + ); +}; + +export const QueryDescriptionField = React.memo(QueryDescriptionFieldComponentn); diff --git a/x-pack/plugins/osquery/public/form/query_id_field.tsx b/x-pack/plugins/osquery/public/form/query_id_field.tsx new file mode 100644 index 00000000000000..1c0abfde5113ff --- /dev/null +++ b/x-pack/plugins/osquery/public/form/query_id_field.tsx @@ -0,0 +1,52 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import React, { useMemo } from 'react'; +import { useController } from 'react-hook-form'; +import { EuiFieldText, EuiFormRow } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { createFormIdFieldValidations } from '../packs/queries/validations'; + +interface QueryIdFieldProps { + idSet?: Set; + euiFieldProps?: Record; +} + +const QueryIdFieldComponentn = ({ idSet, euiFieldProps }: QueryIdFieldProps) => { + const { + field: { onChange, value, name: fieldName }, + fieldState: { error }, + } = useController({ + name: 'id', + defaultValue: '', + rules: idSet && createFormIdFieldValidations(idSet), + }); + + const hasError = useMemo(() => !!error?.message, [error?.message]); + + return ( + + + + ); +}; + +export const QueryIdField = React.memo(QueryIdFieldComponentn); diff --git a/x-pack/plugins/osquery/public/form/types.ts b/x-pack/plugins/osquery/public/form/types.ts new file mode 100644 index 00000000000000..14f013ac2b012b --- /dev/null +++ b/x-pack/plugins/osquery/public/form/types.ts @@ -0,0 +1,28 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type React from 'react'; +import type { ReactNode } from 'react'; + +export interface FormField { + name: string; + onChange: (data: T) => void; + value: T; + onBlur?: () => void; +} + +export interface FormFieldProps { + name: string; + label: string | Element; + labelAppend?: ReactNode; + helpText?: string | (() => React.ReactNode); + idAria?: string; + euiFieldProps?: Record; + defaultValue?: T; + required?: boolean; + rules?: Record; +} diff --git a/x-pack/plugins/osquery/public/form/version_field.tsx b/x-pack/plugins/osquery/public/form/version_field.tsx new file mode 100644 index 00000000000000..f97e26b79a6510 --- /dev/null +++ b/x-pack/plugins/osquery/public/form/version_field.tsx @@ -0,0 +1,88 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { useCallback, useMemo } from 'react'; +import { i18n } from '@kbn/i18n'; +import type { EuiComboBoxOptionOption } from '@elastic/eui'; +import { EuiFormRow, EuiComboBox, EuiFlexGroup, EuiFlexItem, EuiText } from '@elastic/eui'; +import { useController } from 'react-hook-form'; +import { FormattedMessage } from '@kbn/i18n-react'; + +interface VersionFieldProps { + euiFieldProps?: Record; +} +const VersionFieldComponent = ({ euiFieldProps = {} }: VersionFieldProps) => { + const { + field: { onChange, value }, + fieldState: { error }, + } = useController({ + name: 'version', + defaultValue: [], + rules: {}, + }); + + const onCreateComboOption = useCallback( + (newValue: string) => { + const result = [...(value as string[]), newValue]; + + onChange(result); + }, + [onChange, value] + ); + + const onComboChange = useCallback( + (options: EuiComboBoxOptionOption[]) => { + onChange(options.map((option) => option.label)); + }, + [onChange] + ); + const hasError = useMemo(() => !!error?.message, [error?.message]); + + return ( + + + + + + } + labelAppend={ + + + + + + } + error={error?.message} + isInvalid={hasError} + fullWidth + > + ({ label: v }))} + onCreateOption={onCreateComboOption} + onChange={onComboChange} + fullWidth + data-test-subj="input" + {...euiFieldProps} + /> + + ); +}; + +export const VersionField = React.memo(VersionFieldComponent); diff --git a/x-pack/plugins/osquery/public/live_queries/form/agents_table_field.tsx b/x-pack/plugins/osquery/public/live_queries/form/agents_table_field.tsx index b4fd3bdaf216c8..eab43c5982b801 100644 --- a/x-pack/plugins/osquery/public/live_queries/form/agents_table_field.tsx +++ b/x-pack/plugins/osquery/public/live_queries/form/agents_table_field.tsx @@ -5,27 +5,47 @@ * 2.0. */ -import React, { useCallback } from 'react'; -import type { FieldHook } from '../../shared_imports'; +import React from 'react'; +import { useController } from 'react-hook-form'; +import { isEmpty } from 'lodash'; +import { i18n } from '@kbn/i18n'; import { AgentsTable } from '../../agents/agents_table'; import type { AgentSelection } from '../../agents/types'; -interface AgentsTableFieldProps { - field: FieldHook; -} +const checkAgentsLength = (agentsSelection: AgentSelection) => { + if (!isEmpty(agentsSelection)) { + const isValid = !!( + agentsSelection.allAgentsSelected || + agentsSelection.agents?.length || + agentsSelection.platformsSelected?.length || + agentsSelection.policiesSelected?.length + ); -const AgentsTableFieldComponent: React.FC = ({ field }) => { - const { value, setValue } = field; - const handleChange = useCallback( - (props) => { - if (props !== value) { - return setValue(props); - } + return !isValid + ? i18n.translate('xpack.osquery.pack.queryFlyoutForm.osqueryAgentsMissingErrorMessage', { + defaultMessage: 'Agents is a required field', + }) + : undefined; + } + + return i18n.translate('xpack.osquery.pack.queryFlyoutForm.osqueryAgentsMissingErrorMessage', { + defaultMessage: 'Agents is a required field', + }); +}; + +const AgentsTableFieldComponent: React.FC<{}> = () => { + const { + field: { onChange, value }, + fieldState: { error }, + } = useController({ + name: 'agentSelection', + rules: { + validate: checkAgentsLength, }, - [value, setValue] - ); + defaultValue: {}, + }); - return ; + return ; }; export const AgentsTableField = React.memo(AgentsTableFieldComponent); diff --git a/x-pack/plugins/osquery/public/live_queries/form/index.tsx b/x-pack/plugins/osquery/public/live_queries/form/index.tsx index ed4059884a9af5..3ed54c451f38b9 100644 --- a/x-pack/plugins/osquery/public/live_queries/form/index.tsx +++ b/x-pack/plugins/osquery/public/live_queries/form/index.tsx @@ -19,27 +19,47 @@ import { import { FormattedMessage } from '@kbn/i18n-react'; import React, { useCallback, useEffect, useMemo, useState } from 'react'; import styled from 'styled-components'; +import { useForm as useHookForm, FormProvider } from 'react-hook-form'; -import { pickBy, isEmpty, map, find } from 'lodash'; +import { isEmpty, map, find, pickBy } from 'lodash'; import { i18n } from '@kbn/i18n'; +import type { SavedQuerySOFormData } from '../../saved_queries/form/use_saved_query_form'; +import type { + EcsMappingFormField, + EcsMappingSerialized, +} from '../../packs/queries/ecs_mapping_editor_field'; +import { defaultEcsFormData } from '../../packs/queries/ecs_mapping_editor_field'; import { convertECSMappingToObject } from '../../../common/schemas/common/utils'; -import type { FormData } from '../../shared_imports'; -import { UseField, Form, useForm, useFormData } from '../../shared_imports'; -import { AgentsTableField } from './agents_table_field'; -import { LiveQueryQueryField } from './live_query_query_field'; import { useKibana } from '../../common/lib/kibana'; import { ResultTabs } from '../../routes/saved_queries/edit/tabs'; import { SavedQueryFlyout } from '../../saved_queries'; import { ECSMappingEditorField } from '../../packs/queries/lazy_ecs_mapping_editor_field'; import { SavedQueriesDropdown } from '../../saved_queries/saved_queries_dropdown'; -import { liveQueryFormSchema } from './schema'; import { usePacks } from '../../packs/use_packs'; import { PackQueriesStatusTable } from './pack_queries_status_table'; import { useCreateLiveQuery } from '../use_create_live_query_action'; import { useLiveQueryDetails } from '../../actions/use_live_query_details'; +import type { AgentSelection } from '../../agents/types'; +import { LiveQueryQueryField } from './live_query_query_field'; +import { AgentsTableField } from './agents_table_field'; import { PacksComboBoxField } from './packs_combobox_field'; +import { savedQueryDataSerializer } from '../../saved_queries/form/use_saved_query_form'; + +export interface LiveQueryFormFields { + query?: string; + agentSelection: AgentSelection; + savedQueryId?: string | null; + ecs_mapping: EcsMappingFormField[]; + packId: string[]; +} -const FORM_ID = 'liveQueryForm'; +interface DefaultLiveQueryFormFields { + query?: string; + agentSelection?: AgentSelection; + savedQueryId?: string | null; + ecs_mapping?: EcsMappingSerialized; + packId?: string; +} const StyledEuiCard = styled(EuiCard)` padding: 16px 92px 16px 16px !important; @@ -86,12 +106,10 @@ const StyledEuiAccordion = styled(EuiAccordion)` } `; -const GhostFormField = () => <>; - type FormType = 'simple' | 'steps'; interface LiveQueryFormProps { - defaultValue?: Partial; + defaultValue?: DefaultLiveQueryFormFields; onSuccess?: () => void; queryField?: boolean; ecsMappingField?: boolean; @@ -118,6 +136,22 @@ const LiveQueryFormComponent: React.FC = ({ [permissions] ); + const hooksForm = useHookForm({ + defaultValues: { + ecs_mapping: [defaultEcsFormData], + }, + }); + const { + handleSubmit, + watch, + setValue, + resetField, + clearErrors, + getFieldState, + register, + formState: { isSubmitting, errors }, + } = hooksForm; + const canRunSingleQuery = useMemo( () => !!( @@ -133,6 +167,8 @@ const LiveQueryFormComponent: React.FC = ({ const [queryType, setQueryType] = useState('query'); const [isLive, setIsLive] = useState(false); + const queryState = getFieldState('query'); + const watchedValues = watch(); const handleShowSaveQueryFlyout = useCallback(() => setShowSavedQueryFlyout(true), []); const handleCloseSaveQueryFlyout = useCallback(() => setShowSavedQueryFlyout(false), []); @@ -150,75 +186,22 @@ const LiveQueryFormComponent: React.FC = ({ isLive, }); - const { form } = useForm({ - id: FORM_ID, - schema: liveQueryFormSchema, - onSubmit: async (formData, isValid) => { - if (isValid) { - try { - // @ts-expect-error update types - await mutateAsync(formData); - // eslint-disable-next-line no-empty - } catch (e) {} - } - }, - options: { - stripEmptyFields: false, - }, - serializer: ({ - savedQueryId, - // eslint-disable-next-line @typescript-eslint/naming-convention - ecs_mapping, - packId, - ...formData - }) => - pickBy( - { - ...formData, - pack_id: packId?.length ? packId[0] : undefined, - saved_query_id: savedQueryId, - ecs_mapping: convertECSMappingToObject(ecs_mapping), - }, - (value) => !isEmpty(value) - ), - }); - - const { updateFieldValues, setFieldValue, submit, isSubmitting } = form; - const actionId = useMemo(() => liveQueryDetails?.action_id, [liveQueryDetails?.action_id]); const agentIds = useMemo(() => liveQueryDetails?.agents, [liveQueryDetails?.agents]); - const [ - { agentSelection, ecs_mapping: ecsMapping, query, savedQueryId, packId }, - formDataSerializer, - ] = useFormData({ - form, - }); - /* recalculate the form data when ecs_mapping changes */ - // eslint-disable-next-line react-hooks/exhaustive-deps - const serializedFormData = useMemo(() => formDataSerializer(), [ecsMapping, formDataSerializer]); - - const agentSelected = useMemo( - () => - agentSelection && - !!( - agentSelection.allAgentsSelected || - agentSelection.agents?.length || - agentSelection.platformsSelected?.length || - agentSelection.policiesSelected?.length - ), - [agentSelection] - ); + useEffect(() => { + register('savedQueryId'); + }, [register]); - const queryValueProvided = useMemo(() => !!query?.length, [query]); + const { packId } = watchedValues; const queryStatus = useMemo(() => { - if (isError || !form.getFields().query?.isValid) return 'danger'; + if (isError || queryState.invalid) return 'danger'; if (isLoading) return 'loading'; if (isSuccess) return 'complete'; return 'incomplete'; - }, [isError, isLoading, isSuccess, form]); + }, [isError, isLoading, isSuccess, queryState]); const resultsStatus = useMemo( () => (queryStatus === 'complete' ? 'incomplete' : 'disabled'), @@ -228,39 +211,66 @@ const LiveQueryFormComponent: React.FC = ({ const handleSavedQueryChange = useCallback( (savedQuery) => { if (savedQuery) { - updateFieldValues({ - query: savedQuery.query, - savedQueryId: savedQuery.savedQueryId, - ecs_mapping: savedQuery.ecs_mapping + setValue('query', savedQuery.query); + setValue('savedQueryId', savedQuery.savedQueryId); + setValue( + 'ecs_mapping', + !isEmpty(savedQuery.ecs_mapping) ? map(savedQuery.ecs_mapping, (value, key) => ({ key, result: { type: Object.keys(value)[0], - value: Object.values(value)[0], + value: Object.values(value)[0] as string, }, })) - : [], - }); + : [defaultEcsFormData] + ); if (!isEmpty(savedQuery.ecs_mapping)) { setAdvancedContentState('open'); } } else { - setFieldValue('savedQueryId', null); + setValue('savedQueryId', null); } }, - [setFieldValue, updateFieldValues] + [setValue] ); + const onSubmit = useCallback( + // not sure why, but submitOnCmdEnter doesn't have proper form values so I am passing them in manually + async (values: LiveQueryFormFields = watchedValues) => { + const serializedData = pickBy( + { + agentSelection: values.agentSelection, + saved_query_id: values.savedQueryId, + query: values.query, + pack_id: packId?.length ? packId[0] : undefined, + ...(values.ecs_mapping + ? { ecs_mapping: convertECSMappingToObject(values.ecs_mapping) } + : {}), + }, + (value) => !isEmpty(value) + ); + if (isEmpty(errors)) { + try { + // @ts-expect-error update types + await mutateAsync(serializedData); + // eslint-disable-next-line no-empty + } catch (e) {} + } + }, + [errors, mutateAsync, packId, watchedValues] + ); const commands = useMemo( () => [ { name: 'submitOnCmdEnter', bindKey: { win: 'ctrl+enter', mac: 'cmd+enter' }, - exec: () => submit(), + // @ts-expect-error update types - explanation in onSubmit() + exec: () => handleSubmit(onSubmit)(watchedValues), }, ], - [submit] + [handleSubmit, onSubmit, watchedValues] ); const queryComponentProps = useMemo( @@ -270,9 +280,9 @@ const LiveQueryFormComponent: React.FC = ({ [commands] ); - const flyoutFormDefaultValue = useMemo( - () => ({ savedQueryId, query, ecs_mapping: serializedFormData.ecs_mapping }), - [savedQueryId, serializedFormData.ecs_mapping, query] + const serializedData: SavedQuerySOFormData = useMemo( + () => savedQueryDataSerializer(watchedValues), + [watchedValues] ); const handleToggle = useCallback((isOpen) => { @@ -306,12 +316,7 @@ const LiveQueryFormComponent: React.FC = ({ {formType === 'steps' && queryType !== 'pack' && ( = ({ = ({ ), [ - agentSelected, - enabled, formType, - handleShowSaveQueryFlyout, - isSubmitting, - packId, - permissions.writeSavedQueries, queryType, - queryValueProvided, + permissions.writeSavedQueries, resultsStatus, - selectedPackData, - submit, + handleShowSaveQueryFlyout, + enabled, + isSubmitting, + handleSubmit, + onSubmit, ] ); const queryFieldStepContent = useMemo( () => ( <> - {queryField ? ( + {queryField && ( <> {!isSavedQueryDisabled && ( <> @@ -372,20 +367,10 @@ const LiveQueryFormComponent: React.FC = ({ /> )} - - - - ) : ( - <> - - + )} - {ecsMappingField ? ( + {ecsMappingField && ( <> = ({ - ) : ( - )} ), [ queryField, - queryComponentProps, + isSavedQueryDisabled, handleSavedQueryChange, + queryComponentProps, + queryType, ecsMappingField, advancedContentState, handleToggle, ecsFieldProps, - isSavedQueryDisabled, ] ); @@ -422,7 +406,7 @@ const LiveQueryFormComponent: React.FC = ({ singleQueryDetails?.action_id ? ( = ({ singleQueryDetails?.action_id, singleQueryDetails?.expiration, singleQueryDetails?.agents, - serializedFormData.ecs_mapping, + serializedData.ecs_mapping, addToTimeline, ] ); @@ -440,9 +424,7 @@ const LiveQueryFormComponent: React.FC = ({ useEffect(() => { if (defaultValue) { if (defaultValue.agentSelection) { - updateFieldValues({ - agentSelection: defaultValue.agentSelection, - }); + setValue('agentSelection', defaultValue.agentSelection); } if (defaultValue?.packId && canRunPacks) { @@ -451,19 +433,18 @@ const LiveQueryFormComponent: React.FC = ({ if (!isPackDataFetched) return; const selectedPackOption = find(packsData?.data, ['id', defaultValue.packId]); if (selectedPackOption) { - updateFieldValues({ - packId: [defaultValue.packId], - }); + setValue('packId', [defaultValue.packId]); } return; } if (defaultValue?.query && canRunSingleQuery) { - updateFieldValues({ - query: defaultValue.query, - savedQueryId: defaultValue.savedQueryId, - ecs_mapping: defaultValue.ecs_mapping + setValue('query', defaultValue.query); + setValue('savedQueryId', defaultValue.savedQueryId); + setValue( + 'ecs_mapping', + !isEmpty(defaultValue.ecs_mapping) ? map(defaultValue.ecs_mapping, (value, key) => ({ key, result: { @@ -471,8 +452,8 @@ const LiveQueryFormComponent: React.FC = ({ value: Object.values(value)[0], }, })) - : undefined, - }); + : [defaultEcsFormData] + ); return; } @@ -485,14 +466,7 @@ const LiveQueryFormComponent: React.FC = ({ return setQueryType('pack'); } } - }, [ - canRunPacks, - canRunSingleQuery, - defaultValue, - isPackDataFetched, - packsData?.data, - updateFieldValues, - ]); + }, [canRunPacks, canRunSingleQuery, defaultValue, isPackDataFetched, packsData?.data, setValue]); const queryCardSelectable = useMemo( () => ({ @@ -516,11 +490,20 @@ const LiveQueryFormComponent: React.FC = ({ setIsLive(() => !(liveQueryDetails?.status === 'completed')); }, [liveQueryDetails?.status]); - useEffect(() => cleanupLiveQuery(), [queryType, packId, cleanupLiveQuery]); + useEffect(() => { + cleanupLiveQuery(); + if (!defaultValue) { + resetField('packId'); + resetField('query'); + resetField('ecs_mapping'); + resetField('savedQueryId'); + clearErrors(); + } + }, [queryType, cleanupLiveQuery, resetField, setValue, clearErrors, defaultValue]); return ( <> -
+ {queryField && ( @@ -572,25 +555,23 @@ const LiveQueryFormComponent: React.FC = ({ )} - {!hideAgentsField ? ( + {!hideAgentsField && ( - + - ) : ( - )} {queryType === 'pack' ? ( <> - {submitButtonContent} + {liveQueryDetails?.queries?.length || selectedPackData?.attributes?.queries?.length ? ( <> @@ -598,6 +579,7 @@ const LiveQueryFormComponent: React.FC = ({ @@ -613,12 +595,13 @@ const LiveQueryFormComponent: React.FC = ({ )} - +
+ {showSavedQueryFlyout ? ( ) : null} diff --git a/x-pack/plugins/osquery/public/live_queries/form/live_query_query_field.tsx b/x-pack/plugins/osquery/public/live_queries/form/live_query_query_field.tsx index 86775040c7f73b..e3516f982cc0b3 100644 --- a/x-pack/plugins/osquery/public/live_queries/form/live_query_query_field.tsx +++ b/x-pack/plugins/osquery/public/live_queries/form/live_query_query_field.tsx @@ -6,12 +6,15 @@ */ import { EuiCodeBlock, EuiFormRow } from '@elastic/eui'; -import React, { useCallback } from 'react'; +import React from 'react'; import styled from 'styled-components'; -import type { EuiCodeEditorProps, FieldHook } from '../../shared_imports'; +import { useController } from 'react-hook-form'; +import { i18n } from '@kbn/i18n'; +import type { EuiCodeEditorProps } from '../../shared_imports'; import { OsqueryEditor } from '../../editor'; import { useKibana } from '../../common/lib/kibana'; +import { MAX_QUERY_LENGTH } from '../../packs/queries/validations'; const StyledEuiCodeBlock = styled(EuiCodeBlock)` min-height: 100px; @@ -19,30 +22,44 @@ const StyledEuiCodeBlock = styled(EuiCodeBlock)` interface LiveQueryQueryFieldProps { disabled?: boolean; - field: FieldHook; commands?: EuiCodeEditorProps['commands']; + queryType: string; } const LiveQueryQueryFieldComponent: React.FC = ({ disabled, - field, commands, + queryType, }) => { const permissions = useKibana().services.application.capabilities.osquery; - const { value, setValue, errors } = field; - const error = errors[0]?.message; - const handleEditorChange = useCallback( - (newValue) => { - setValue(newValue); + const { + field: { onChange, value }, + fieldState: { error }, + } = useController({ + name: 'query', + rules: { + required: { + message: i18n.translate('xpack.osquery.pack.queryFlyoutForm.emptyQueryError', { + defaultMessage: 'Query is a required field', + }), + value: queryType === 'query', + }, + maxLength: { + message: i18n.translate('xpack.osquery.liveQuery.queryForm.largeQueryError', { + defaultMessage: 'Query is too large (max {maxLength} characters)', + values: { maxLength: MAX_QUERY_LENGTH }, + }), + value: MAX_QUERY_LENGTH, + }, }, - [setValue] - ); + defaultValue: '', + }); return ( @@ -56,7 +73,7 @@ const LiveQueryQueryFieldComponent: React.FC = ({ {value} ) : ( - + )} ); diff --git a/x-pack/plugins/osquery/public/live_queries/form/packs_combobox_field.tsx b/x-pack/plugins/osquery/public/live_queries/form/packs_combobox_field.tsx index e9cf7fa6f9e85b..0d6c93d23ed306 100644 --- a/x-pack/plugins/osquery/public/live_queries/form/packs_combobox_field.tsx +++ b/x-pack/plugins/osquery/public/live_queries/form/packs_combobox_field.tsx @@ -12,8 +12,7 @@ import type { EuiComboBoxOptionOption } from '@elastic/eui'; import { EuiFormRow, EuiComboBox, EuiTextColor, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import styled from 'styled-components'; -import type { FieldHook } from '../../shared_imports'; -import { VALIDATION_TYPES } from '../../shared_imports'; +import { useController } from 'react-hook-form'; import type { PackSavedObject } from '../../packs/types'; const TextTruncate = styled.div` @@ -21,13 +20,12 @@ const TextTruncate = styled.div` text-overflow: ellipsis; `; -interface Props { - field: FieldHook; - euiFieldProps?: { +interface PackComboBoxFieldProps { + fieldProps?: { packsData?: PackSavedObject[]; }; idAria?: string; - [key: string]: unknown; + queryType: string; } interface PackOption { @@ -36,48 +34,53 @@ interface PackOption { description?: string; } -export const PacksComboBoxField = ({ field, euiFieldProps = {}, idAria, ...rest }: Props) => { +export const PacksComboBoxField = ({ + queryType, + fieldProps = {}, + idAria, + ...rest +}: PackComboBoxFieldProps) => { + const { + field: { value, onChange }, + fieldState, + } = useController({ + name: 'packId', + rules: { + required: { + message: i18n.translate( + 'xpack.osquery.pack.queryFlyoutForm.osqueryPackMissingErrorMessage', + { + defaultMessage: 'Pack is a required field', + } + ), + value: queryType === 'pack', + }, + }, + defaultValue: [], + }); + const error = fieldState.error?.message; const [selectedOptions, setSelectedOptions] = useState< Array> >([]); - // Errors for the comboBox value (the "array") - const errorMessageField = field.getErrorsMessages(); - - // Errors for comboBox option added (the array "item") - const errorMessageArrayItem = field.getErrorsMessages({ - validationType: VALIDATION_TYPES.ARRAY_ITEM, - }); - - const isInvalid = field.errors.length - ? errorMessageField !== null || errorMessageArrayItem !== null - : false; - - // Concatenate error messages. - const errorMessage = - errorMessageField && errorMessageArrayItem - ? `${errorMessageField}, ${errorMessageArrayItem}` - : errorMessageField - ? errorMessageField - : errorMessageArrayItem; const handlePackChange = useCallback( (newSelectedOptions) => { if (!newSelectedOptions.length) { setSelectedOptions(newSelectedOptions); - field.setValue([]); + onChange([]); return; } setSelectedOptions(newSelectedOptions); - field.setValue([newSelectedOptions[0].value?.id]); + onChange([newSelectedOptions[0].value?.id]); }, - [field] + [onChange] ); const packOptions = useMemo>>( () => - euiFieldProps?.packsData?.map((packSO) => ({ + fieldProps?.packsData?.map((packSO) => ({ label: packSO.attributes.name ?? '', value: { id: packSO.id, @@ -85,20 +88,11 @@ export const PacksComboBoxField = ({ field, euiFieldProps = {}, idAria, ...rest description: packSO.attributes.description, }, })) ?? [], - [euiFieldProps?.packsData] - ); - - const onSearchComboChange = useCallback( - (value: string) => { - if (value !== undefined) { - field.clearErrors(VALIDATION_TYPES.ARRAY_ITEM); - } - }, - [field] + [fieldProps?.packsData] ); const renderOption = useCallback( - ({ value }) => ( + ({ value: option }) => ( - {value.name} + {option?.name} - {value.description} + {option?.description} @@ -119,22 +113,22 @@ export const PacksComboBoxField = ({ field, euiFieldProps = {}, idAria, ...rest ); useEffect(() => { - if (field.value.length) { - const packOption = find(packOptions, ['value.id', field.value[0]]); + if (value?.length) { + const packOption = find(packOptions, ['value.id', value[0]]); if (packOption) { setSelectedOptions([packOption]); } } - }, [field.value, packOptions]); + }, [value, packOptions]); return ( ); diff --git a/x-pack/plugins/osquery/public/live_queries/form/schema.ts b/x-pack/plugins/osquery/public/live_queries/form/schema.ts deleted file mode 100644 index c09eccd1c5c881..00000000000000 --- a/x-pack/plugins/osquery/public/live_queries/form/schema.ts +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -export const MAX_QUERY_LENGTH = 2000; - -import { i18n } from '@kbn/i18n'; -import { FIELD_TYPES } from '../../shared_imports'; -import { queryFieldValidation } from '../../common/validations'; -import { fieldValidators } from '../../shared_imports'; - -export const liveQueryFormSchema = { - agentSelection: { - defaultValue: { - agents: [], - allAgentsSelected: false, - platformsSelected: [], - policiesSelected: [], - }, - type: FIELD_TYPES.JSON, - validations: [], - }, - savedQueryId: { - type: FIELD_TYPES.TEXT, - validations: [], - }, - query: { - defaultValue: '', - type: FIELD_TYPES.TEXT, - validations: [ - { - validator: fieldValidators.maxLengthField({ - length: MAX_QUERY_LENGTH, - message: i18n.translate('xpack.osquery.liveQuery.queryForm.largeQueryError', { - defaultMessage: 'Query is too large (max {maxLength} characters)', - values: { maxLength: MAX_QUERY_LENGTH }, - }), - }), - }, - { validator: queryFieldValidation }, - ], - }, - packId: { - label: i18n.translate('xpack.osquery.packs.dropdown.searchFieldLabel', { - defaultMessage: `Pack`, - }), - type: FIELD_TYPES.COMBO_BOX, - defaultValue: [], - }, - ecs_mapping: { - defaultValue: [], - type: FIELD_TYPES.JSON, - }, -}; diff --git a/x-pack/plugins/osquery/public/live_queries/index.tsx b/x-pack/plugins/osquery/public/live_queries/index.tsx index 22aa3be77c2a71..746687f4b644b7 100644 --- a/x-pack/plugins/osquery/public/live_queries/index.tsx +++ b/x-pack/plugins/osquery/public/live_queries/index.tsx @@ -10,6 +10,7 @@ import { EuiCode, EuiLoadingContent, EuiEmptyPrompt } from '@elastic/eui'; import React, { useMemo } from 'react'; import { FormattedMessage } from '@kbn/i18n-react'; +import type { EcsMappingSerialized } from '../packs/queries/ecs_mapping_editor_field'; import { LiveQueryForm } from './form'; import { useActionResultsPrivileges } from '../action_results/use_action_privileges'; import { OSQUERY_INTEGRATION_NAME } from '../../common'; @@ -23,7 +24,7 @@ interface LiveQueryProps { onSuccess?: () => void; query?: string; savedQueryId?: string; - ecs_mapping?: unknown; + ecs_mapping?: EcsMappingSerialized; agentsField?: boolean; queryField?: boolean; ecsMappingField?: boolean; diff --git a/x-pack/plugins/osquery/public/live_queries/use_create_live_query_action.tsx b/x-pack/plugins/osquery/public/live_queries/use_create_live_query_action.tsx index 72ac627b02a63f..dfb08ddeda87db 100644 --- a/x-pack/plugins/osquery/public/live_queries/use_create_live_query_action.tsx +++ b/x-pack/plugins/osquery/public/live_queries/use_create_live_query_action.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { useMutation } from 'react-query'; +import { useMutation } from '@tanstack/react-query'; import type { AgentSelection } from '../../common/schemas/common'; import type { CreateLiveQueryRequestBodySchema } from '../../common/schemas/routes/live_query'; import { useKibana } from '../common/lib/kibana'; diff --git a/x-pack/plugins/osquery/public/packs/active_state_switch.tsx b/x-pack/plugins/osquery/public/packs/active_state_switch.tsx index 41f7c7a32522e7..cb67f248207fc7 100644 --- a/x-pack/plugins/osquery/public/packs/active_state_switch.tsx +++ b/x-pack/plugins/osquery/public/packs/active_state_switch.tsx @@ -7,7 +7,7 @@ import { EuiSwitch, EuiLoadingSpinner } from '@elastic/eui'; import React, { useCallback, useMemo, useState } from 'react'; -import { useQueryClient } from 'react-query'; +import { useQueryClient } from '@tanstack/react-query'; import styled from 'styled-components'; import { i18n } from '@kbn/i18n'; @@ -55,7 +55,7 @@ const ActiveStateSwitchComponent: React.FC = ({ item }) const { isLoading, mutateAsync } = useUpdatePack({ options: { onSuccess: (response) => { - queryClient.invalidateQueries(PACKS_ID); + queryClient.invalidateQueries([PACKS_ID]); setErrorToast(); toasts.addSuccess( response?.data?.attributes.enabled diff --git a/x-pack/plugins/osquery/public/packs/form/queries_field.tsx b/x-pack/plugins/osquery/public/packs/form/queries_field.tsx index bff3e30a901c17..62f5c9c7e7e934 100644 --- a/x-pack/plugins/osquery/public/packs/form/queries_field.tsx +++ b/x-pack/plugins/osquery/public/packs/form/queries_field.tsx @@ -93,6 +93,7 @@ const QueriesFieldComponent: React.FC = ({ if (updatedQuery.ecs_mapping) { draft[showEditQueryFlyout].ecs_mapping = updatedQuery.ecs_mapping; } else { + // @ts-expect-error update types delete draft[showEditQueryFlyout].ecs_mapping; } @@ -231,6 +232,7 @@ const QueriesFieldComponent: React.FC = ({ {showEditQueryFlyout != null && showEditQueryFlyout >= 0 && ( ; const typeMap = { binary: 'binary', @@ -80,17 +85,6 @@ const typeMap = { constant_keyword: 'string', }; -const StyledEuiSuperSelect = styled(EuiSuperSelect)` - min-width: 70px; - border-radius: 6px 0 0 6px; - - .euiIcon { - padding: 0; - width: 18px; - background: none; - } -`; - // @ts-expect-error update types const ResultComboBox = styled(EuiComboBox)` &.euiComboBox { @@ -103,6 +97,17 @@ const ResultComboBox = styled(EuiComboBox)` } `; +const StyledEuiSuperSelect = styled(EuiSuperSelect)` + min-width: 70px; + border-radius: 6px 0 0 6px; + + .euiIcon { + padding: 0; + width: 18px; + background: none; + } +`; + const StyledFieldIcon = styled(FieldIcon)` width: 32px; @@ -144,31 +149,32 @@ const ECSSchemaOptions = ECSSchema.map((ecs) => ({ type ECSSchemaOption = typeof ECSSchemaOptions[0]; -interface ECSComboboxFieldProps { - field: FieldHook; +interface ECSComboboxFieldProps extends FormField { euiFieldProps: EuiComboBoxProps; idAria?: string; + error?: string; } const ECSComboboxFieldComponent: React.FC = ({ - field, euiFieldProps = {}, idAria, + onChange, + value, + error, }) => { - const { setValue } = field; const [selectedOptions, setSelected] = useState>>( [] ); - const { isInvalid, errorMessage } = getFieldValidityAndErrorMessage(field); const describedByIds = useMemo(() => (idAria ? [idAria] : []), [idAria]); - const [formData] = useFormData(); - + const { ecs_mapping: watchedEcsMapping } = useWatch() as unknown as { + ecs_mapping: EcsMappingFormField[]; + }; const handleChange = useCallback( (newSelectedOptions) => { setSelected(newSelectedOptions); - setValue(newSelectedOptions[0]?.label ?? ''); + onChange(newSelectedOptions[0]?.label ?? ''); }, - [setValue] + [onChange] ); // TODO: Create own component for this. @@ -230,37 +236,36 @@ const ECSComboboxFieldComponent: React.FC = ({ }, [selectedOptions]); const availableECSSchemaOptions = useMemo(() => { - const currentFormECSFieldValues = map(formData.ecs_mapping, 'key'); + const currentFormECSFieldValues = map(watchedEcsMapping, 'key'); return ECSSchemaOptions.filter(({ label }) => !currentFormECSFieldValues.includes(label)); - }, [formData.ecs_mapping]); + }, [watchedEcsMapping]); useEffect(() => { // @ts-expect-error update types setSelected(() => { - if (!field.value.length) return []; + if (!value?.length) return []; - const selectedOption = find(ECSSchemaOptions, ['label', field.value]); + const selectedOption = find(ECSSchemaOptions, ['label', value]); return selectedOption ? [selectedOption] : [ { - label: field.value, + label: value, value: { - value: field.value, + value, }, }, ]; }); - }, [field.value]); + }, [value]); return ( ; - resultValue: FieldHook; euiFieldProps: EuiComboBoxProps; - item: ArrayItem; + item: EcsMappingFormField; + index: number; idAria?: string; + isLastItem: boolean; } const OsqueryColumnFieldComponent: React.FC = ({ - resultType, - resultValue, - euiFieldProps = {}, + euiFieldProps, idAria, item, + index, + isLastItem, }) => { + const osqueryResultFieldValidator = ( + value: string, + ecsMappingFormData: EcsMappingFormField[] + ): string | undefined => { + const currentMapping = ecsMappingFormData[index]; + + if (!value.length && currentMapping.key.length) { + return i18n.translate( + 'xpack.osquery.pack.queryFlyoutForm.osqueryResultFieldRequiredErrorMessage', + { + defaultMessage: 'Value field is required.', + } + ); + } + + if (!value.length || currentMapping.result.type !== 'field') return; + + const osqueryColumnExists = find(euiFieldProps.options, [ + 'label', + isArray(value) ? value[0] : value, + ]); + + return !osqueryColumnExists + ? i18n.translate( + 'xpack.osquery.pack.queryFlyoutForm.osqueryResultFieldValueMissingErrorMessage', + { + defaultMessage: 'The current query does not return a {columnName} field', + values: { + columnName: value, + }, + } + ) + : undefined; + }; + + const { setValue } = useFormContext(); + const { ecs_mapping: watchedEcsMapping } = useWatch() as unknown as { + ecs_mapping: EcsMappingFormField[]; + }; + + const { field: resultField, fieldState: resultFieldState } = useController({ + name: `ecs_mapping.${index}.result.value`, + rules: { + validate: (data) => osqueryResultFieldValidator(data, watchedEcsMapping), + }, + defaultValue: '', + }); + const itemPath = `ecs_mapping.${index}`; + const resultValue = item.result; const inputRef = useRef(); - const { setValue } = resultValue; - const { value: typeValue, setValue: setType } = resultType; - const { isInvalid, errorMessage } = getFieldValidityAndErrorMessage(resultValue); + const [selectedOptions, setSelected] = useState([]); const describedByIds = useMemo(() => (idAria ? [idAria] : []), [idAria]); - const [selectedOptions, setSelected] = useState< - Array> - >([]); - const [formData] = useFormData(); const renderOsqueryOption = useCallback( (option, searchValue, contentClassName) => ( @@ -365,7 +413,6 @@ const OsqueryColumnFieldComponent: React.FC = ({ {option.value.suggestion_label}
- {option.value.description} @@ -376,37 +423,44 @@ const OsqueryColumnFieldComponent: React.FC = ({ [] ); - const handleChange = useCallback( + const handleKeyChange = useCallback( (newSelectedOptions) => { setSelected(newSelectedOptions); - setValue( + resultField.onChange( isArray(newSelectedOptions) ? map(newSelectedOptions, 'label') : newSelectedOptions[0]?.label ?? '' ); }, - [setValue, setSelected] + [resultField] ); const isSingleSelection = useMemo(() => { - const ecsKey = get(formData, item.path)?.key; - if (ecsKey?.length && typeValue === 'value') { - const ecsKeySchemaOption = find(ECSSchemaOptions, ['label', ecsKey]); + const ecsData = get(watchedEcsMapping, `${index}`); + if (ecsData?.key?.length && item.result.type === 'value') { + const ecsKeySchemaOption = find(ECSSchemaOptions, ['label', ecsData?.key]); return ecsKeySchemaOption?.value?.normalization !== 'array'; } - return !!ecsKey?.length; - }, [typeValue, formData, item.path]); + if (!ecsData?.key?.length && isLastItem) { + return true; + } + + return !!ecsData?.key?.length; + }, [index, isLastItem, item.result.type, watchedEcsMapping]); const onTypeChange = useCallback( (newType) => { - if (newType !== typeValue) { - setType(newType); - setValue(newType === 'value' && isSingleSelection === false ? [] : ''); + if (newType !== item.result.type) { + setValue(`${itemPath}.result.type`, newType); + setValue( + `${itemPath}.result.value`, + newType === 'value' && isSingleSelection === false ? [] : '' + ); } }, - [typeValue, setType, setValue, isSingleSelection] + [isSingleSelection, item.result.type, itemPath, setValue] ); const handleCreateOption = useCallback( @@ -416,19 +470,19 @@ const OsqueryColumnFieldComponent: React.FC = ({ if (!trimmedNewOption.length) return; if (isSingleSelection === false) { - setValue([trimmedNewOption]); - if (resultValue.value.length) { - setValue([...castArray(resultValue.value), trimmedNewOption]); + setValue(`${itemPath}.result.value`, [trimmedNewOption]); + if (item.result.value.length) { + setValue(`${itemPath}.result.value`, [...castArray(resultValue.value), trimmedNewOption]); } else { - setValue([trimmedNewOption]); + setValue(`${itemPath}.result.value`, [trimmedNewOption]); } inputRef.current?.blur(); } else { - setValue(trimmedNewOption); + setValue(`${itemPath}.result.value`, trimmedNewOption); } }, - [isSingleSelection, resultValue.value, setValue] + [isSingleSelection, item.result.value.length, itemPath, resultValue.value, setValue] ); const Prepend = useMemo( @@ -436,7 +490,7 @@ const OsqueryColumnFieldComponent: React.FC = ({ = ({ onChange={onTypeChange} /> ), - [euiFieldProps.isDisabled, onTypeChange, typeValue] + [euiFieldProps.isDisabled, item.result.type, onTypeChange] ); useEffect(() => { if (isSingleSelection && isArray(resultValue.value)) { - setValue(resultValue.value.join(' ')); + setValue(`${itemPath}.result.value`, resultValue.value.join(' ')); } if (!isSingleSelection && !isArray(resultValue.value)) { - setValue(resultValue.value.length ? [resultValue.value] : []); + const value = resultValue.value.length ? [resultValue.value] : []; + setValue(`${itemPath}.result.value`, value); } - }, [isSingleSelection, resultValue.value, setValue]); + }, [index, isSingleSelection, itemPath, resultValue, resultValue.value, setValue]); useEffect(() => { - setSelected(() => { + // @ts-expect-error hard to type to satisfy TS, but it represents proper types + setSelected((_: OsquerySchemaOption[]): OsquerySchemaOption[] | Array<{ label: string }> => { if (!resultValue.value.length) return []; // Static array values if (isArray(resultValue.value)) { - return resultValue.value.map((value) => ({ label: value })); + return resultValue.value.map((value) => ({ label: value })) as OsquerySchemaOption[]; } - const selectedOption = find(euiFieldProps?.options, ['label', resultValue.value]); + const selectedOption = find(euiFieldProps?.options, ['label', resultValue.value]) as + | OsquerySchemaOption + | undefined; return selectedOption ? [selectedOption] : [{ label: resultValue.value }]; }); @@ -476,10 +534,9 @@ const OsqueryColumnFieldComponent: React.FC = ({ return ( = ({ {Prepend} { inputRef.current = ref; }} fullWidth selectedOptions={selectedOptions} - onChange={handleChange} + onChange={handleKeyChange} onCreateOption={handleCreateOption} renderOption={renderOsqueryOption} rowHeight={32} isClearable - {...euiFieldProps} singleSelection={isSingleSelection ? SINGLE_SELECTION : false} - options={(typeValue === 'field' && euiFieldProps.options) || EMPTY_ARRAY} + options={(item.result.type === 'field' && euiFieldProps.options) || EMPTY_ARRAY} + idAria={idAria} + helpText={selectedOptions[0]?.value?.description} + {...euiFieldProps} /> @@ -518,177 +581,76 @@ export interface ECSMappingEditorFieldProps { interface ECSMappingEditorFormProps { isDisabled?: boolean; osquerySchemaOptions: OsquerySchemaOption[]; - item: ArrayItem; - isLastItem?: boolean; + item: EcsMappingFormField; + index: number; + isLastItem: boolean; + onAppend: (ecs_mapping: EcsMappingFormField[]) => void; onDelete?: FormArrayField['removeItem']; } -const ecsFieldValidator = ( - args: ValidationFuncArg & { - customData: { - value: { - editForm: boolean; - }; - }; - } -) => { - const editForm: boolean = args.customData.value?.editForm; - const rootPath = args.path.split('.')[0]; - - const fieldRequiredError = fieldValidators.emptyField( - i18n.translate('xpack.osquery.pack.queryFlyoutForm.ecsFieldRequiredErrorMessage', { - defaultMessage: 'ECS field is required.', - }) - )(args); - - if ( - fieldRequiredError && - // @ts-expect-error update types - ((!editForm && args.formData[`${rootPath}.result.value`]?.length) || editForm) - ) { - return fieldRequiredError; - } - - return undefined; -}; - -const osqueryResultFieldValidator = async ( - args: ValidationFuncArg & { - customData: { - value: { - editForm: boolean; - osquerySchemaOptions: OsquerySchemaOption[]; - }; - }; - } -) => { - const rootPath = args.path.split('.')[0]; - const { editForm, osquerySchemaOptions } = args.customData.value; - const fieldRequiredError = fieldValidators.emptyField( - i18n.translate('xpack.osquery.pack.queryFlyoutForm.osqueryResultFieldRequiredErrorMessage', { - defaultMessage: 'Value is required.', - }) - )(args); - - // @ts-expect-error update types - if (fieldRequiredError && ((!editForm && args.formData[`${rootPath}.key`]?.length) || editForm)) { - return fieldRequiredError; - } - - // @ts-expect-error update types - if (!args.value?.length || args.formData[`${rootPath}.result.type`] !== 'field') return; - - const osqueryColumnExists = find(osquerySchemaOptions, [ - 'label', - isArray(args.value) ? args.value[0] : args.value, - ]); - - return !osqueryColumnExists - ? { - code: 'ERR_FIELD_FORMAT', - path: args.path, - message: i18n.translate( - 'xpack.osquery.pack.queryFlyoutForm.osqueryResultFieldValueMissingErrorMessage', - { - defaultMessage: 'The current query does not return a {columnName} field', - values: { - columnName: args.value, - }, - } - ), - } - : undefined; +export const defaultEcsFormData = { + key: '', + result: { + type: 'field', + value: '', + }, }; -interface ECSMappingEditorFormData { - key: string; - value: { - field?: string; - value?: string; - }; -} - export const ECSMappingEditorForm: React.FC = ({ isDisabled, osquerySchemaOptions, item, isLastItem, + index, onDelete, }) => { + const ecsFieldValidator = (value: string, ecsMapping: EcsMappingFormField[]) => { + const ecsCurrentMapping = ecsMapping[index].result.value; + + return !value.length && ecsCurrentMapping.length + ? i18n.translate('xpack.osquery.pack.queryFlyoutForm.ecsFieldRequiredErrorMessage', { + defaultMessage: 'ECS field is required.', + }) + : undefined; + }; + + const { ecs_mapping: ecsMapping } = useWatch() as unknown as { + ecs_mapping: EcsMappingFormField[]; + }; + const { field: ECSField, fieldState: ECSFieldState } = useController({ + name: `ecs_mapping.${index}.key`, + rules: { + validate: (value: string) => ecsFieldValidator(value, ecsMapping), + }, + defaultValue: '', + }); + const MultiFields = useMemo( () => ( - - {(fields) => ( - - )} - +
+ +
), - [item, osquerySchemaOptions, isLastItem, isDisabled] + [item, index, isLastItem, osquerySchemaOptions, isDisabled] ); const ecsComboBoxEuiFieldProps = useMemo(() => ({ isDisabled }), [isDisabled]); - const validationData = useMemo(() => ({ editForm: !isLastItem }), [isLastItem]); - - const config = useMemo( - () => ({ - valueChangeDebounceTime: 300, - fieldsToValidateOnChange: [`${item.path}.key`, `${item.path}.result.value`], - validations: [ - { - validator: ecsFieldValidator, - }, - ], - }), - [item.path] - ); - const handleDeleteClick = useCallback(() => { if (onDelete) { - onDelete(item.id); + onDelete(index); } - }, [item.id, onDelete]); + }, [index, onDelete]); return ( <> @@ -696,14 +658,13 @@ export const ECSMappingEditorForm: React.FC = ({ - @@ -764,22 +725,26 @@ interface OsqueryColumn { export const ECSMappingEditorField = React.memo( ({ euiFieldProps }: ECSMappingEditorFieldProps) => { - const lastItemPath = useRef(); - const onAdd = useRef(); - const itemsList = useRef([]); - const [osquerySchemaOptions, setOsquerySchemaOptions] = useState([]); - const [{ query, ...formData }, formDataSerializer, isMounted] = useFormData(); + const { trigger } = useFormContext(); + const { fields, append, remove } = useFieldArray<{ ecs_mapping: EcsMappingFormField[] }>({ + name: 'ecs_mapping', + }); - const { validateFields } = useFormContext(); + const itemsList = useRef>([]); + const [osquerySchemaOptions, setOsquerySchemaOptions] = useState([]); + const { query, ...formData } = useWatch() as unknown as { + query: string; + ecs_mapping: EcsMappingFormField[]; + }; useEffect(() => { // Additional 'suspended' validation of osquery ecs fields. fieldsToValidateOnChange doesn't work because it happens before the osquerySchema gets updated. - const fieldsToValidate = prepareEcsFieldsToValidate(itemsList.current); + const fieldsToValidate = prepareEcsFieldsToValidate(fields); // it is always at least 2 - empty fields if (fieldsToValidate.length > 2) { - setTimeout(() => validateFields(fieldsToValidate), 0); + setTimeout(async () => await trigger('ecs_mapping'), 0); } - }, [query, validateFields]); + }, [fields, query, trigger]); useEffect(() => { if (!query?.length) { @@ -1013,32 +978,23 @@ export const ECSMappingEditorField = React.memo( }, [query]); useLayoutEffect(() => { - if (isMounted) { - if (!lastItemPath.current && onAdd.current) { - onAdd.current(); - - return; - } - - if (euiFieldProps?.isDisabled) { - return; - } - - const itemKey = get(formData, `${lastItemPath.current}.key`); + const ecsList = formData?.ecs_mapping; + const lastEcs = formData?.ecs_mapping?.[itemsList?.current.length - 1]; - if (itemKey) { - const serializedFormData = formDataSerializer(); - const itemValue = - serializedFormData.ecs_mapping && - (serializedFormData.ecs_mapping[`${itemKey}`]?.field || - serializedFormData.ecs_mapping[`${itemKey}`]?.value); + // we skip appending on remove + if (itemsList?.current?.length < ecsList?.length) { + return; + } - if (itemValue && onAdd.current) { - onAdd.current(); - } - } + // // list contains ecs already, and the last item has values provided + if ( + ecsList?.length === itemsList.current.length && + lastEcs?.key?.length && + lastEcs?.result?.value?.length + ) { + return append(defaultEcsFormData); } - }, [euiFieldProps?.isDisabled, formData, formDataSerializer, isMounted, onAdd]); + }, [append, euiFieldProps?.isDisabled, formData]); return ( <> @@ -1080,28 +1036,24 @@ export const ECSMappingEditorField = React.memo( - - {({ items, addItem, removeItem }) => { - lastItemPath.current = items[items.length - 1]?.path; - onAdd.current = addItem; - itemsList.current = items; - - return ( - <> - {items.map((item, index) => ( - - ))} - - ); - }} - + + {fields.map((item, index, array) => { + itemsList.current = array; + + return ( +
+ +
+ ); + })} ); }, diff --git a/x-pack/plugins/osquery/public/packs/queries/platform_checkbox_group_field.tsx b/x-pack/plugins/osquery/public/packs/queries/platform_checkbox_group_field.tsx index 1aa83a39f12b78..62e0a7bdaef6dc 100644 --- a/x-pack/plugins/osquery/public/packs/queries/platform_checkbox_group_field.tsx +++ b/x-pack/plugins/osquery/public/packs/queries/platform_checkbox_group_field.tsx @@ -11,23 +11,22 @@ import type { EuiCheckboxGroupOption } from '@elastic/eui'; import { EuiFlexGroup, EuiFlexItem, EuiFormRow, EuiCheckboxGroup } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; -import type { FieldHook } from '../../shared_imports'; -import { getFieldValidityAndErrorMessage } from '../../shared_imports'; +import { useController } from 'react-hook-form'; +import { i18n } from '@kbn/i18n'; +import type { FormFieldProps } from '../../form/types'; import { PlatformIcon } from './platforms/platform_icon'; -interface Props { - field: FieldHook; - euiFieldProps?: Record; - idAria?: string; - [key: string]: unknown; -} +type Props = Omit, 'name' | 'label'>; -export const PlatformCheckBoxGroupField = ({ - field, - euiFieldProps = {}, - idAria, - ...rest -}: Props) => { +export const PlatformCheckBoxGroupField = (props: Props) => { + const { euiFieldProps = {}, idAria, helpText, ...rest } = props; + const { + field: { onChange, value }, + fieldState: { error }, + } = useController({ + name: 'platform', + defaultValue: [], + }); const options = useMemo( () => [ { @@ -82,17 +81,16 @@ export const PlatformCheckBoxGroupField = ({ [] ); - const { isInvalid, errorMessage } = getFieldValidityAndErrorMessage(field); const [checkboxIdToSelectedMap, setCheckboxIdToSelectedMap] = useState>( () => (options as EuiCheckboxGroupOption[]).reduce((acc, option) => { - acc[option.id] = isEmpty(field.value) ? true : field.value?.includes(option.id) ?? false; + acc[option.id] = isEmpty(value) ? true : value?.includes(option.id) ?? false; return acc; }, {} as Record) ); - const onChange = useCallback( + const handleChange = useCallback( (optionId: string) => { const newCheckboxIdToSelectedMap = { ...checkboxIdToSelectedMap, @@ -100,11 +98,13 @@ export const PlatformCheckBoxGroupField = ({ }; setCheckboxIdToSelectedMap(newCheckboxIdToSelectedMap); - field.setValue(() => - Object.keys(pickBy(newCheckboxIdToSelectedMap, (value) => value === true)).join(',') + onChange( + Object.keys( + pickBy(newCheckboxIdToSelectedMap, (checkboxValue) => checkboxValue === true) + ).join(',') ); }, - [checkboxIdToSelectedMap, field] + [checkboxIdToSelectedMap, onChange] ); const describedByIds = useMemo(() => (idAria ? [idAria] : []), [idAria]); @@ -112,19 +112,23 @@ export const PlatformCheckBoxGroupField = ({ useEffect(() => { setCheckboxIdToSelectedMap(() => (options as EuiCheckboxGroupOption[]).reduce((acc, option) => { - acc[option.id] = isEmpty(field.value) ? true : field.value?.includes(option.id) ?? false; + acc[option.id] = isEmpty(value) ? true : value?.includes(option.id) ?? false; return acc; }, {} as Record) ); - }, [field.value, options]); + }, [value, options]); + + const hasError = useMemo(() => !!error?.message, [error?.message]); return ( diff --git a/x-pack/plugins/osquery/public/packs/queries/query_flyout.tsx b/x-pack/plugins/osquery/public/packs/queries/query_flyout.tsx index 72317dbadc708d..3d8872cb45d642 100644 --- a/x-pack/plugins/osquery/public/packs/queries/query_flyout.tsx +++ b/x-pack/plugins/osquery/public/packs/queries/query_flyout.tsx @@ -5,7 +5,6 @@ * 2.0. */ -import { map } from 'lodash'; import { EuiFlyout, EuiTitle, @@ -17,28 +16,33 @@ import { EuiFlexItem, EuiButtonEmpty, EuiButton, - EuiText, } from '@elastic/eui'; import React, { useCallback, useMemo, useState } from 'react'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; +import { FormProvider } from 'react-hook-form'; +import { isEmpty, map } from 'lodash'; +import { QueryIdField, IntervalField } from '../../form'; +import { defaultEcsFormData } from './ecs_mapping_editor_field'; import { CodeEditorField } from '../../saved_queries/form/code_editor_field'; -import { Form, getUseField, Field } from '../../shared_imports'; import { PlatformCheckBoxGroupField } from './platform_checkbox_group_field'; import { ALL_OSQUERY_VERSIONS_OPTIONS } from './constants'; -import type { UsePackQueryFormProps, PackQueryFormData } from './use_pack_query_form'; +import type { + UsePackQueryFormProps, + PackQueryFormData, + PackSOQueryFormData, +} from './use_pack_query_form'; import { usePackQueryForm } from './use_pack_query_form'; import { SavedQueriesDropdown } from '../../saved_queries/saved_queries_dropdown'; import { ECSMappingEditorField } from './lazy_ecs_mapping_editor_field'; import { useKibana } from '../../common/lib/kibana'; - -const CommonUseField = getUseField({ component: Field }); +import { VersionField } from '../../form'; interface QueryFlyoutProps { uniqueQueryIds: string[]; defaultValue?: UsePackQueryFormProps['defaultValue'] | undefined; - onSave: (payload: PackQueryFormData) => Promise; + onSave: (payload: PackSOQueryFormData) => void; onClose: () => void; } @@ -50,45 +54,48 @@ const QueryFlyoutComponent: React.FC = ({ }) => { const permissions = useKibana().services.application.capabilities.osquery; const [isEditMode] = useState(!!defaultValue); - const { form } = usePackQueryForm({ + const { serializer, idSet, ...hooksForm } = usePackQueryForm({ uniqueQueryIds, defaultValue, - handleSubmit: async (payload, isValid) => - new Promise((resolve) => { - if (isValid) { - onSave(payload); - onClose(); - } - - resolve(); - }), }); - const { submit, isSubmitting, updateFieldValues } = form; + const { + handleSubmit, + formState: { isSubmitting }, + setValue, + clearErrors, + } = hooksForm; + const onSubmit = (payload: PackQueryFormData) => { + const serializedData: PackSOQueryFormData = serializer(payload); + onSave(serializedData); + onClose(); + }; const handleSetQueryValue = useCallback( (savedQuery) => { if (savedQuery) { - updateFieldValues({ - id: savedQuery.id, - query: savedQuery.query, - description: savedQuery.description, - platform: savedQuery.platform ? savedQuery.platform : 'linux,windows,darwin', - version: savedQuery.version, - interval: savedQuery.interval, - // @ts-expect-error update types - ecs_mapping: - map(savedQuery.ecs_mapping, (value, key) => ({ - key, - result: { - type: Object.keys(value)[0], - value: Object.values(value)[0], - }, - })) ?? [], - }); + clearErrors('id'); + setValue('id', savedQuery.id); + setValue('query', savedQuery.query); + // setValue('description', savedQuery.description); // TODO do we need it? + setValue('platform', savedQuery.platform ? savedQuery.platform : 'linux,windows,darwin'); + setValue('version', savedQuery.version ? [savedQuery.version] : []); + setValue('interval', savedQuery.interval); + setValue( + 'ecs_mapping', + !isEmpty(savedQuery.ecs_mapping) + ? map(savedQuery.ecs_mapping, (value, key) => ({ + key, + result: { + type: Object.keys(value)[0], + value: Object.values(value)[0] as string, + }, + })) + : [defaultEcsFormData] + ); } }, - [updateFieldValues] + [clearErrors, setValue] ); /* Avoids accidental closing of the flyout when the user clicks outside of the flyout */ const maskProps = useMemo(() => ({ onClick: () => ({}) }), []); @@ -119,37 +126,25 @@ const QueryFlyoutComponent: React.FC = ({ -
+ {!isEditMode && permissions.readSavedQueries ? ( <> ) : null} - + - + - - - - - - - } + = ({ /> - + @@ -172,7 +167,7 @@ const QueryFlyoutComponent: React.FC = ({ - +
@@ -185,7 +180,7 @@ const QueryFlyoutComponent: React.FC = ({
- + ) => ({ - id: { - type: FIELD_TYPES.TEXT, - label: i18n.translate('xpack.osquery.pack.queryFlyoutForm.idFieldLabel', { - defaultMessage: 'ID', - }), - validations: createIdFieldValidations(ids).map((validator) => ({ validator })), - }, - description: { - type: FIELD_TYPES.TEXT, - label: i18n.translate('xpack.osquery.pack.queryFlyoutForm.descriptionFieldLabel', { - defaultMessage: 'Description (optional)', - }), - validations: [], - }, - query: { - type: FIELD_TYPES.TEXT, - label: i18n.translate('xpack.osquery.pack.queryFlyoutForm.queryFieldLabel', { - defaultMessage: 'Query', - }), - validations: [{ validator: queryFieldValidation }], - }, - interval: { - defaultValue: 3600, - type: FIELD_TYPES.NUMBER, - label: i18n.translate('xpack.osquery.pack.queryFlyoutForm.intervalFieldLabel', { - defaultMessage: 'Interval (s)', - }), - validations: intervalFieldValidations, - }, - platform: { - type: FIELD_TYPES.TEXT, - label: i18n.translate('xpack.osquery.pack.queryFlyoutForm.platformFieldLabel', { - defaultMessage: 'Platform', - }), - validations: [], - }, - version: { - defaultValue: [], - type: FIELD_TYPES.COMBO_BOX, - label: ( - - - - - - ) as unknown as string, - validations: [], - }, - ecs_mapping: { - defaultValue: [], - type: FIELD_TYPES.JSON, - }, -}); diff --git a/x-pack/plugins/osquery/public/packs/queries/use_pack_query_form.tsx b/x-pack/plugins/osquery/public/packs/queries/use_pack_query_form.tsx index 16da80b0489214..4a1e47c3df9b72 100644 --- a/x-pack/plugins/osquery/public/packs/queries/use_pack_query_form.tsx +++ b/x-pack/plugins/osquery/public/packs/queries/use_pack_query_form.tsx @@ -5,134 +5,113 @@ * 2.0. */ -import { isArray, isEmpty, xor, map } from 'lodash'; -import uuid from 'uuid'; -import { produce } from 'immer'; +import { isArray, isEmpty, map, xor } from 'lodash'; +import { useForm as useHookForm } from 'react-hook-form'; +import type { Draft } from 'immer'; +import { produce } from 'immer'; import { useMemo } from 'react'; -import type { ECSMapping } from '../../../common/schemas/common'; import { convertECSMappingToObject } from '../../../common/schemas/common/utils'; -import type { FormConfig } from '../../shared_imports'; -import { useForm } from '../../shared_imports'; -import { createFormSchema } from './schema'; - -const FORM_ID = 'editQueryFlyoutForm'; +import type { EcsMappingFormField } from './ecs_mapping_editor_field'; +import { defaultEcsFormData } from './ecs_mapping_editor_field'; export interface UsePackQueryFormProps { uniqueQueryIds: string[]; - defaultValue?: PackQueryFormData | undefined; - handleSubmit: FormConfig['onSubmit']; + defaultValue?: PackSOQueryFormData | undefined; } export interface PackSOQueryFormData { id: string; query: string; - interval: number; + interval: string; platform?: string | undefined; version?: string | undefined; - ecs_mapping?: PackQuerySOECSMapping[] | undefined; + ecs_mapping?: PackQuerySOECSMapping[]; } export type PackQuerySOECSMapping = Array<{ field: string; value: string }>; export interface PackQueryFormData { - id?: string; + id: string; description?: string; query: string; - interval?: number; + interval: number; platform?: string | undefined; - version?: string | undefined; - ecs_mapping?: ECSMapping; + version?: string[] | undefined; + ecs_mapping: EcsMappingFormField[]; } -export type PackQueryECSMapping = Record< - string, - { - field?: string; - value?: string; - } ->; - -export const usePackQueryForm = ({ - uniqueQueryIds, - defaultValue, - handleSubmit, -}: UsePackQueryFormProps) => { - const idSet = useMemo>( - () => new Set(xor(uniqueQueryIds, defaultValue?.id ? [defaultValue.id] : [])), - [uniqueQueryIds, defaultValue] - ); - const formSchema = useMemo>( - () => createFormSchema(idSet), - [idSet] - ); +const deserializer = (payload: PackSOQueryFormData): PackQueryFormData => + ({ + id: payload.id, + query: payload.query, + interval: payload.interval ? parseInt(payload.interval, 10) : 3600, + platform: payload.platform, + version: payload.version ? [payload.version] : [], + ecs_mapping: !isEmpty(payload.ecs_mapping) + ? !isArray(payload.ecs_mapping) + ? map(payload.ecs_mapping as unknown as PackQuerySOECSMapping, (value, key) => ({ + key, + result: { + type: Object.keys(value)[0], + value: Object.values(value)[0], + }, + })) + : payload.ecs_mapping + : [defaultEcsFormData], + } as PackQueryFormData); - return useForm({ - id: FORM_ID + uuid.v4(), - onSubmit: async (formData, isValid) => { - if (isValid && handleSubmit) { - // @ts-expect-error update types - return handleSubmit(formData, isValid); +const serializer = (payload: PackQueryFormData): PackSOQueryFormData => + // @ts-expect-error update types + produce(payload, (draft: Draft) => { + if (isArray(draft.platform)) { + if (draft.platform.length) { + draft.platform.join(','); + } else { + delete draft.platform; } - }, - options: { - stripEmptyFields: true, - }, - // @ts-expect-error update types - defaultValue: defaultValue || { - id: '', - query: '', - interval: 3600, - ecs_mapping: [], - }, - // @ts-expect-error update types - serializer: (payload) => - produce(payload, (draft) => { - if (isArray(draft.platform)) { - draft.platform.join(','); - } + } - if (isArray(draft.version)) { - if (!draft.version.length) { - delete draft.version; - } else { - draft.version = draft.version[0]; - } - } + if (isArray(draft.version)) { + if (!draft.version.length) { + delete draft.version; + } else { + draft.version = draft.version[0]; + } + } - if (isEmpty(draft.ecs_mapping)) { - delete draft.ecs_mapping; - } else { - // @ts-expect-error update types - draft.ecs_mapping = convertECSMappingToObject(payload.ecs_mapping); - } + if (draft.interval) { + draft.interval = draft.interval + ''; + } - return draft; - }), - // @ts-expect-error update types - deserializer: (payload) => { - if (!payload) return {} as PackQueryFormData; + if (isEmpty(draft.ecs_mapping)) { + delete draft.ecs_mapping; + } else { + // @ts-expect-error update types + draft.ecs_mapping = convertECSMappingToObject(payload.ecs_mapping); + } - return { - id: payload.id, - query: payload.query, - interval: payload.interval, - platform: payload.platform, - version: payload.version ? [payload.version] : [], - ecs_mapping: !isArray(payload.ecs_mapping) - ? map(payload.ecs_mapping, (value, key) => ({ - key, - result: { - // @ts-expect-error update types - type: Object.keys(value)[0], - // @ts-expect-error update types - value: Object.values(value)[0], - }, - })) - : payload.ecs_mapping, - }; - }, - // @ts-expect-error update types - schema: formSchema, + return draft; }); + +export const usePackQueryForm = ({ uniqueQueryIds, defaultValue }: UsePackQueryFormProps) => { + const idSet = useMemo>( + () => new Set(xor(uniqueQueryIds, defaultValue?.id ? [defaultValue.id] : [])), + [uniqueQueryIds, defaultValue] + ); + + return { + serializer, + idSet, + ...useHookForm({ + defaultValues: defaultValue + ? deserializer(defaultValue) + : { + id: '', + query: '', + interval: 3600, + ecs_mapping: [defaultEcsFormData], + }, + }), + }; }; diff --git a/x-pack/plugins/osquery/public/packs/queries/validations.ts b/x-pack/plugins/osquery/public/packs/queries/validations.ts index 54ea9deece692d..37d74806fd1ae2 100644 --- a/x-pack/plugins/osquery/public/packs/queries/validations.ts +++ b/x-pack/plugins/osquery/public/packs/queries/validations.ts @@ -6,12 +6,11 @@ */ import { i18n } from '@kbn/i18n'; +import type { FormData, ValidationFunc } from '../../shared_imports'; -import type { FormData, ValidationConfig, ValidationFunc } from '../../shared_imports'; -import { fieldValidators } from '../../shared_imports'; -export { queryFieldValidation } from '../../common/validations'; - +export const MAX_QUERY_LENGTH = 2000; const idPattern = /^[a-zA-Z0-9-_]+$/; +// still used in Packs export const idSchemaValidation: ValidationFunc = ({ value }) => { const valueIsValid = idPattern.test(value); if (!valueIsValid) { @@ -23,47 +22,39 @@ export const idSchemaValidation: ValidationFunc = ({ v } }; +export const idHookSchemaValidation = (value: string) => { + const valueIsValid = idPattern.test(value); + + if (!valueIsValid) { + return i18n.translate('xpack.osquery.pack.queryFlyoutForm.invalidIdError', { + defaultMessage: 'Characters must be alphanumeric, _, or -', + }); + } +}; + const createUniqueIdValidation = (ids: Set) => { - const uniqueIdCheck: ValidationFunc = ({ value }) => { + const uniqueIdCheck = (value: string) => { if (ids.has(value)) { - return { - message: i18n.translate('xpack.osquery.pack.queryFlyoutForm.uniqueIdError', { - defaultMessage: 'ID must be unique', - }), - }; + return i18n.translate('xpack.osquery.pack.queryFlyoutForm.uniqueIdError', { + defaultMessage: 'ID must be unique', + }); } }; return uniqueIdCheck; }; -export const createIdFieldValidations = (ids: Set) => [ - fieldValidators.emptyField( - i18n.translate('xpack.osquery.pack.queryFlyoutForm.emptyIdError', { +export const createFormIdFieldValidations = (ids: Set) => ({ + required: { + message: i18n.translate('xpack.osquery.pack.queryFlyoutForm.emptyIdError', { defaultMessage: 'ID is required', - }) - ), - idSchemaValidation, - createUniqueIdValidation(ids), -]; - -export const intervalFieldValidations: Array> = [ - { - validator: fieldValidators.numberGreaterThanField({ - than: 0, - message: i18n.translate('xpack.osquery.pack.queryFlyoutForm.intervalFieldMinNumberError', { - defaultMessage: 'A positive interval value is required', - }), }), + value: true, }, - { - validator: fieldValidators.numberSmallerThanField({ - than: 604800, - message: ({ than }) => - i18n.translate('xpack.osquery.pack.queryFlyoutForm.intervalFieldMaxNumberError', { - defaultMessage: 'An interval value must be lower than {than}', - values: { than }, - }), - }), + validate: (text: string) => { + const isPatternValid = idHookSchemaValidation(text); + const isUnique = createUniqueIdValidation(ids)(text); + + return isPatternValid || isUnique; }, -]; +}); diff --git a/x-pack/plugins/osquery/public/packs/types.ts b/x-pack/plugins/osquery/public/packs/types.ts index 4a4253b35b0486..dcdb03045ab226 100644 --- a/x-pack/plugins/osquery/public/packs/types.ts +++ b/x-pack/plugins/osquery/public/packs/types.ts @@ -6,24 +6,6 @@ */ import type { SavedObject } from '@kbn/core/public'; import type { PackQueryFormData } from './queries/use_pack_query_form'; -import type { PackQueryECSMapping } from './queries/use_pack_query_form'; - -export interface IQueryPayload { - attributes?: { - name: string; - id: string; - }; -} - -export interface PackItemQuery { - id: string; - name: string; - interval: number; - query: string; - platform?: string; - version?: string; - ecs_mapping?: PackQueryECSMapping[]; -} export type PackSavedObject = SavedObject<{ name: string; diff --git a/x-pack/plugins/osquery/public/packs/use_create_pack.ts b/x-pack/plugins/osquery/public/packs/use_create_pack.ts index b536f50075a862..26cf1fad2eeb95 100644 --- a/x-pack/plugins/osquery/public/packs/use_create_pack.ts +++ b/x-pack/plugins/osquery/public/packs/use_create_pack.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { useMutation, useQueryClient } from 'react-query'; +import { useMutation, useQueryClient } from '@tanstack/react-query'; import { i18n } from '@kbn/i18n'; import { useKibana } from '../common/lib/kibana'; @@ -42,7 +42,7 @@ export const useCreatePack = ({ withRedirect }: UseCreatePackProps) => { setErrorToast(error, { title: error.body.error, toastMessage: error.body.message }); }, onSuccess: (payload) => { - queryClient.invalidateQueries(PACKS_ID); + queryClient.invalidateQueries([PACKS_ID]); if (withRedirect) { navigateToApp(PLUGIN_ID, { path: pagePathGetters.packs() }); } diff --git a/x-pack/plugins/osquery/public/packs/use_delete_pack.ts b/x-pack/plugins/osquery/public/packs/use_delete_pack.ts index 439a850c785b06..8b5e7f0fb1450b 100644 --- a/x-pack/plugins/osquery/public/packs/use_delete_pack.ts +++ b/x-pack/plugins/osquery/public/packs/use_delete_pack.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { useMutation, useQueryClient } from 'react-query'; +import { useMutation, useQueryClient } from '@tanstack/react-query'; import { i18n } from '@kbn/i18n'; import { useKibana } from '../common/lib/kibana'; @@ -36,7 +36,7 @@ export const useDeletePack = ({ packId, withRedirect }: UseDeletePackProps) => { }); }, onSuccess: () => { - queryClient.invalidateQueries(PACKS_ID); + queryClient.invalidateQueries([PACKS_ID]); if (withRedirect) { navigateToApp(PLUGIN_ID, { path: pagePathGetters.packs() }); } diff --git a/x-pack/plugins/osquery/public/packs/use_pack.ts b/x-pack/plugins/osquery/public/packs/use_pack.ts index da6062fb8309fa..bedaceff9c63cf 100644 --- a/x-pack/plugins/osquery/public/packs/use_pack.ts +++ b/x-pack/plugins/osquery/public/packs/use_pack.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { useQuery } from 'react-query'; +import { useQuery } from '@tanstack/react-query'; import { useKibana } from '../common/lib/kibana'; import type { PackItem } from './types'; diff --git a/x-pack/plugins/osquery/public/packs/use_pack_query_errors.ts b/x-pack/plugins/osquery/public/packs/use_pack_query_errors.ts index 1e57af58c46b46..95b2ddc7c9268f 100644 --- a/x-pack/plugins/osquery/public/packs/use_pack_query_errors.ts +++ b/x-pack/plugins/osquery/public/packs/use_pack_query_errors.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { useQuery } from 'react-query'; +import { useQuery } from '@tanstack/react-query'; import { lastValueFrom } from 'rxjs'; import type { DataView } from '@kbn/data-plugin/common'; import { SortDirection } from '@kbn/data-plugin/common'; diff --git a/x-pack/plugins/osquery/public/packs/use_pack_query_last_results.ts b/x-pack/plugins/osquery/public/packs/use_pack_query_last_results.ts index 28b474530f4bca..15fbcce34a862a 100644 --- a/x-pack/plugins/osquery/public/packs/use_pack_query_last_results.ts +++ b/x-pack/plugins/osquery/public/packs/use_pack_query_last_results.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { useQuery } from 'react-query'; +import { useQuery } from '@tanstack/react-query'; import moment from 'moment-timezone'; import { lastValueFrom } from 'rxjs'; import { SortDirection } from '@kbn/data-plugin/common'; diff --git a/x-pack/plugins/osquery/public/packs/use_packs.ts b/x-pack/plugins/osquery/public/packs/use_packs.ts index b8fadaf571a84d..05dd200b8f1c81 100644 --- a/x-pack/plugins/osquery/public/packs/use_packs.ts +++ b/x-pack/plugins/osquery/public/packs/use_packs.ts @@ -6,7 +6,7 @@ */ import type { SavedObjectsFindResponse } from '@kbn/core/public'; -import { useQuery } from 'react-query'; +import { useQuery } from '@tanstack/react-query'; import { useKibana } from '../common/lib/kibana'; import { PACKS_ID } from './constants'; diff --git a/x-pack/plugins/osquery/public/packs/use_update_pack.ts b/x-pack/plugins/osquery/public/packs/use_update_pack.ts index 1075078dd0e98b..840d01e9b32fdf 100644 --- a/x-pack/plugins/osquery/public/packs/use_update_pack.ts +++ b/x-pack/plugins/osquery/public/packs/use_update_pack.ts @@ -5,8 +5,8 @@ * 2.0. */ -import type { UseMutationOptions } from 'react-query'; -import { useMutation, useQueryClient } from 'react-query'; +import type { UseMutationOptions } from '@tanstack/react-query'; +import { useMutation, useQueryClient } from '@tanstack/react-query'; import { i18n } from '@kbn/i18n'; import { useKibana } from '../common/lib/kibana'; @@ -48,7 +48,7 @@ export const useUpdatePack = ({ withRedirect, options }: UseUpdatePackProps) => setErrorToast(error, { title: error?.body?.error, toastMessage: error?.body?.message }); }, onSuccess: (response) => { - queryClient.invalidateQueries(PACKS_ID); + queryClient.invalidateQueries([PACKS_ID]); if (withRedirect) { navigateToApp(PLUGIN_ID, { path: pagePathGetters.packs() }); } diff --git a/x-pack/plugins/osquery/public/query_client.ts b/x-pack/plugins/osquery/public/query_client.ts index a0ee6c71be288d..41467404c7bffb 100644 --- a/x-pack/plugins/osquery/public/query_client.ts +++ b/x-pack/plugins/osquery/public/query_client.ts @@ -5,14 +5,12 @@ * 2.0. */ -/* eslint-disable @typescript-eslint/no-empty-function */ +import { QueryClient } from '@tanstack/react-query'; -import { QueryClient, setLogger } from 'react-query'; - -setLogger({ - log: () => {}, - warn: () => {}, - error: () => {}, +export const queryClient = new QueryClient({ + logger: { + log: () => null, + warn: () => null, + error: () => null, + }, }); - -export const queryClient = new QueryClient(); diff --git a/x-pack/plugins/osquery/public/results/results_table.tsx b/x-pack/plugins/osquery/public/results/results_table.tsx index a00818ae4857d5..a1658538045a64 100644 --- a/x-pack/plugins/osquery/public/results/results_table.tsx +++ b/x-pack/plugins/osquery/public/results/results_table.tsx @@ -28,6 +28,7 @@ import { FormattedMessage } from '@kbn/i18n-react'; import React, { createContext, useEffect, useState, useCallback, useContext, useMemo } from 'react'; import { pagePathGetters } from '@kbn/fleet-plugin/public'; +import type { ECSMapping } from '../../common/schemas/common'; import { useAllResults } from './use_all_results'; import type { ResultEdges } from '../../common/search_strategy'; import { Direction } from '../../common/search_strategy'; @@ -48,7 +49,7 @@ interface ResultsTableComponentProps { actionId: string; selectedAgent?: string; agentIds?: string[]; - ecsMapping?: Record; + ecsMapping?: ECSMapping; endDate?: string; startDate?: string; addToTimeline?: (payload: { query: [string, string]; isIcon?: true }) => React.ReactElement; @@ -186,10 +187,8 @@ const ResultsTableComponent: React.FC = ({ if (!ecsMapping) return; return reduce( - (acc, [key, value]) => { - // @ts-expect-error update types + (acc: Record, [key, value]) => { if (value?.field) { - // @ts-expect-error update types acc[value?.field] = [...(acc[value?.field] ?? []), key]; } @@ -202,7 +201,6 @@ const ResultsTableComponent: React.FC = ({ const getHeaderDisplay = useCallback( (columnName: string) => { - // @ts-expect-error update types if (ecsMappingConfig && ecsMappingConfig[columnName]) { return ( <> @@ -217,12 +215,9 @@ const ResultsTableComponent: React.FC = ({ /> {`:`}
    - { - // @ts-expect-error update types - ecsMappingConfig[columnName].map((fieldName) => ( -
  • {fieldName}
  • - )) - } + {ecsMappingConfig[columnName].map((fieldName) => ( +
  • {fieldName}
  • + ))}
} diff --git a/x-pack/plugins/osquery/public/results/use_all_results.ts b/x-pack/plugins/osquery/public/results/use_all_results.ts index 94a80fb09734ab..ee545a2eaf9e9c 100644 --- a/x-pack/plugins/osquery/public/results/use_all_results.ts +++ b/x-pack/plugins/osquery/public/results/use_all_results.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { useQuery } from 'react-query'; +import { useQuery } from '@tanstack/react-query'; import { i18n } from '@kbn/i18n'; import { lastValueFrom } from 'rxjs'; diff --git a/x-pack/plugins/osquery/public/routes/saved_queries/edit/form.tsx b/x-pack/plugins/osquery/public/routes/saved_queries/edit/form.tsx index f5ab2308d17206..1b24b4a71eeb5f 100644 --- a/x-pack/plugins/osquery/public/routes/saved_queries/edit/form.tsx +++ b/x-pack/plugins/osquery/public/routes/saved_queries/edit/form.tsx @@ -16,14 +16,17 @@ import { import React from 'react'; import { FormattedMessage } from '@kbn/i18n-react'; -import type { PackQueryFormData } from '../../../packs/queries/use_pack_query_form'; +import { FormProvider } from 'react-hook-form'; import { useRouterNavigate } from '../../../common/lib/kibana'; -import { Form } from '../../../shared_imports'; import { SavedQueryForm } from '../../../saved_queries/form'; +import type { + SavedQueryFormData, + SavedQuerySOFormData, +} from '../../../saved_queries/form/use_saved_query_form'; import { useSavedQueryForm } from '../../../saved_queries/form/use_saved_query_form'; interface EditSavedQueryFormProps { - defaultValue?: PackQueryFormData; + defaultValue?: SavedQuerySOFormData; handleSubmit: (payload: unknown) => Promise; viewMode?: boolean; } @@ -35,15 +38,28 @@ const EditSavedQueryFormComponent: React.FC = ({ }) => { const savedQueryListProps = useRouterNavigate('saved_queries'); - const { form } = useSavedQueryForm({ + const hooksForm = useSavedQueryForm({ defaultValue, - handleSubmit, }); - const { submit, isSubmitting } = form; + + const { + serializer, + idSet, + handleSubmit: formSubmit, + formState: { isSubmitting }, + } = hooksForm; + + const onSubmit = (payload: SavedQueryFormData) => { + const serializedData = serializer(payload); + try { + handleSubmit(serializedData); + // eslint-disable-next-line no-empty + } catch (e) {} + }; return ( -
- + + {!viewMode && ( <> @@ -65,7 +81,7 @@ const EditSavedQueryFormComponent: React.FC = ({ fill size="m" iconType="save" - onClick={submit} + onClick={formSubmit(onSubmit)} > = ({ )} - + ); }; diff --git a/x-pack/plugins/osquery/public/routes/saved_queries/edit/tabs.tsx b/x-pack/plugins/osquery/public/routes/saved_queries/edit/tabs.tsx index c8e57f4f5db230..081530479c8b11 100644 --- a/x-pack/plugins/osquery/public/routes/saved_queries/edit/tabs.tsx +++ b/x-pack/plugins/osquery/public/routes/saved_queries/edit/tabs.tsx @@ -9,6 +9,7 @@ import { EuiTabbedContent, EuiNotificationBadge } from '@elastic/eui'; import React, { useMemo } from 'react'; import type { ReactElement } from 'react'; +import type { ECSMapping } from '../../../../common/schemas/common'; import { ResultsTable } from '../../../results/results_table'; import { ActionResultsSummary } from '../../../action_results/action_results_summary'; @@ -16,7 +17,7 @@ interface ResultTabsProps { actionId: string; agentIds?: string[]; startDate?: string; - ecsMapping?: Record; + ecsMapping?: ECSMapping; failedAgentsCount?: number; endDate?: string; addToTimeline?: (payload: { query: [string, string]; isIcon?: true }) => ReactElement; diff --git a/x-pack/plugins/osquery/public/routes/saved_queries/new/form.tsx b/x-pack/plugins/osquery/public/routes/saved_queries/new/form.tsx index 4dc26c5aaedf4c..350c35b2b3fa5c 100644 --- a/x-pack/plugins/osquery/public/routes/saved_queries/new/form.tsx +++ b/x-pack/plugins/osquery/public/routes/saved_queries/new/form.tsx @@ -15,15 +15,19 @@ import { } from '@elastic/eui'; import React from 'react'; import { FormattedMessage } from '@kbn/i18n-react'; +import { FormProvider } from 'react-hook-form'; -import type { PackQueryFormData } from '../../../packs/queries/use_pack_query_form'; +import { isEmpty } from 'lodash'; import { useRouterNavigate } from '../../../common/lib/kibana'; -import { Form } from '../../../shared_imports'; import { SavedQueryForm } from '../../../saved_queries/form'; +import type { + SavedQuerySOFormData, + SavedQueryFormData, +} from '../../../saved_queries/form/use_saved_query_form'; import { useSavedQueryForm } from '../../../saved_queries/form/use_saved_query_form'; interface NewSavedQueryFormProps { - defaultValue?: PackQueryFormData; + defaultValue?: SavedQuerySOFormData; handleSubmit: (payload: unknown) => Promise; } @@ -33,15 +37,24 @@ const NewSavedQueryFormComponent: React.FC = ({ }) => { const savedQueryListProps = useRouterNavigate('saved_queries'); - const { form } = useSavedQueryForm({ + const hooksForm = useSavedQueryForm({ defaultValue, - handleSubmit, }); - const { submit, isSubmitting, isValid } = form; + const { + serializer, + idSet, + handleSubmit: formSubmit, + formState: { isSubmitting, errors }, + } = hooksForm; + + const onSubmit = (payload: SavedQueryFormData) => { + const serializedData = serializer(payload); + handleSubmit(serializedData); + }; return ( -
- + + @@ -61,7 +74,7 @@ const NewSavedQueryFormComponent: React.FC = ({ fill size="m" iconType="save" - onClick={submit} + onClick={formSubmit(onSubmit)} > = ({ - + ); }; diff --git a/x-pack/plugins/osquery/public/saved_queries/form/code_editor_field.tsx b/x-pack/plugins/osquery/public/saved_queries/form/code_editor_field.tsx index de9d62fe1406c7..2f4ee427461dc9 100644 --- a/x-pack/plugins/osquery/public/saved_queries/form/code_editor_field.tsx +++ b/x-pack/plugins/osquery/public/saved_queries/form/code_editor_field.tsx @@ -10,9 +10,11 @@ import { EuiCodeBlock, EuiFormRow } from '@elastic/eui'; import React from 'react'; import styled from 'styled-components'; +import { useController } from 'react-hook-form'; +import { i18n } from '@kbn/i18n'; +import { MAX_QUERY_LENGTH } from '../../packs/queries/validations'; import { OsquerySchemaLink } from '../../components/osquery_schema_link'; import { OsqueryEditor } from '../../editor'; -import type { FieldHook } from '../../shared_imports'; const StyledEuiCodeBlock = styled(EuiCodeBlock)` min-height: 100px; @@ -20,20 +22,47 @@ const StyledEuiCodeBlock = styled(EuiCodeBlock)` interface CodeEditorFieldProps { euiFieldProps?: Record; - field: FieldHook; + labelAppend?: string; + helpText?: string; } -const CodeEditorFieldComponent: React.FC = ({ euiFieldProps, field }) => { - const { value, label, labelAppend, helpText, setValue, errors } = field; - const error = errors[0]?.message; +const CodeEditorFieldComponent: React.FC = ({ + euiFieldProps, + labelAppend, + helpText, +}) => { + const { + field: { onChange, value }, + fieldState: { error }, + } = useController({ + name: 'query', + rules: { + required: { + message: i18n.translate('xpack.osquery.pack.queryFlyoutForm.emptyQueryError', { + defaultMessage: 'Query is a required field', + }), + value: true, + }, + maxLength: { + message: i18n.translate('xpack.osquery.liveQuery.queryForm.largeQueryError', { + defaultMessage: 'Query is too large (max {maxLength} characters)', + values: { maxLength: MAX_QUERY_LENGTH }, + }), + value: MAX_QUERY_LENGTH, + }, + }, + defaultValue: '', + }); return ( } helpText={helpText} - isInvalid={typeof error === 'string'} - error={error} + isInvalid={!!error?.message} + error={error?.message} fullWidth > {euiFieldProps?.isDisabled ? ( @@ -46,7 +75,7 @@ const CodeEditorFieldComponent: React.FC = ({ euiFieldProp {value} ) : ( - + )} ); diff --git a/x-pack/plugins/osquery/public/saved_queries/form/index.tsx b/x-pack/plugins/osquery/public/saved_queries/form/index.tsx index ec87f430eea92e..6bddd7f0508e41 100644 --- a/x-pack/plugins/osquery/public/saved_queries/form/index.tsx +++ b/x-pack/plugins/osquery/public/saved_queries/form/index.tsx @@ -17,25 +17,25 @@ import React, { useCallback, useMemo, useState } from 'react'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; -import { ALL_OSQUERY_VERSIONS_OPTIONS } from '../../packs/queries/constants'; +import { IntervalField, QueryIdField, QueryDescriptionField, VersionField } from '../../form'; import { PlatformCheckBoxGroupField } from '../../packs/queries/platform_checkbox_group_field'; -import { Field, getUseField, UseField } from '../../shared_imports'; -import { CodeEditorField } from './code_editor_field'; +import { ALL_OSQUERY_VERSIONS_OPTIONS } from '../../packs/queries/constants'; import { ECSMappingEditorField } from '../../packs/queries/lazy_ecs_mapping_editor_field'; import { PlaygroundFlyout } from './playground_flyout'; - -export const CommonUseField = getUseField({ component: Field }); +import { CodeEditorField } from './code_editor_field'; interface SavedQueryFormProps { viewMode?: boolean; hasPlayground?: boolean; isValid?: boolean; + idSet?: Set; } const SavedQueryFormComponent: React.FC = ({ viewMode, hasPlayground, isValid, + idSet, }) => { const [playgroundVisible, setPlaygroundVisible] = useState(false); @@ -77,11 +77,11 @@ const SavedQueryFormComponent: React.FC = ({ return ( <> - + - + - + @@ -119,16 +119,12 @@ const SavedQueryFormComponent: React.FC = ({ - + - + - + {playgroundVisible && ( diff --git a/x-pack/plugins/osquery/public/saved_queries/form/playground_flyout.tsx b/x-pack/plugins/osquery/public/saved_queries/form/playground_flyout.tsx index a253fada318a05..741651b5f2a9af 100644 --- a/x-pack/plugins/osquery/public/saved_queries/form/playground_flyout.tsx +++ b/x-pack/plugins/osquery/public/saved_queries/form/playground_flyout.tsx @@ -10,8 +10,8 @@ import React, { useMemo } from 'react'; import styled from 'styled-components'; import { FormattedMessage } from '@kbn/i18n-react'; +import { useFormContext } from 'react-hook-form'; import { LiveQuery } from '../../live_queries'; -import { useFormData } from '../../shared_imports'; const StyledEuiFlyoutHeader = styled(EuiFlyoutHeader)` &.euiFlyoutHeader.euiFlyoutHeader--hasBorder { @@ -26,11 +26,13 @@ interface PlaygroundFlyoutProps { } const PlaygroundFlyoutComponent: React.FC = ({ enabled, onClose }) => { - const [{ query, ecs_mapping: ecsMapping, id }, formDataSerializer] = useFormData(); - + // @ts-expect-error update types + const { serializer, watch } = useFormContext(); + const watchedValues = watch(); + const { query, ecs_mapping: ecsMapping, id } = watchedValues; /* recalculate the form data when ecs_mapping changes */ // eslint-disable-next-line react-hooks/exhaustive-deps - const serializedFormData = useMemo(() => formDataSerializer(), [ecsMapping, formDataSerializer]); + const serializedFormData = useMemo(() => serializer(watchedValues), [ecsMapping]); return ( diff --git a/x-pack/plugins/osquery/public/saved_queries/form/use_saved_query_form.tsx b/x-pack/plugins/osquery/public/saved_queries/form/use_saved_query_form.tsx index 92849b57f7122b..36f303c8dfff3e 100644 --- a/x-pack/plugins/osquery/public/saved_queries/form/use_saved_query_form.tsx +++ b/x-pack/plugins/osquery/public/saved_queries/form/use_saved_query_form.tsx @@ -5,105 +5,98 @@ * 2.0. */ +import { useForm as useHookForm } from 'react-hook-form'; import { isArray, isEmpty, map } from 'lodash'; -import uuid from 'uuid'; -import { produce } from 'immer'; +import type { Draft } from 'immer'; +import produce from 'immer'; import { useMemo } from 'react'; - +import type { ECSMapping } from '../../../common/schemas/common'; import { convertECSMappingToObject } from '../../../common/schemas/common/utils'; -import { useForm } from '../../shared_imports'; -import { createFormSchema } from '../../packs/queries/schema'; -import type { - PackQueryECSMapping, - PackQueryFormData, -} from '../../packs/queries/use_pack_query_form'; +import type { EcsMappingFormField } from '../../packs/queries/ecs_mapping_editor_field'; +import { defaultEcsFormData } from '../../packs/queries/ecs_mapping_editor_field'; import { useSavedQueries } from '../use_saved_queries'; -const SAVED_QUERY_FORM_ID = 'savedQueryForm'; +export interface SavedQuerySOFormData { + id?: string; + description?: string; + query?: string; + interval?: string; + platform?: string; + version?: string | undefined; + ecs_mapping?: ECSMapping | undefined; +} -interface ReturnFormData { +export interface SavedQueryFormData { id?: string; description?: string; - query: string; + query?: string; interval?: number; platform?: string; version?: string[]; - ecs_mapping?: PackQueryECSMapping[] | undefined; + ecs_mapping: EcsMappingFormField[]; } interface UseSavedQueryFormProps { - defaultValue?: PackQueryFormData; - handleSubmit: (payload: unknown) => Promise; + defaultValue?: SavedQuerySOFormData; } -export const useSavedQueryForm = ({ defaultValue, handleSubmit }: UseSavedQueryFormProps) => { +const deserializer = (payload: SavedQuerySOFormData): SavedQueryFormData => ({ + id: payload.id, + description: payload.description, + query: payload.query, + interval: payload.interval ? parseInt(payload.interval, 10) : 3600, + platform: payload.platform, + version: payload.version ? [payload.version] : [], + ecs_mapping: !isEmpty(payload.ecs_mapping) + ? (map(payload.ecs_mapping, (value, key: string) => ({ + key, + result: { + type: Object.keys(value)[0], + value: Object.values(value)[0], + }, + })) as unknown as EcsMappingFormField[]) + : [defaultEcsFormData], +}); + +export const savedQueryDataSerializer = (payload: SavedQueryFormData): SavedQuerySOFormData => + // @ts-expect-error update types + produce(payload, (draft: Draft) => { + if (isArray(draft.version)) { + if (!draft.version.length) { + draft.version = ''; + } else { + draft.version = draft.version[0]; + } + } + + if (isArray(draft.platform) && !draft.platform.length) { + delete draft.platform; + } + + draft.ecs_mapping = convertECSMappingToObject(payload.ecs_mapping); + + if (draft.interval) { + draft.interval = draft.interval + ''; + } + + return draft; + }); + +export const useSavedQueryForm = ({ defaultValue }: UseSavedQueryFormProps) => { const { data } = useSavedQueries({}); - const ids: string[] = useMemo(() => map(data, 'attributes.id') ?? [], [data]); + const ids: string[] = useMemo(() => map(data?.data, 'attributes.id') ?? [], [data]); const idSet = useMemo>(() => { const res = new Set(ids); if (defaultValue && defaultValue.id) res.delete(defaultValue.id); return res; }, [ids, defaultValue]); - const formSchema = useMemo(() => createFormSchema(idSet), [idSet]); - - return useForm({ - id: SAVED_QUERY_FORM_ID + uuid.v4(), - schema: formSchema, - onSubmit: async (formData, isValid) => { - if (isValid) { - try { - await handleSubmit(formData); - // eslint-disable-next-line no-empty - } catch (e) {} - } - }, - defaultValue, - // @ts-expect-error update types - serializer: (payload) => - produce(payload, (draft) => { - if (isArray(draft.version)) { - if (!draft.version.length) { - // @ts-expect-error update types - draft.version = ''; - } else { - // @ts-expect-error update types - draft.version = draft.version[0]; - } - } - if (isEmpty(payload.ecs_mapping)) { - delete draft.ecs_mapping; - } else { - // @ts-expect-error update types - draft.ecs_mapping = convertECSMappingToObject(payload.ecs_mapping); - } - - // @ts-expect-error update types - draft.interval = draft.interval + ''; - - return draft; - }), - deserializer: (payload) => { - if (!payload) return {} as ReturnFormData; - - return { - id: payload.id, - description: payload.description, - query: payload.query, - interval: payload.interval ?? 3600, - platform: payload.platform, - version: payload.version ? [payload.version] : [], - ecs_mapping: (!isEmpty(payload.ecs_mapping) - ? map(payload.ecs_mapping, (value, key: string) => ({ - key, - result: { - type: Object.keys(value)[0], - value: Object.values(value)[0], - }, - })) - : ([] as PackQueryECSMapping[])) as PackQueryECSMapping[], - }; - }, - }); + return { + serializer: savedQueryDataSerializer, + idSet, + ...useHookForm({ + defaultValues: defaultValue ? deserializer(defaultValue) : {}, + }), + }; }; diff --git a/x-pack/plugins/osquery/public/saved_queries/saved_queries_dropdown.tsx b/x-pack/plugins/osquery/public/saved_queries/saved_queries_dropdown.tsx index c70bad1a617c18..eedaf8ac5ce0fe 100644 --- a/x-pack/plugins/osquery/public/saved_queries/saved_queries_dropdown.tsx +++ b/x-pack/plugins/osquery/public/saved_queries/saved_queries_dropdown.tsx @@ -9,11 +9,11 @@ import { find } from 'lodash/fp'; import { EuiCodeBlock, EuiFormRow, EuiComboBox, EuiTextColor } from '@elastic/eui'; import React, { useCallback, useEffect, useMemo, useState } from 'react'; import styled from 'styled-components'; +import { useWatch } from 'react-hook-form'; import { QUERIES_DROPDOWN_LABEL, QUERIES_DROPDOWN_SEARCH_FIELD_LABEL } from './constants'; import { OsquerySchemaLink } from '../components/osquery_schema_link'; import { useSavedQueries } from './use_saved_queries'; -import { useFormData } from '../shared_imports'; import type { SavedQuerySO } from '../routes/saved_queries/list'; const TextTruncate = styled.div` @@ -49,10 +49,9 @@ const SavedQueriesDropdownComponent: React.FC = ({ disabled, onChange, }) => { + const savedQueryId = useWatch({ name: 'savedQueryId' }); const [selectedOptions, setSelectedOptions] = useState([]); - const [{ savedQueryId }] = useFormData(); - const { data } = useSavedQueries({}); const queryOptions = useMemo( diff --git a/x-pack/plugins/osquery/public/saved_queries/saved_query_flyout.tsx b/x-pack/plugins/osquery/public/saved_queries/saved_query_flyout.tsx index 1e92294a5f1b45..abf8138ff11fab 100644 --- a/x-pack/plugins/osquery/public/saved_queries/saved_query_flyout.tsx +++ b/x-pack/plugins/osquery/public/saved_queries/saved_query_flyout.tsx @@ -17,17 +17,18 @@ import { EuiButtonEmpty, EuiButton, } from '@elastic/eui'; +import { FormProvider } from 'react-hook-form'; + import React, { useCallback } from 'react'; import { FormattedMessage } from '@kbn/i18n-react'; -import { Form } from '../shared_imports'; +import type { SavedQuerySOFormData, SavedQueryFormData } from './form/use_saved_query_form'; import { useSavedQueryForm } from './form/use_saved_query_form'; import { SavedQueryForm } from './form'; import { useCreateSavedQuery } from './use_create_saved_query'; -import type { PackQueryFormData } from '../packs/queries/use_pack_query_form'; interface AddQueryFlyoutProps { - defaultValue: PackQueryFormData; + defaultValue: SavedQuerySOFormData; onClose: () => void; isExternal?: boolean; } @@ -41,18 +42,24 @@ const SavedQueryFlyoutComponent: React.FC = ({ }) => { const createSavedQueryMutation = useCreateSavedQuery({ withRedirect: false }); - const handleSubmit = useCallback( - async (payload) => { - await createSavedQueryMutation.mutateAsync(payload).then(() => onClose()); - }, - [createSavedQueryMutation, onClose] - ); - - const { form } = useSavedQueryForm({ + const hooksForm = useSavedQueryForm({ defaultValue, - handleSubmit, }); - const { submit, isSubmitting } = form; + const { + serializer, + idSet, + handleSubmit, + formState: { isSubmitting }, + } = hooksForm; + const onSubmit = useCallback( + async (payload: SavedQueryFormData) => { + const serializedData = serializer(payload); + // TODO CHECK THIS + // @ts-expect-error update types + await createSavedQueryMutation.mutateAsync(serializedData).then(() => onClose()); + }, + [createSavedQueryMutation, onClose, serializer] + ); return ( @@ -74,9 +81,9 @@ const SavedQueryFlyoutComponent: React.FC = ({ -
- - + + +
@@ -89,7 +96,7 @@ const SavedQueryFlyoutComponent: React.FC = ({
- + { - queryClient.invalidateQueries(SAVED_QUERIES_ID); + queryClient.invalidateQueries([SAVED_QUERIES_ID]); if (withRedirect) { navigateToApp(PLUGIN_ID, { path: pagePathGetters.saved_queries() }); } diff --git a/x-pack/plugins/osquery/public/saved_queries/use_delete_saved_query.ts b/x-pack/plugins/osquery/public/saved_queries/use_delete_saved_query.ts index e882a9ba2f1eaf..f03ac709db1eeb 100644 --- a/x-pack/plugins/osquery/public/saved_queries/use_delete_saved_query.ts +++ b/x-pack/plugins/osquery/public/saved_queries/use_delete_saved_query.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { useMutation, useQueryClient } from 'react-query'; +import { useMutation, useQueryClient } from '@tanstack/react-query'; import { i18n } from '@kbn/i18n'; import { useKibana } from '../common/lib/kibana'; @@ -35,7 +35,7 @@ export const useDeleteSavedQuery = ({ savedQueryId }: UseDeleteSavedQueryProps) }); }, onSuccess: () => { - queryClient.invalidateQueries(SAVED_QUERIES_ID); + queryClient.invalidateQueries([SAVED_QUERIES_ID]); navigateToApp(PLUGIN_ID, { path: pagePathGetters.saved_queries() }); toasts.addSuccess( i18n.translate('xpack.osquery.editSavedQuery.deleteSuccessToastMessageText', { diff --git a/x-pack/plugins/osquery/public/saved_queries/use_saved_queries.ts b/x-pack/plugins/osquery/public/saved_queries/use_saved_queries.ts index 53d07c52e325b3..bceeaed5be435e 100644 --- a/x-pack/plugins/osquery/public/saved_queries/use_saved_queries.ts +++ b/x-pack/plugins/osquery/public/saved_queries/use_saved_queries.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { useQuery } from 'react-query'; +import { useQuery } from '@tanstack/react-query'; import type { SavedObjectsFindResponse } from '@kbn/core/public'; import { useKibana } from '../common/lib/kibana'; diff --git a/x-pack/plugins/osquery/public/saved_queries/use_saved_query.ts b/x-pack/plugins/osquery/public/saved_queries/use_saved_query.ts index f146910f35c141..e5c39d76c94f29 100644 --- a/x-pack/plugins/osquery/public/saved_queries/use_saved_query.ts +++ b/x-pack/plugins/osquery/public/saved_queries/use_saved_query.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { useQuery } from 'react-query'; +import { useQuery } from '@tanstack/react-query'; import { PLUGIN_ID } from '../../common'; import { useKibana } from '../common/lib/kibana'; diff --git a/x-pack/plugins/osquery/public/saved_queries/use_update_saved_query.ts b/x-pack/plugins/osquery/public/saved_queries/use_update_saved_query.ts index 95eb446e147bda..aef48b7577ecef 100644 --- a/x-pack/plugins/osquery/public/saved_queries/use_update_saved_query.ts +++ b/x-pack/plugins/osquery/public/saved_queries/use_update_saved_query.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { useMutation, useQueryClient } from 'react-query'; +import { useMutation, useQueryClient } from '@tanstack/react-query'; import { i18n } from '@kbn/i18n'; import { useKibana } from '../common/lib/kibana'; @@ -40,15 +40,15 @@ export const useUpdateSavedQuery = ({ savedQueryId }: UseUpdateSavedQueryProps) toastMessage: error.body.message, }); }, - onSuccess: (payload: SavedQuerySO) => { - queryClient.invalidateQueries(SAVED_QUERIES_ID); + onSuccess: (payload: { data: SavedQuerySO }) => { + queryClient.invalidateQueries([SAVED_QUERIES_ID]); queryClient.invalidateQueries([SAVED_QUERY_ID, { savedQueryId }]); navigateToApp(PLUGIN_ID, { path: pagePathGetters.saved_queries() }); toasts.addSuccess( i18n.translate('xpack.osquery.editSavedQuery.successToastMessageText', { defaultMessage: 'Successfully updated "{savedQueryName}" query', values: { - savedQueryName: payload.attributes?.id ?? '', + savedQueryName: payload.data.attributes?.id ?? '', }, }) ); diff --git a/x-pack/plugins/osquery/public/shared_components/osquery_action/index.tsx b/x-pack/plugins/osquery/public/shared_components/osquery_action/index.tsx index 3cffdbde50dd19..15c6fa645de115 100644 --- a/x-pack/plugins/osquery/public/shared_components/osquery_action/index.tsx +++ b/x-pack/plugins/osquery/public/shared_components/osquery_action/index.tsx @@ -7,7 +7,7 @@ import { EuiErrorBoundary, EuiLoadingContent, EuiEmptyPrompt, EuiCode } from '@elastic/eui'; import React, { useMemo } from 'react'; -import { QueryClientProvider } from 'react-query'; +import { QueryClientProvider } from '@tanstack/react-query'; import type { CoreStart } from '@kbn/core/public'; import { AGENT_STATUS_ERROR, diff --git a/x-pack/plugins/osquery/public/shared_components/osquery_action/osquery_action.test.tsx b/x-pack/plugins/osquery/public/shared_components/osquery_action/osquery_action.test.tsx index 4c9214ca3ea146..927d408884d202 100644 --- a/x-pack/plugins/osquery/public/shared_components/osquery_action/osquery_action.test.tsx +++ b/x-pack/plugins/osquery/public/shared_components/osquery_action/osquery_action.test.tsx @@ -8,7 +8,7 @@ import React from 'react'; import { __IntlProvider as IntlProvider } from '@kbn/i18n-react'; import { render } from '@testing-library/react'; -import { QueryClientProvider } from 'react-query'; +import { QueryClientProvider } from '@tanstack/react-query'; import { OsqueryAction } from '.'; import { queryClient } from '../../query_client'; diff --git a/x-pack/plugins/rule_registry/common/mapping_from_field_map.ts b/x-pack/plugins/rule_registry/common/mapping_from_field_map.ts index 4833631f09adbf..1b66496bee19b8 100644 --- a/x-pack/plugins/rule_registry/common/mapping_from_field_map.ts +++ b/x-pack/plugins/rule_registry/common/mapping_from_field_map.ts @@ -6,7 +6,7 @@ */ import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; -import { set } from '@elastic/safer-lodash-set'; +import { set } from '@kbn/safer-lodash-set'; import { FieldMap } from './field_map/types'; export function mappingFromFieldMap( diff --git a/x-pack/plugins/security/public/authentication/access_agreement/__snapshots__/access_agreement_page.test.tsx.snap b/x-pack/plugins/security/public/authentication/access_agreement/__snapshots__/access_agreement_page.test.tsx.snap index 04dd39c69e64d2..2735c8d14d1a16 100644 --- a/x-pack/plugins/security/public/authentication/access_agreement/__snapshots__/access_agreement_page.test.tsx.snap +++ b/x-pack/plugins/security/public/authentication/access_agreement/__snapshots__/access_agreement_page.test.tsx.snap @@ -2,42 +2,18 @@ exports[`AccessAgreementPage renders as expected when state is available 1`] = ` - -

- - This is - - - - link - - -

-
+ link +
+

`; diff --git a/x-pack/plugins/security/public/authentication/login/components/login_form/__snapshots__/login_form.test.tsx.snap b/x-pack/plugins/security/public/authentication/login/components/login_form/__snapshots__/login_form.test.tsx.snap index d6eb4c20b8003a..9e150c2ff0312e 100644 --- a/x-pack/plugins/security/public/authentication/login/components/login_form/__snapshots__/login_form.test.tsx.snap +++ b/x-pack/plugins/security/public/authentication/login/components/login_form/__snapshots__/login_form.test.tsx.snap @@ -2,103 +2,49 @@ exports[`LoginForm login selector properly switches to login form -> login help and back: Login Help 1`] = ` - -

- - - some help - - -

-
+ some help + +

`; exports[`LoginForm login selector properly switches to login help: Login Help 1`] = ` - -

- - - some help - - -

-
+ some help + +

`; exports[`LoginForm properly switches to login help: Login Help 1`] = ` - -

- - - some help - - -

-
+ some help + +

`; diff --git a/x-pack/plugins/security/public/management/api_keys/api_keys_management_app.test.tsx b/x-pack/plugins/security/public/management/api_keys/api_keys_management_app.test.tsx index 514e9aa5e306cc..c4f3000277af70 100644 --- a/x-pack/plugins/security/public/management/api_keys/api_keys_management_app.test.tsx +++ b/x-pack/plugins/security/public/management/api_keys/api_keys_management_app.test.tsx @@ -89,7 +89,9 @@ describe('apiKeysManagementApp', () => {
`); - unmount!(); + act(() => { + unmount!(); + }); expect(docTitle.reset).toHaveBeenCalledTimes(1); expect(container).toMatchInlineSnapshot(`
`); diff --git a/x-pack/plugins/security/public/management/role_mappings/role_mappings_management_app.test.tsx b/x-pack/plugins/security/public/management/role_mappings/role_mappings_management_app.test.tsx index 04db6c58c27d12..c085bafb562c2f 100644 --- a/x-pack/plugins/security/public/management/role_mappings/role_mappings_management_app.test.tsx +++ b/x-pack/plugins/security/public/management/role_mappings/role_mappings_management_app.test.tsx @@ -82,7 +82,9 @@ describe('roleMappingsManagementApp', () => {
`); - unmount(); + act(() => { + unmount(); + }); expect(docTitle.reset).toHaveBeenCalledTimes(1); @@ -105,7 +107,9 @@ describe('roleMappingsManagementApp', () => {
`); - unmount(); + act(() => { + unmount(); + }); expect(docTitle.reset).toHaveBeenCalledTimes(1); @@ -133,7 +137,9 @@ describe('roleMappingsManagementApp', () => {
`); - unmount(); + act(() => { + unmount(); + }); expect(docTitle.reset).toHaveBeenCalledTimes(1); diff --git a/x-pack/plugins/security/public/management/roles/roles_management_app.test.tsx b/x-pack/plugins/security/public/management/roles/roles_management_app.test.tsx index 327499c64bb76d..a6e06351f38c9f 100644 --- a/x-pack/plugins/security/public/management/roles/roles_management_app.test.tsx +++ b/x-pack/plugins/security/public/management/roles/roles_management_app.test.tsx @@ -88,7 +88,9 @@ describe('rolesManagementApp', () => {
`); - unmount(); + act(() => { + unmount(); + }); expect(docTitle.reset).toHaveBeenCalledTimes(1); @@ -108,7 +110,9 @@ describe('rolesManagementApp', () => {
`); - unmount(); + act(() => { + unmount(); + }); expect(docTitle.reset).toHaveBeenCalledTimes(1); @@ -133,7 +137,9 @@ describe('rolesManagementApp', () => {
`); - unmount(); + act(() => { + unmount(); + }); expect(docTitle.reset).toHaveBeenCalledTimes(1); @@ -158,7 +164,9 @@ describe('rolesManagementApp', () => {