diff --git a/.backportrc.json b/.backportrc.json index f89e758afe8a6..e9fc5abecfe23 100644 --- a/.backportrc.json +++ b/.backportrc.json @@ -3,6 +3,7 @@ "targetBranchChoices": [ { "name": "main", "checked": true }, "8.0", + "7.17", "7.16", "7.15", "7.14", diff --git a/.buildkite/pipelines/flaky_tests/groups.json b/.buildkite/pipelines/flaky_tests/groups.json deleted file mode 100644 index b47ccf16a0184..0000000000000 --- a/.buildkite/pipelines/flaky_tests/groups.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "groups": [ - { - "key": "oss/cigroup", - "name": "OSS CI Group", - "ciGroups": 12 - }, - { - "key": "oss/firefox", - "name": "OSS Firefox" - }, - { - "key": "oss/accessibility", - "name": "OSS Accessibility" - }, - { - "key": "xpack/cigroup", - "name": "Default CI Group", - "ciGroups": 27 - }, - { - "key": "xpack/cigroup/Docker", - "name": "Default CI Group Docker" - }, - { - "key": "xpack/firefox", - "name": "Default Firefox" - }, - { - "key": "xpack/accessibility", - "name": "Default Accessibility" - } - ] -} diff --git a/.buildkite/pipelines/flaky_tests/pipeline.js b/.buildkite/pipelines/flaky_tests/pipeline.js index 68e19c8e275d7..bf4abb9ff4c89 100644 --- a/.buildkite/pipelines/flaky_tests/pipeline.js +++ b/.buildkite/pipelines/flaky_tests/pipeline.js @@ -1,7 +1,3 @@ -const groups = /** @type {Array<{key: string, name: string, ciGroups: number }>} */( - require('./groups.json').groups -) - const stepInput = (key, nameOfSuite) => { return { key: `ftsr-suite/${key}`, @@ -11,31 +7,38 @@ const stepInput = (key, nameOfSuite) => { }; }; +const OSS_CI_GROUPS = 12; +const XPACK_CI_GROUPS = 27; + const inputs = [ { key: 'ftsr-override-count', text: 'Override for all suites', - default: '0', + default: 0, required: true, }, ]; -for (const group of groups) { - if (!group.ciGroups) { - inputs.push(stepInput(group.key, group.name)) - } else { - for (let i = 1; i <= group.ciGroups; i++) { - inputs.push(stepInput(`${group.key}/${i}`, `${group.name} ${i}`)) - } - } +for (let i = 1; i <= OSS_CI_GROUPS; i++) { + inputs.push(stepInput(`oss/cigroup/${i}`, `OSS CI Group ${i}`)); } +inputs.push(stepInput(`oss/firefox`, 'OSS Firefox')); +inputs.push(stepInput(`oss/accessibility`, 'OSS Accessibility')); + +for (let i = 1; i <= XPACK_CI_GROUPS; i++) { + inputs.push(stepInput(`xpack/cigroup/${i}`, `Default CI Group ${i}`)); +} + +inputs.push(stepInput(`xpack/cigroup/Docker`, 'Default CI Group Docker')); +inputs.push(stepInput(`xpack/firefox`, 'Default Firefox')); +inputs.push(stepInput(`xpack/accessibility`, 'Default Accessibility')); + const pipeline = { steps: [ { input: 'Number of Runs - Click Me', fields: inputs, - if: `build.env('KIBANA_FLAKY_TEST_RUNNER_CONFIG') == null` }, { wait: '~', diff --git a/.buildkite/pipelines/flaky_tests/runner.js b/.buildkite/pipelines/flaky_tests/runner.js index 54da6890b2b07..0c2db5c724f7b 100644 --- a/.buildkite/pipelines/flaky_tests/runner.js +++ b/.buildkite/pipelines/flaky_tests/runner.js @@ -1,85 +1,37 @@ const { execSync } = require('child_process'); -const concurrency = 25; -const defaultCount = concurrency * 2; -const initialJobs = 3; - -function getTestSuitesFromMetadata() { - const keys = execSync('buildkite-agent meta-data keys') - .toString() - .split('\n') - .filter((k) => k.startsWith('ftsr-suite/')); - - const overrideCount = execSync(`buildkite-agent meta-data get 'ftsr-override-count'`).toString().trim(); - - const testSuites = []; - for (const key of keys) { - if (!key) { - continue; - } +const keys = execSync('buildkite-agent meta-data keys') + .toString() + .split('\n') + .filter((k) => k.startsWith('ftsr-suite/')); - const value = - overrideCount || execSync(`buildkite-agent meta-data get '${key}'`).toString().trim(); +const overrideCount = parseInt( + execSync(`buildkite-agent meta-data get 'ftsr-override-count'`).toString().trim() +); - const count = value === '' ? defaultCount : parseInt(value); - totalJobs += count; - - testSuites.push({ - key: key.replace('ftsr-suite/', ''), - count: count, - }); - } - - return testSuites -} +const concurrency = 25; +const initialJobs = 3; -function getTestSuitesFromJson(json) { - const fail = (errorMsg) => { - console.error('+++ Invalid test config provided') - console.error(`${errorMsg}: ${json}`); - process.exit(1); - } +let totalJobs = initialJobs; - let parsed; - try { - parsed = JSON.parse(json) - } catch (error) { - fail(`JSON test config did not parse correctly`) +const testSuites = []; +for (const key of keys) { + if (!key) { + continue; } - if (!Array.isArray(parsed)) { - fail(`JSON test config must be an array`) - } + const value = + overrideCount || execSync(`buildkite-agent meta-data get '${key}'`).toString().trim(); - /** @type {Array<{ key: string, count: number }>} */ - const testSuites = [] - for (const item of parsed) { - if (typeof item !== 'object' || item === null) { - fail(`testSuites must be objects`) - } - const key = item.key - if (typeof key !== 'string') { - fail(`testSuite.key must be a string`) - } - const count = item.count; - if (typeof count !== 'number') { - fail(`testSuite.count must be a number`) - } - testSuites.push({ - key, - count, - }) - } + const count = value === '' ? defaultCount : parseInt(value); + totalJobs += count; - return testSuites + testSuites.push({ + key: key.replace('ftsr-suite/', ''), + count: count, + }); } -const testSuites = process.env.KIBANA_FLAKY_TEST_RUNNER_CONFIG - ? getTestSuitesFromJson(process.env.KIBANA_FLAKY_TEST_RUNNER_CONFIG) - : getTestSuitesFromMetadata(); - -let totalJobs = testSuites.reduce((acc, t) => acc + t.count, initialJobs); - if (totalJobs > 500) { console.error('+++ Too many tests'); console.error( diff --git a/.buildkite/scripts/build_kibana.sh b/.buildkite/scripts/build_kibana.sh index 007dd19a2c0e1..d05fe178b72db 100755 --- a/.buildkite/scripts/build_kibana.sh +++ b/.buildkite/scripts/build_kibana.sh @@ -28,7 +28,7 @@ if [[ "${GITHUB_PR_LABELS:-}" == *"ci:deploy-cloud"* ]]; then --docker-tag-qualifier="$GIT_COMMIT" \ --docker-push \ --skip-docker-ubi \ - --skip-docker-centos \ + --skip-docker-ubuntu \ --skip-docker-contexts CLOUD_IMAGE=$(docker images --format "{{.Repository}}:{{.Tag}}" docker.elastic.co/kibana-ci/kibana-cloud) diff --git a/.buildkite/scripts/post_build_kibana.sh b/.buildkite/scripts/post_build_kibana.sh index 5f26c80ddb6b6..d8b297935471a 100755 --- a/.buildkite/scripts/post_build_kibana.sh +++ b/.buildkite/scripts/post_build_kibana.sh @@ -13,5 +13,5 @@ echo "--- Upload Build Artifacts" # Moving to `target/` first will keep `buildkite-agent` from including directories in the artifact name cd "$KIBANA_DIR/target" cp kibana-*-linux-x86_64.tar.gz kibana-default.tar.gz -buildkite-agent artifact upload "./*.tar.gz;./*.zip" +buildkite-agent artifact upload "./*.tar.gz;./*.zip;./*.deb;./*.rpm" cd - diff --git a/.buildkite/scripts/steps/demo_env/kibana.sh b/.buildkite/scripts/steps/demo_env/kibana.sh index f10ed4013bc0c..f38d43b5479e6 100755 --- a/.buildkite/scripts/steps/demo_env/kibana.sh +++ b/.buildkite/scripts/steps/demo_env/kibana.sh @@ -9,7 +9,7 @@ source "$(dirname "${0}")/config.sh" export KIBANA_IMAGE="gcr.io/elastic-kibana-184716/demo/kibana:$DEPLOYMENT_NAME-$(git rev-parse HEAD)" echo '--- Build Kibana' -node scripts/build --debug --docker-images --example-plugins --skip-os-packages --skip-docker-ubi +node scripts/build --debug --docker-images --example-plugins --skip-docker-ubi echo '--- Build Docker image with example plugins' cd target/example_plugins diff --git a/.eslintrc.js b/.eslintrc.js index 75580f115f48a..b303a9fefb691 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -850,10 +850,6 @@ module.exports = { name: 'semver', message: 'Please use "semver/*/{function}" instead', }, - { - name: '@kbn/rule-data-utils', - message: `Import directly from @kbn/rule-data-utils/* submodules in public/common code`, - }, ], }, ], diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index e2a99bfc7e483..cd3188ad971af 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -63,6 +63,8 @@ /packages/elastic-datemath/ @elastic/kibana-app-services /packages/kbn-interpreter/ @elastic/kibana-app-services /packages/kbn-react-field/ @elastic/kibana-app-services +/packages/kbn-es-query/ @elastic/kibana-app-services +/packages/kbn-field-types/ @elastic/kibana-app-services /src/plugins/bfetch/ @elastic/kibana-app-services /src/plugins/data/ @elastic/kibana-app-services /src/plugins/data_views/ @elastic/kibana-app-services @@ -409,15 +411,13 @@ /x-pack/plugins/security_solution/public/common/lib/endpoint*/ @elastic/security-onboarding-and-lifecycle-mgt /x-pack/plugins/security_solution/public/common/components/endpoint/ @elastic/security-onboarding-and-lifecycle-mgt /x-pack/plugins/security_solution/common/endpoint/ @elastic/security-onboarding-and-lifecycle-mgt -/x-pack/plugins/security_solution/server/endpoint/routes/trusted_apps/ @elastic/security-onboarding-and-lifecycle-mgt -/x-pack/plugins/security_solution/server/endpoint/routes/actions/ @elastic/security-onboarding-and-lifecycle-mgt -/x-pack/plugins/security_solution/server/endpoint/routes/metadata/ @elastic/security-onboarding-and-lifecycle-mgt -/x-pack/plugins/security_solution/server/endpoint/lib/policy/ @elastic/security-onboarding-and-lifecycle-mgt +/x-pack/plugins/security_solution/server/endpoint/ @elastic/security-onboarding-and-lifecycle-mgt /x-pack/plugins/security_solution/server/lib/license/ @elastic/security-onboarding-and-lifecycle-mgt /x-pack/plugins/security_solution/server/fleet_integration/ @elastic/security-onboarding-and-lifecycle-mgt /x-pack/plugins/security_solution/scripts/endpoint/event_filters/ @elastic/security-onboarding-and-lifecycle-mgt /x-pack/plugins/security_solution/scripts/endpoint/trusted_apps/ @elastic/security-onboarding-and-lifecycle-mgt /x-pack/test/security_solution_endpoint/apps/endpoint/ @elastic/security-onboarding-and-lifecycle-mgt +/x-pack/test/security_solution_endpoint_api_int/ @elastic/security-onboarding-and-lifecycle-mgt ## Security Solution sub teams - security-telemetry (Data Engineering) x-pack/plugins/security_solution/server/usage/ @elastic/security-telemetry diff --git a/docs/api/saved-objects.asciidoc b/docs/api/saved-objects.asciidoc index fcb4b119c06c6..2185dfd4d21a4 100644 --- a/docs/api/saved-objects.asciidoc +++ b/docs/api/saved-objects.asciidoc @@ -6,7 +6,7 @@ Manage {kib} saved objects, including dashboards, visualizations, and more. WARNING: Do not write documents directly to the `.kibana` index. When you write directly to the `.kibana` index, the data becomes corrupted and permanently breaks future {kib} versions. -NOTE: For managing {kib} index patterns, use the <>. +NOTE: For managing {data-sources}, use the <>. The following saved objects APIs are available: diff --git a/docs/api/saved-objects/bulk_create.asciidoc b/docs/api/saved-objects/bulk_create.asciidoc index 471e297316578..dcb402ee1a1dc 100644 --- a/docs/api/saved-objects/bulk_create.asciidoc +++ b/docs/api/saved-objects/bulk_create.asciidoc @@ -72,7 +72,7 @@ Saved objects that are unable to persist are replaced with an error object. [[saved-objects-api-bulk-create-example]] ==== Example -Create an index pattern with the `my-pattern` ID, and a dashboard with the `my-dashboard` ID: +Create {a-data-source} with the `my-pattern` ID, and a dashboard with the `my-dashboard` ID: [source,sh] -------------------------------------------------- @@ -122,7 +122,7 @@ The API returns the following: } -------------------------------------------------- -There is already a saved object with the `my-dashboard` ID, so only the index pattern is created. +There is already a saved object with the `my-dashboard` ID, so only the {data-source} is created. [[saved-objects-api-bulk-create-conflict-errors]] ==== Conflict errors diff --git a/docs/api/saved-objects/bulk_get.asciidoc b/docs/api/saved-objects/bulk_get.asciidoc index 65cd93fe212f8..bec503eb18fe6 100644 --- a/docs/api/saved-objects/bulk_get.asciidoc +++ b/docs/api/saved-objects/bulk_get.asciidoc @@ -59,7 +59,7 @@ Saved objects that are unable to persist are replaced with an error object. [[saved-objects-api-bulk-get-body-example]] ==== Example -Retrieve an index pattern with the `my-pattern` ID, and a dashboard with the `my-dashboard` ID: +Retrieve a {data-source} with the `my-pattern` ID, and a dashboard with the `my-dashboard` ID: [source,sh] -------------------------------------------------- @@ -103,4 +103,4 @@ The API returns the following: } -------------------------------------------------- -Only the index pattern exists. +Only the {data-source} exists. diff --git a/docs/api/saved-objects/delete.asciidoc b/docs/api/saved-objects/delete.asciidoc index ab50fd6e37eac..eca46e202beda 100644 --- a/docs/api/saved-objects/delete.asciidoc +++ b/docs/api/saved-objects/delete.asciidoc @@ -43,7 +43,7 @@ TIP: Use this if you attempted to delete an object and received an HTTP 400 erro ==== Example -Delete an index pattern object with the `my-pattern` ID: +Delete {a-data-source} object with the `my-pattern` ID: [source,sh] -------------------------------------------------- diff --git a/docs/api/saved-objects/export.asciidoc b/docs/api/saved-objects/export.asciidoc index 667a9c57ca802..53910835c4989 100644 --- a/docs/api/saved-objects/export.asciidoc +++ b/docs/api/saved-objects/export.asciidoc @@ -67,7 +67,7 @@ When `excludeExportDetails=false` (the default) we append an export result detai [[ssaved-objects-api-create-example]] ==== Examples -Export all index pattern saved objects: +Export all {data-source} saved objects: [source,sh] -------------------------------------------------- @@ -78,7 +78,7 @@ $ curl -X POST api/saved_objects/_export -H 'kbn-xsrf: true' -H 'Content-Type: a -------------------------------------------------- // KIBANA -Export all index pattern saved objects and exclude the export summary from the stream: +Export all {data-source} saved objects and exclude the export summary from the stream: [source,sh] -------------------------------------------------- diff --git a/docs/api/saved-objects/find.asciidoc b/docs/api/saved-objects/find.asciidoc index f04aeb8420620..43c7f4cde8fa8 100644 --- a/docs/api/saved-objects/find.asciidoc +++ b/docs/api/saved-objects/find.asciidoc @@ -73,7 +73,7 @@ change. Use the find API for traditional paginated results, but avoid using it t ==== Examples -Find index patterns with titles that start with `my`: +Find {data-sources} with titles that start with `my`: [source,sh] -------------------------------------------------- diff --git a/docs/api/saved-objects/get.asciidoc b/docs/api/saved-objects/get.asciidoc index cfc591d811227..174587b400993 100644 --- a/docs/api/saved-objects/get.asciidoc +++ b/docs/api/saved-objects/get.asciidoc @@ -35,7 +35,7 @@ experimental[] Retrieve a single {kib} saved object by ID. [[saved-objects-api-get-example]] ==== Example -Retrieve the index pattern object with the `my-pattern` ID: +Retrieve the {data-source} object with the `my-pattern` ID: [source,sh] -------------------------------------------------- diff --git a/docs/api/saved-objects/import.asciidoc b/docs/api/saved-objects/import.asciidoc index a214598af31af..8a6ef5b26e424 100644 --- a/docs/api/saved-objects/import.asciidoc +++ b/docs/api/saved-objects/import.asciidoc @@ -95,7 +95,7 @@ to resolve errors, refer to the <>. [[saved-objects-api-import-example-1]] ===== Successful import with `createNewCopies` enabled -Import an index pattern and dashboard: +Import {a-data-source} and dashboard: [source,sh] -------------------------------------------------- @@ -147,7 +147,7 @@ The result indicates a successful import, and both objects are created. Since th [[saved-objects-api-import-example-2]] ===== Successful import with `createNewCopies` disabled -Import an index pattern and dashboard: +Import {a-data-source} and dashboard: [source,sh] -------------------------------------------------- @@ -196,7 +196,7 @@ The result indicates a successful import, and both objects are created. [[saved-objects-api-import-example-3]] ===== Failed import with conflict errors -Import an index pattern, visualization, *Canvas* workpad, and dashboard that include saved objects: +Import {a-data-source}, visualization, *Canvas* workpad, and dashboard that include saved objects: [source,sh] -------------------------------------------------- @@ -285,10 +285,10 @@ The API returns the following: } -------------------------------------------------- -The result indicates an unsuccessful import because the index pattern, visualization, *Canvas* workpad, and dashboard resulted in a conflict +The result indicates an unsuccessful import because the {data-source}, visualization, *Canvas* workpad, and dashboard resulted in a conflict error: -* An index pattern with the same ID already exists, which resulted in a conflict error. To resolve the error, overwrite the existing object, +* A {data-source} with the same ID already exists, which resulted in a conflict error. To resolve the error, overwrite the existing object, or skip the object. * A visualization with a different ID, but the same origin already exists, which resulted in a conflict error. The `destinationId` field @@ -307,7 +307,7 @@ Objects are created when the error is resolved using the <>. This example builds upon the <>. -Resolve conflict errors for an index pattern, visualization, and *Canvas* workpad by overwriting the existing saved objects: +Resolve conflict errors for {a-data-source}, visualization, and *Canvas* workpad by overwriting the existing saved objects: [source,sh] -------------------------------------------------- @@ -173,7 +173,7 @@ that were returned in the `successResults` array. In this example, we retried im This example builds upon the <>. -Resolve a missing reference error for a visualization by replacing the index pattern with another, and resolve a missing reference error for +Resolve a missing reference error for a visualization by replacing the {data-source} with another, and resolve a missing reference error for a search by ignoring it: [source,sh] diff --git a/docs/api/saved-objects/update.asciidoc b/docs/api/saved-objects/update.asciidoc index fccc6112948a1..fb7decccabd4c 100644 --- a/docs/api/saved-objects/update.asciidoc +++ b/docs/api/saved-objects/update.asciidoc @@ -54,7 +54,7 @@ WARNING: When you update, attributes are not validated, which allows you to pass [[saved-objects-api-update-example]] ==== Example -Update an existing index pattern object,`my-pattern`, with a different title: +Update an existing {data-source} object,`my-pattern`, with a different title: [source,sh] -------------------------------------------------- diff --git a/docs/api/spaces-management/copy_saved_objects.asciidoc b/docs/api/spaces-management/copy_saved_objects.asciidoc index cf18af9b28a34..0aa6ac58c55cb 100644 --- a/docs/api/spaces-management/copy_saved_objects.asciidoc +++ b/docs/api/spaces-management/copy_saved_objects.asciidoc @@ -8,7 +8,7 @@ experimental[] Copy saved objects between spaces. It also allows you to automatically copy related objects, so when you copy a `dashboard`, this can automatically copy over the -associated visualizations, index patterns, and saved searches, as required. +associated visualizations, {data-sources}, and saved searches, as required. You can request to overwrite any objects that already exist in the target space if they share an ID, or you can use the <> to do this on a per-object basis. @@ -125,7 +125,7 @@ refer to the <>. ===== Successful copy (with `createNewCopies` enabled) Copy a dashboard with the `my-dashboard` ID, including all references from the `default` space to the `marketing` space. In this example, -the dashboard has a reference to a visualization, and that has a reference to an index pattern: +the dashboard has a reference to a visualization, and that has a reference to {a-data-source}: [source,sh] ---- @@ -189,7 +189,7 @@ The result indicates a successful copy, and all three objects are created. Since ===== Successful copy (with `createNewCopies` disabled) Copy a dashboard with the `my-dashboard` ID, including all references from the `default` space to the `marketing` space. In this example, -the dashboard has a reference to a visualization, and that has a reference to an index pattern: +the dashboard has a reference to a visualization, and that has a reference to {a-data-source}: [source,sh] ---- @@ -379,10 +379,10 @@ The API returns the following: } ---- -The result indicates a successful copy for the `marketing` space, and an unsuccessful copy for the `sales` space because the index pattern, +The result indicates a successful copy for the `marketing` space, and an unsuccessful copy for the `sales` space because the {data-source}, visualization, and *Canvas* workpad each resulted in a conflict error: -* An index pattern with the same ID already exists, which resulted in a conflict error. To resolve the error, overwrite the existing object, +* A {data-source} with the same ID already exists, which resulted in a conflict error. To resolve the error, overwrite the existing object, or skip the object. * A visualization with a different ID, but the same origin already exists, which resulted in a conflict error. The `destinationId` field @@ -403,7 +403,7 @@ API>>. ===== Failed copy (with missing reference errors) Copy a dashboard with the `my-dashboard` ID, including all references from the `default` space to the `marketing` space. In this example, -the dashboard has a reference to a visualization and a *Canvas* workpad, and the visualization has a reference to an index pattern: +the dashboard has a reference to a visualization and a *Canvas* workpad, and the visualization has a reference to {a-data-source}: [source,sh] ---- diff --git a/docs/api/spaces-management/resolve_copy_saved_objects_conflicts.asciidoc b/docs/api/spaces-management/resolve_copy_saved_objects_conflicts.asciidoc index 1a0017fe167ab..d79df2c085b19 100644 --- a/docs/api/spaces-management/resolve_copy_saved_objects_conflicts.asciidoc +++ b/docs/api/spaces-management/resolve_copy_saved_objects_conflicts.asciidoc @@ -141,7 +141,7 @@ refer to the < This example builds upon the <>. -Resolve conflict errors for an index pattern, visualization, and *Canvas* workpad by overwriting the existing saved objects: +Resolve conflict errors for {a-data-source}, visualization, and *Canvas* workpad by overwriting the existing saved objects: [source,sh] ---- diff --git a/docs/apm/api.asciidoc b/docs/apm/api.asciidoc index a7e2a93e0944e..43ba30cb7cf83 100644 --- a/docs/apm/api.asciidoc +++ b/docs/apm/api.asciidoc @@ -11,6 +11,7 @@ Some APM app features are provided via a REST API: * <> * <> * <> +* <> [float] [[apm-api-example]] @@ -708,3 +709,105 @@ curl -X DELETE "http://localhost:5601/api/apm/sourcemaps/apm:foo-1.0.0-644fd5a9" -------------------------------------------------- {} -------------------------------------------------- + +//// +******************************************************* +******************************************************* +//// + +[role="xpack"] +[[agent-key-api]] +=== APM agent Key API + +The Agent Key API allows you to configure agent keys to authorize requests from APM agents to the APM Server. + +The following Agent key APIs are available: + +* <> to create an agent key + +[float] +[[use-agent-key-api]] +==== How to use APM APIs + +.Expand for required headers, privileges, and usage details +[%collapsible%closed] +====== +include::api.asciidoc[tag=using-the-APIs] +====== + +//// +******************************************************* +//// + +[[apm-create-agent-key]] +==== Create agent key + +Create an APM agent key. Specify privileges in the request body at creation time. + +[[apm-create-agent-key-privileges]] +===== Privileges + +Users must have at least the `manage_own_api_key` cluster privilege and the required application privileges. + +====== Example role: + +[source,js] +-------------------------------------------------- +POST /_security/role/apm_agent_key_user +{ + "cluster": ["manage_own_api_key"], + "applications": [{ + "application": "apm", + "privileges": ["event:write", "sourcemap:write", "config_agent:read"], + "resources": ["*"] + }] +} +-------------------------------------------------- + +[[apm-create-agent-key-req]] +===== Request + +`POST /api/apm/agent_keys` + +[role="child_attributes"] +[[apm-create-agent-key-req-body]] +===== Request body + +`name`:: +(required, string) Name of the agent key. + +`privileges`:: +(required, array) APM agent key privileges. It can take one or more of the following values: + + - `event:write`. Required for ingesting agent events. + - `config_agent:read`. Required for agents to read agent configuration remotely. + - `sourcemap:write`. Required for uploading sourcemaps. + +[[apm-agent-key-create-example]] +===== Example + +[source,curl] +-------------------------------------------------- +POST /api/apm/agent_keys +{ + "name": "apm-key", + "privileges": ["event:write", "config_agent:read", "sourcemap:write"] +} +-------------------------------------------------- + +[[apm-agent-key-create-body]] +===== Response body + +[source,js] +-------------------------------------------------- +{ + "agentKey": { + "id": "3DCLmn0B3ZMhLUa7WBG9", + "name": "apm-key", + "api_key": "PjGloCGOTzaZr8ilUPvkjA", + "encoded": "M0RDTG1uMEIzWk1oTFVhN1dCRzk6UGpHbG9DR09UemFacjhpbFVQdmtqQQ==" + } +} +-------------------------------------------------- + +Once created, you can copy the API key (Base64 encoded) and use it to to authorize requests from APM agents to the APM Server. \ No newline at end of file diff --git a/docs/concepts/data-views.asciidoc b/docs/concepts/data-views.asciidoc index 870b923f20cf4..98bbba5392b15 100644 --- a/docs/concepts/data-views.asciidoc +++ b/docs/concepts/data-views.asciidoc @@ -12,10 +12,10 @@ or all indices that contain your data. [[data-views-read-only-access]] === Required permissions -* Access to *Data Views* requires the <> +* Access to *Data Views* requires the <> `Data View Management`. -* To create a data view, you must have the <> +* To create a data view, you must have the <> `view_index_metadata`. * If a read-only indicator appears in {kib}, you have insufficient privileges diff --git a/docs/development/core/public/kibana-plugin-core-public.doclinksstart.links.md b/docs/development/core/public/kibana-plugin-core-public.doclinksstart.links.md index 63c29df44019d..bd4aea38d1cee 100644 --- a/docs/development/core/public/kibana-plugin-core-public.doclinksstart.links.md +++ b/docs/development/core/public/kibana-plugin-core-public.doclinksstart.links.md @@ -27,6 +27,9 @@ readonly links: { readonly cloud: { readonly indexManagement: string; }; + readonly console: { + readonly guide: string; + }; readonly dashboard: { readonly guide: string; readonly drilldowns: string; diff --git a/docs/development/core/public/kibana-plugin-core-public.doclinksstart.md b/docs/development/core/public/kibana-plugin-core-public.doclinksstart.md index b60f9ad17e9c4..da42918e4722f 100644 --- a/docs/development/core/public/kibana-plugin-core-public.doclinksstart.md +++ b/docs/development/core/public/kibana-plugin-core-public.doclinksstart.md @@ -17,5 +17,5 @@ export interface DocLinksStart | --- | --- | --- | | [DOC\_LINK\_VERSION](./kibana-plugin-core-public.doclinksstart.doc_link_version.md) | string | | | [ELASTIC\_WEBSITE\_URL](./kibana-plugin-core-public.doclinksstart.elastic_website_url.md) | string | | -| [links](./kibana-plugin-core-public.doclinksstart.links.md) | { readonly settings: string; readonly elasticStackGetStarted: string; readonly upgrade: { readonly upgradingElasticStack: string; }; readonly apm: { readonly kibanaSettings: string; readonly supportedServiceMaps: string; readonly customLinks: string; readonly droppedTransactionSpans: string; readonly upgrading: string; readonly metaData: string; }; readonly canvas: { readonly guide: string; }; readonly cloud: { readonly indexManagement: string; }; readonly dashboard: { readonly guide: string; readonly drilldowns: string; readonly drilldownsTriggerPicker: string; readonly urlDrilldownTemplateSyntax: string; readonly urlDrilldownVariables: string; }; readonly discover: Record<string, string>; readonly filebeat: { readonly base: string; readonly installation: string; readonly configuration: string; readonly elasticsearchOutput: string; readonly elasticsearchModule: string; readonly startup: string; readonly exportedFields: string; readonly suricataModule: string; readonly zeekModule: string; }; readonly auditbeat: { readonly base: string; readonly auditdModule: string; readonly systemModule: string; }; readonly metricbeat: { readonly base: string; readonly configure: string; readonly httpEndpoint: string; readonly install: string; readonly start: string; }; readonly appSearch: { readonly apiRef: string; readonly apiClients: string; readonly apiKeys: string; readonly authentication: string; readonly crawlRules: string; readonly curations: string; readonly duplicateDocuments: string; readonly entryPoints: string; readonly guide: string; readonly indexingDocuments: string; readonly indexingDocumentsSchema: string; readonly logSettings: string; readonly metaEngines: string; readonly precisionTuning: string; readonly relevanceTuning: string; readonly resultSettings: string; readonly searchUI: string; readonly security: string; readonly synonyms: string; readonly webCrawler: string; readonly webCrawlerEventLogs: string; }; readonly enterpriseSearch: { readonly configuration: string; readonly licenseManagement: string; readonly mailService: string; readonly usersAccess: string; }; readonly workplaceSearch: { readonly apiKeys: string; readonly box: string; readonly confluenceCloud: string; readonly confluenceServer: string; readonly customSources: string; readonly customSourcePermissions: string; readonly documentPermissions: string; readonly dropbox: string; readonly externalIdentities: string; readonly gitHub: string; readonly gettingStarted: string; readonly gmail: string; readonly googleDrive: string; readonly indexingSchedule: string; readonly jiraCloud: string; readonly jiraServer: string; readonly oneDrive: string; readonly permissions: string; readonly salesforce: string; readonly security: string; readonly serviceNow: string; readonly sharePoint: string; readonly slack: string; readonly synch: string; readonly zendesk: string; }; readonly heartbeat: { readonly base: string; }; readonly libbeat: { readonly getStarted: string; }; readonly logstash: { readonly base: string; }; readonly functionbeat: { readonly base: string; }; readonly winlogbeat: { readonly base: string; }; readonly aggs: { readonly composite: string; readonly composite\_missing\_bucket: string; readonly date\_histogram: string; readonly date\_range: string; readonly date\_format\_pattern: string; readonly filter: string; readonly filters: string; readonly geohash\_grid: string; readonly histogram: string; readonly ip\_range: string; readonly range: string; readonly significant\_terms: string; readonly terms: string; readonly terms\_doc\_count\_error: string; readonly avg: string; readonly avg\_bucket: string; readonly max\_bucket: string; readonly min\_bucket: string; readonly sum\_bucket: string; readonly cardinality: string; readonly count: string; readonly cumulative\_sum: string; readonly derivative: string; readonly geo\_bounds: string; readonly geo\_centroid: string; readonly max: string; readonly median: string; readonly min: string; readonly moving\_avg: string; readonly percentile\_ranks: string; readonly serial\_diff: string; readonly std\_dev: string; readonly sum: string; readonly top\_hits: string; }; readonly runtimeFields: { readonly overview: string; readonly mapping: string; }; readonly scriptedFields: { readonly scriptFields: string; readonly scriptAggs: string; readonly painless: string; readonly painlessApi: string; readonly painlessLangSpec: string; readonly painlessSyntax: string; readonly painlessWalkthrough: string; readonly luceneExpressions: string; }; readonly search: { readonly sessions: string; readonly sessionLimits: string; }; readonly indexPatterns: { readonly introduction: string; readonly fieldFormattersNumber: string; readonly fieldFormattersString: string; readonly runtimeFields: string; }; readonly addData: string; readonly kibana: string; readonly upgradeAssistant: { readonly overview: string; readonly batchReindex: string; readonly remoteReindex: string; }; readonly rollupJobs: string; readonly elasticsearch: Record<string, string>; readonly siem: { readonly privileges: string; readonly guide: string; readonly gettingStarted: string; readonly ml: string; readonly ruleChangeLog: string; readonly detectionsReq: string; readonly networkMap: string; readonly troubleshootGaps: string; }; readonly securitySolution: { readonly trustedApps: string; }; readonly query: { readonly eql: string; readonly kueryQuerySyntax: string; readonly luceneQuerySyntax: string; readonly percolate: string; readonly queryDsl: string; }; readonly date: { readonly dateMath: string; readonly dateMathIndexNames: string; }; readonly management: Record<string, string>; readonly ml: Record<string, string>; readonly transforms: Record<string, string>; readonly visualize: Record<string, string>; readonly apis: Readonly<{ bulkIndexAlias: string; byteSizeUnits: string; createAutoFollowPattern: string; createFollower: string; createIndex: string; createSnapshotLifecyclePolicy: string; createRoleMapping: string; createRoleMappingTemplates: string; createRollupJobsRequest: string; createApiKey: string; createPipeline: string; createTransformRequest: string; cronExpressions: string; executeWatchActionModes: string; indexExists: string; openIndex: string; putComponentTemplate: string; painlessExecute: string; painlessExecuteAPIContexts: string; putComponentTemplateMetadata: string; putSnapshotLifecyclePolicy: string; putIndexTemplateV1: string; putWatch: string; simulatePipeline: string; timeUnits: string; updateTransform: string; }>; readonly observability: Readonly<{ guide: string; infrastructureThreshold: string; logsThreshold: string; metricsThreshold: string; monitorStatus: string; monitorUptime: string; tlsCertificate: string; uptimeDurationAnomaly: string; }>; readonly alerting: Record<string, string>; readonly maps: Readonly<{ guide: string; importGeospatialPrivileges: string; gdalTutorial: string; }>; readonly monitoring: Record<string, string>; readonly security: Readonly<{ apiKeyServiceSettings: string; clusterPrivileges: string; elasticsearchSettings: string; elasticsearchEnableSecurity: string; elasticsearchEnableApiKeys: string; indicesPrivileges: string; kibanaTLS: string; kibanaPrivileges: string; mappingRoles: string; mappingRolesFieldRules: string; runAsPrivilege: string; }>; readonly spaces: Readonly<{ kibanaLegacyUrlAliases: string; kibanaDisableLegacyUrlAliasesApi: string; }>; readonly watcher: Record<string, string>; readonly ccs: Record<string, string>; readonly plugins: { azureRepo: string; gcsRepo: string; hdfsRepo: string; s3Repo: string; snapshotRestoreRepos: string; mapperSize: string; }; readonly snapshotRestore: Record<string, string>; readonly ingest: Record<string, string>; readonly fleet: Readonly<{ beatsAgentComparison: string; guide: string; fleetServer: string; fleetServerAddFleetServer: string; settings: string; settingsFleetServerHostSettings: string; settingsFleetServerProxySettings: string; troubleshooting: string; elasticAgent: string; datastreams: string; datastreamsNamingScheme: string; installElasticAgent: string; installElasticAgentStandalone: string; upgradeElasticAgent: string; upgradeElasticAgent712lower: string; learnMoreBlog: string; apiKeysLearnMore: string; onPremRegistry: string; }>; readonly ecs: { readonly guide: string; }; readonly clients: { readonly guide: string; readonly goOverview: string; readonly javaIndex: string; readonly jsIntro: string; readonly netGuide: string; readonly perlGuide: string; readonly phpGuide: string; readonly pythonGuide: string; readonly rubyOverview: string; readonly rustGuide: string; }; readonly endpoints: { readonly troubleshooting: string; }; } | | +| [links](./kibana-plugin-core-public.doclinksstart.links.md) | { readonly settings: string; readonly elasticStackGetStarted: string; readonly upgrade: { readonly upgradingElasticStack: string; }; readonly apm: { readonly kibanaSettings: string; readonly supportedServiceMaps: string; readonly customLinks: string; readonly droppedTransactionSpans: string; readonly upgrading: string; readonly metaData: string; }; readonly canvas: { readonly guide: string; }; readonly cloud: { readonly indexManagement: string; }; readonly console: { readonly guide: string; }; readonly dashboard: { readonly guide: string; readonly drilldowns: string; readonly drilldownsTriggerPicker: string; readonly urlDrilldownTemplateSyntax: string; readonly urlDrilldownVariables: string; }; readonly discover: Record<string, string>; readonly filebeat: { readonly base: string; readonly installation: string; readonly configuration: string; readonly elasticsearchOutput: string; readonly elasticsearchModule: string; readonly startup: string; readonly exportedFields: string; readonly suricataModule: string; readonly zeekModule: string; }; readonly auditbeat: { readonly base: string; readonly auditdModule: string; readonly systemModule: string; }; readonly metricbeat: { readonly base: string; readonly configure: string; readonly httpEndpoint: string; readonly install: string; readonly start: string; }; readonly appSearch: { readonly apiRef: string; readonly apiClients: string; readonly apiKeys: string; readonly authentication: string; readonly crawlRules: string; readonly curations: string; readonly duplicateDocuments: string; readonly entryPoints: string; readonly guide: string; readonly indexingDocuments: string; readonly indexingDocumentsSchema: string; readonly logSettings: string; readonly metaEngines: string; readonly precisionTuning: string; readonly relevanceTuning: string; readonly resultSettings: string; readonly searchUI: string; readonly security: string; readonly synonyms: string; readonly webCrawler: string; readonly webCrawlerEventLogs: string; }; readonly enterpriseSearch: { readonly configuration: string; readonly licenseManagement: string; readonly mailService: string; readonly usersAccess: string; }; readonly workplaceSearch: { readonly apiKeys: string; readonly box: string; readonly confluenceCloud: string; readonly confluenceServer: string; readonly customSources: string; readonly customSourcePermissions: string; readonly documentPermissions: string; readonly dropbox: string; readonly externalIdentities: string; readonly gitHub: string; readonly gettingStarted: string; readonly gmail: string; readonly googleDrive: string; readonly indexingSchedule: string; readonly jiraCloud: string; readonly jiraServer: string; readonly oneDrive: string; readonly permissions: string; readonly salesforce: string; readonly security: string; readonly serviceNow: string; readonly sharePoint: string; readonly slack: string; readonly synch: string; readonly zendesk: string; }; readonly heartbeat: { readonly base: string; }; readonly libbeat: { readonly getStarted: string; }; readonly logstash: { readonly base: string; }; readonly functionbeat: { readonly base: string; }; readonly winlogbeat: { readonly base: string; }; readonly aggs: { readonly composite: string; readonly composite\_missing\_bucket: string; readonly date\_histogram: string; readonly date\_range: string; readonly date\_format\_pattern: string; readonly filter: string; readonly filters: string; readonly geohash\_grid: string; readonly histogram: string; readonly ip\_range: string; readonly range: string; readonly significant\_terms: string; readonly terms: string; readonly terms\_doc\_count\_error: string; readonly avg: string; readonly avg\_bucket: string; readonly max\_bucket: string; readonly min\_bucket: string; readonly sum\_bucket: string; readonly cardinality: string; readonly count: string; readonly cumulative\_sum: string; readonly derivative: string; readonly geo\_bounds: string; readonly geo\_centroid: string; readonly max: string; readonly median: string; readonly min: string; readonly moving\_avg: string; readonly percentile\_ranks: string; readonly serial\_diff: string; readonly std\_dev: string; readonly sum: string; readonly top\_hits: string; }; readonly runtimeFields: { readonly overview: string; readonly mapping: string; }; readonly scriptedFields: { readonly scriptFields: string; readonly scriptAggs: string; readonly painless: string; readonly painlessApi: string; readonly painlessLangSpec: string; readonly painlessSyntax: string; readonly painlessWalkthrough: string; readonly luceneExpressions: string; }; readonly search: { readonly sessions: string; readonly sessionLimits: string; }; readonly indexPatterns: { readonly introduction: string; readonly fieldFormattersNumber: string; readonly fieldFormattersString: string; readonly runtimeFields: string; }; readonly addData: string; readonly kibana: string; readonly upgradeAssistant: { readonly overview: string; readonly batchReindex: string; readonly remoteReindex: string; }; readonly rollupJobs: string; readonly elasticsearch: Record<string, string>; readonly siem: { readonly privileges: string; readonly guide: string; readonly gettingStarted: string; readonly ml: string; readonly ruleChangeLog: string; readonly detectionsReq: string; readonly networkMap: string; readonly troubleshootGaps: string; }; readonly securitySolution: { readonly trustedApps: string; }; readonly query: { readonly eql: string; readonly kueryQuerySyntax: string; readonly luceneQuerySyntax: string; readonly percolate: string; readonly queryDsl: string; }; readonly date: { readonly dateMath: string; readonly dateMathIndexNames: string; }; readonly management: Record<string, string>; readonly ml: Record<string, string>; readonly transforms: Record<string, string>; readonly visualize: Record<string, string>; readonly apis: Readonly<{ bulkIndexAlias: string; byteSizeUnits: string; createAutoFollowPattern: string; createFollower: string; createIndex: string; createSnapshotLifecyclePolicy: string; createRoleMapping: string; createRoleMappingTemplates: string; createRollupJobsRequest: string; createApiKey: string; createPipeline: string; createTransformRequest: string; cronExpressions: string; executeWatchActionModes: string; indexExists: string; openIndex: string; putComponentTemplate: string; painlessExecute: string; painlessExecuteAPIContexts: string; putComponentTemplateMetadata: string; putSnapshotLifecyclePolicy: string; putIndexTemplateV1: string; putWatch: string; simulatePipeline: string; timeUnits: string; updateTransform: string; }>; readonly observability: Readonly<{ guide: string; infrastructureThreshold: string; logsThreshold: string; metricsThreshold: string; monitorStatus: string; monitorUptime: string; tlsCertificate: string; uptimeDurationAnomaly: string; }>; readonly alerting: Record<string, string>; readonly maps: Readonly<{ guide: string; importGeospatialPrivileges: string; gdalTutorial: string; }>; readonly monitoring: Record<string, string>; readonly security: Readonly<{ apiKeyServiceSettings: string; clusterPrivileges: string; elasticsearchSettings: string; elasticsearchEnableSecurity: string; elasticsearchEnableApiKeys: string; indicesPrivileges: string; kibanaTLS: string; kibanaPrivileges: string; mappingRoles: string; mappingRolesFieldRules: string; runAsPrivilege: string; }>; readonly spaces: Readonly<{ kibanaLegacyUrlAliases: string; kibanaDisableLegacyUrlAliasesApi: string; }>; readonly watcher: Record<string, string>; readonly ccs: Record<string, string>; readonly plugins: { azureRepo: string; gcsRepo: string; hdfsRepo: string; s3Repo: string; snapshotRestoreRepos: string; mapperSize: string; }; readonly snapshotRestore: Record<string, string>; readonly ingest: Record<string, string>; readonly fleet: Readonly<{ beatsAgentComparison: string; guide: string; fleetServer: string; fleetServerAddFleetServer: string; settings: string; settingsFleetServerHostSettings: string; settingsFleetServerProxySettings: string; troubleshooting: string; elasticAgent: string; datastreams: string; datastreamsNamingScheme: string; installElasticAgent: string; installElasticAgentStandalone: string; upgradeElasticAgent: string; upgradeElasticAgent712lower: string; learnMoreBlog: string; apiKeysLearnMore: string; onPremRegistry: string; }>; readonly ecs: { readonly guide: string; }; readonly clients: { readonly guide: string; readonly goOverview: string; readonly javaIndex: string; readonly jsIntro: string; readonly netGuide: string; readonly perlGuide: string; readonly phpGuide: string; readonly pythonGuide: string; readonly rubyOverview: string; readonly rustGuide: string; }; readonly endpoints: { readonly troubleshooting: string; }; } | | diff --git a/docs/management/connectors/action-types/index.asciidoc b/docs/management/connectors/action-types/index.asciidoc index 7868085ef9c96..98f7dac4de81d 100644 --- a/docs/management/connectors/action-types/index.asciidoc +++ b/docs/management/connectors/action-types/index.asciidoc @@ -74,7 +74,7 @@ Example of the index document for Index Threshold rule: "rule_name": "{{ruleName}}", "alert_id": "{{alertId}}", "context_message": "{{context.message}}" -} +} -------------------------------------------------- Example of creating a test index using the API. @@ -108,7 +108,7 @@ experimental[] {kib} offers a preconfigured index connector to facilitate indexi This functionality is experimental and may be changed or removed completely in a future release. ================================================== -To use this connector, set the <> configuration to `true`. +To use this connector, set the <> configuration to `true`. ```js xpack.actions.preconfiguredAlertHistoryEsIndex: true @@ -123,11 +123,11 @@ Documents are indexed using a preconfigured schema that captures the <> for more information. +To write documents to the preconfigured index, you must have `all` or `write` privileges to the `kibana-alert-history-*` indices. Refer to <> for more information. ============================================== [NOTE] ================================================== The `kibana-alert-history-*` indices are not configured to use ILM so they must be maintained manually. If the index size grows large, consider using the {ref}/docs-delete-by-query.html[delete by query] API to clean up older documents in the index. -================================================== \ No newline at end of file +================================================== diff --git a/docs/maps/import-geospatial-data.asciidoc b/docs/maps/import-geospatial-data.asciidoc index c7b12c4ac32f6..58d9ca2255dd3 100644 --- a/docs/maps/import-geospatial-data.asciidoc +++ b/docs/maps/import-geospatial-data.asciidoc @@ -17,7 +17,7 @@ The {stack-security-features} provide roles and privileges that control which us You can manage your roles, privileges, and spaces in **{stack-manage-app}** in {kib}. For more information, see {ref}/security-privileges.html[Security privileges], -<>, and <>. +<>, and <>. To upload GeoJSON files in {kib} with *Maps*, you must have: diff --git a/docs/redirects.asciidoc b/docs/redirects.asciidoc index 6fafe1ce2506d..5d161711719ac 100644 --- a/docs/redirects.asciidoc +++ b/docs/redirects.asciidoc @@ -416,27 +416,32 @@ This content has moved. Refer to <>. This content has moved. Refer to <>. -[role="exclude",id="index-patterns-runtime-field-api-delete] +[role="exclude",id="index-patterns-runtime-field-api-delete"] == Index patterns has been renamed to data views. This content has moved. Refer to <>. -[role="exclude",id="index-patterns-runtime-field-api-get] +[role="exclude",id="index-patterns-runtime-field-api-get"] == Index patterns has been renamed to data views. This content has moved. Refer to <>. -[role="exclude",id="index-patterns-runtime-field-api-update] +[role="exclude",id="index-patterns-runtime-field-api-update"] == Index patterns has been renamed to data views. This content has moved. Refer to <>. -[role="exclude",id="index-patterns-runtime-field-api-upsert] +[role="exclude",id="index-patterns-runtime-field-api-upsert"] == Index patterns has been renamed to data views. This content has moved. Refer to <>. -[role="exclude",id="index-patterns-api-update] +[role="exclude",id="index-patterns-api-update"] == Index patterns has been renamed to data views. This content has moved. Refer to <>. + +[role="exclude",id="xpack-kibana-role-management"] +== Kibana role management. + +This content has moved. Refer to <>. diff --git a/docs/setup/access.asciidoc b/docs/setup/access.asciidoc index 3fc1aa43f9f29..77ad6ffb9c602 100644 --- a/docs/setup/access.asciidoc +++ b/docs/setup/access.asciidoc @@ -16,7 +16,7 @@ If you are using a self-managed deployment, access {kib} through the web applica . Point your web browser to the machine where you are running {kib} and specify the port number. For example, `localhost:5601` or `http://YOURDOMAIN.com:5601`. + -To remotely connect to {kib}, set > to a non-loopback address. +To remotely connect to {kib}, set <> to a non-loopback address. . Log on to your account. diff --git a/docs/user/dashboard/aggregation-based.asciidoc b/docs/user/dashboard/aggregation-based.asciidoc index 351e1f5d0825a..c4f26e701bccf 100644 --- a/docs/user/dashboard/aggregation-based.asciidoc +++ b/docs/user/dashboard/aggregation-based.asciidoc @@ -114,7 +114,7 @@ Choose the type of visualization you want to create, then use the editor to conf . Add the <> you want to visualize using the editor, then click *Update*. + -NOTE: For the *Date Histogram* to use an *auto interval*, the date field must match the primary time field of the index pattern. +NOTE: For the *Date Histogram* to use an *auto interval*, the date field must match the primary time field of the {data-source}. . To change the order, drag and drop the aggregations in the editor. + diff --git a/docs/user/dashboard/images/lens_dataViewDropDown_8.0.png b/docs/user/dashboard/images/lens_dataViewDropDown_8.0.png new file mode 100644 index 0000000000000..309e1be49b9db Binary files /dev/null and b/docs/user/dashboard/images/lens_dataViewDropDown_8.0.png differ diff --git a/docs/user/dashboard/images/lens_indexPatternDropDown_7.16.png b/docs/user/dashboard/images/lens_indexPatternDropDown_7.16.png deleted file mode 100644 index f8e797c7dd4b6..0000000000000 Binary files a/docs/user/dashboard/images/lens_indexPatternDropDown_7.16.png and /dev/null differ diff --git a/docs/user/dashboard/lens-advanced.asciidoc b/docs/user/dashboard/lens-advanced.asciidoc index 324676ecb0a8e..eaa2014717714 100644 --- a/docs/user/dashboard/lens-advanced.asciidoc +++ b/docs/user/dashboard/lens-advanced.asciidoc @@ -34,7 +34,7 @@ Open the visualization editor, then make sure the correct fields appear. . On the dashboard, click *Create visualization*. -. Make sure the *kibana_sample_data_ecommerce* index appears, then set the <> to *Last 30 days*. +. Make sure the *kibana_sample_data_ecommerce* {data-source} appears, then set the <> to *Last 30 days*. [discrete] [[custom-time-interval]] diff --git a/docs/user/dashboard/lens.asciidoc b/docs/user/dashboard/lens.asciidoc index 1b0bbf866b852..1fcc3eb797b59 100644 --- a/docs/user/dashboard/lens.asciidoc +++ b/docs/user/dashboard/lens.asciidoc @@ -48,7 +48,7 @@ Choose the data you want to visualize. . If you want to learn more about the data a field contains, click the field. -. To visualize more than one index pattern, click *Add layer > Add visualization layer*, then select the index pattern. +. To visualize more than one {data-source}, click *Add layer > Add visualization layer*, then select the {data-source}. Edit and delete. @@ -60,18 +60,18 @@ Edit and delete. [[change-the-fields]] ==== Change the fields list -Change the fields list to display a different index pattern, different time range, or add your own fields. +Change the fields list to display a different {data-source}, different time range, or add your own fields. -* To create a visualization with fields in a different index pattern, open the *Index pattern* dropdown, then select the index pattern. +* To create a visualization with fields in a different {data-source}, open the *Data view* dropdown, then select the {data-source}. * If the fields list is empty, change the <>. -* To add fields, open the action menu (*...*) next to the *Index pattern* dropdown, then select *Add field to index pattern*. +* To add fields, open the action menu (*...*) next to the *Data view* dropdown, then select *Add field to {data-source}*. + [role="screenshot"] -image:images/runtime-field-menu.png[Dropdown menu located next to index pattern field with items for adding and managing fields, width=50%] +image:images/runtime-field-menu.png[Dropdown menu located next to {data-source} field with items for adding and managing fields, width=50%] + -For more information about adding fields to index patterns and examples, refer to <>. +For more information about adding fields to {data-sources} and examples, refer to <>. [float] [[create-custom-tables]] @@ -453,7 +453,7 @@ To configure the bounds, use the menus in the editor toolbar. Bar and area chart .*Is it possible to display icons in data tables?* [%collapsible] ==== -You can display icons with <> in data tables. +You can display icons with <> in data tables. ==== [discrete] diff --git a/docs/user/dashboard/timelion.asciidoc b/docs/user/dashboard/timelion.asciidoc index 8d89adc454d63..19962d11f7335 100644 --- a/docs/user/dashboard/timelion.asciidoc +++ b/docs/user/dashboard/timelion.asciidoc @@ -34,7 +34,7 @@ The fist parameter of the .es function is the parameter q (for query), which is .es(*) .es(q=*) -Multiple parameters are separated by comma. The .es function has another parameter called index, that can be used to specify an index pattern for this series, so the query won't be executed again all indexes (or whatever you changed the above mentioned setting to). +Multiple parameters are separated by a comma. The .es function has another parameter called index, that can be used to specify {a-data-source} for this series, so the query won't be executed against all indexes (or whatever you changed the setting to). .es(q=*, index=logstash-*) diff --git a/docs/user/dashboard/tsvb.asciidoc b/docs/user/dashboard/tsvb.asciidoc index 1c90c28826f6e..a1bad870dde46 100644 --- a/docs/user/dashboard/tsvb.asciidoc +++ b/docs/user/dashboard/tsvb.asciidoc @@ -16,7 +16,7 @@ With *TSVB*, you can: image::images/tsvb-screenshot.png[TSVB overview] [float] -[[tsvb-index-pattern-mode]] +[[tsvb-data-view-mode]] ==== Open and set up TSVB Open *TSVB*, then configure the required settings. You can create *TSVB* visualizations with only {data-sources}, or {es} index strings. @@ -31,17 +31,19 @@ When you use only {data-sources}, you are able to: * Improve performance +[[tsvb-index-pattern-mode]] + IMPORTANT: Creating *TSVB* visualizations with an {es} index string is deprecated and will be removed in a future release. By default, you create *TSVB* visualizations with only {data-sources}. To use an {es} index string, contact your administrator, or go to <> and set `metrics:allowStringIndices` to `true`. . On the dashboard, click *All types*, then select *TSVB*. . In *TSVB*, click *Panel options*, then specify the *Data* settings. -. Open the *Index pattern selection mode* options next to the *Index pattern* dropdown. +. Open the *Data view mode* options next to the *Data view* dropdown. . Select *Use only {kib} {data-sources}*. -. From the *Index pattern* drodpown, select the {data-source}, then select the *Time field* and *Interval*. +. From the *Data view* drodpown, select the {data-source}, then select the *Time field* and *Interval*. . Select a *Drop last bucket* option. + @@ -258,9 +260,9 @@ Calculating the duration between the start and end of an event is unsupported in [%collapsible] ==== -To group with multiple fields, create runtime fields in the index pattern you are visualizing. +To group with multiple fields, create runtime fields in the {data-source} you are visualizing. -. Create a runtime field. Refer to <> for more information. +. Create a runtime field. Refer to <> for more information. + [role="screenshot"] image::images/tsvb_group_by_multiple_fields.png[Group by multiple fields] 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 e270c16cf60f6..4d36647c808b3 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 @@ -41,7 +41,7 @@ Open the visualization editor, then make sure the correct fields appear. . Make sure the *kibana_sample_data_logs* index appears. + [role="screenshot"] -image::images/lens_indexPatternDropDown_7.16.png[Index pattern dropdown] +image::images/lens_dataViewDropDown_8.0.png[Data view dropdown] To create the visualizations in this tutorial, you'll use the following fields: @@ -96,7 +96,7 @@ image::images/lens_metricUniqueVisitors_7.16.png[Metric visualization that displ There are two shortcuts you can use to view metrics over time. When you drag a numeric field to the workspace, the visualization editor adds the default -time field from the index pattern. When you use the *Date histogram* function, you can +time field from the {data-source}. When you use the *Date histogram* function, you can replace the time field by dragging the field to the workspace. To visualize the *bytes* field over time: diff --git a/docs/user/dashboard/url-drilldown.asciidoc b/docs/user/dashboard/url-drilldown.asciidoc index 7a092b4686e2d..99cbf6f8eb533 100644 --- a/docs/user/dashboard/url-drilldown.asciidoc +++ b/docs/user/dashboard/url-drilldown.asciidoc @@ -202,7 +202,7 @@ Tip: Use in combination with <> helper to format date. | | context.panel.indexPatternId + context.panel.indexPatternIds -|Index pattern ids used by a panel. +|The {data-source} IDs used by a panel. | | context.panel.savedObjectId diff --git a/docs/user/dashboard/vega.asciidoc b/docs/user/dashboard/vega.asciidoc index cd893dfe8d944..fd2055a085c5e 100644 --- a/docs/user/dashboard/vega.asciidoc +++ b/docs/user/dashboard/vega.asciidoc @@ -10,7 +10,7 @@ URL, or static data, and support <> Add or delete users and assign roles that give users specific privileges. -| <> +| <> |View the roles that exist on your cluster. Customize the actions that a user with the role can perform, on a cluster, index, and space level. diff --git a/docs/user/security/authorization/index.asciidoc b/docs/user/security/authorization/index.asciidoc index df4ad4e2b89b0..b478e8b7c38d5 100644 --- a/docs/user/security/authorization/index.asciidoc +++ b/docs/user/security/authorization/index.asciidoc @@ -23,7 +23,7 @@ Whichever approach you use, be careful when granting cluster privileges and inde cluster, and {kib} spaces do not prevent you from granting users of two different tenants access to the same index. [role="xpack"] -[[xpack-kibana-role-management]] +[[kibana-role-management]] === {kib} role management Roles are a collection of privileges that allow you to perform actions in {kib} and {es}. Users are not directly granted privileges, but are instead assigned one or more roles that describe the desired level of access. When you assign a user multiple roles, the user receives a union of the roles’ privileges. This means that you cannot reduce the privileges of a user by assigning them an additional role. You must instead remove or edit one of their existing roles. diff --git a/docs/user/security/tutorials/how-to-secure-access-to-kibana.asciidoc b/docs/user/security/tutorials/how-to-secure-access-to-kibana.asciidoc index dd913a5bb28d8..9e457ee409f4b 100644 --- a/docs/user/security/tutorials/how-to-secure-access-to-kibana.asciidoc +++ b/docs/user/security/tutorials/how-to-secure-access-to-kibana.asciidoc @@ -131,6 +131,6 @@ This guide is an introduction to {kib}'s security features. Check out these addi * View the <> to learn more about single-sign on and other login features. -* View the <> to learn more about authorizing access to {kib}'s features. +* View the <> to learn more about authorizing access to {kib}'s features. Still have questions? Ask on our https://discuss.elastic.co/c/kibana[Kibana discuss forum] and a fellow community member or Elastic engineer will help out. diff --git a/docs/user/troubleshooting/index.asciidoc b/docs/user/troubleshooting/index.asciidoc new file mode 100644 index 0000000000000..aaa6f731db07a --- /dev/null +++ b/docs/user/troubleshooting/index.asciidoc @@ -0,0 +1,10 @@ +[[kibana-troubleshooting]] +== Troubleshooting + +{kib} provides the following tools for debugging issues: + +* <> +* <> + +include::using-server-logs.asciidoc[] +include::trace-query.asciidoc[] diff --git a/docs/user/troubleshooting/trace-query.asciidoc b/docs/user/troubleshooting/trace-query.asciidoc new file mode 100644 index 0000000000000..70c7853d3a3f3 --- /dev/null +++ b/docs/user/troubleshooting/trace-query.asciidoc @@ -0,0 +1,44 @@ +[[kibana-troubleshooting-trace-query]] +=== Trace {es} query to the origin in {kib} +Sometimes the {es} server might be slowed down by the execution of an expensive query. Such queries are logged to {es}'s {ref}/index-modules-slowlog.html#search-slow-log[search slow log] file. But there is a problem: it's impossible to say what triggered a slow search request—a {kib} instance or a user accessing an {es} endpoint directly. +To simplify the investigation of such cases, the search slow log file includes the `x-opaque-id` header, which might provide additional information about a request if it originated from {kib}. + +WARNING: At the moment, {kib} can only highlight cases where a slow query originated from a {kib} visualization, *Lens*, *Discover*, or *Alerting*. + +For example, if a request to {es} was initiated by a Vega visualization on a dashboard, you will see the following in the slow logs: +[source,json] +---- +"source": { "id": "c89d1ab3-b4a7-4920-a64a-22a910a413b0;kibana:application:dashboard:edf84fe0-e1a0-11e7-b6d5-4dc382ef7f5b;visualization:Vega:cb099a20-ea66-11eb-9425-113343a037e3" } +---- + +Take a closer look at the format of the string. +The id value starts with `c89d1ab3-b4a7-4920-a64a-22a910a413b0`, which is a unique identifier of a request set by the {kib} server. +The part after the `kibana` prefix indicates that the request was triggered by *Dashboard* with id `edf84fe0-e1a0-11e7-b6d5-4dc382ef7f5b` and Vega visualization with id `cb099a20-ea66-11eb-9425-113343a037e3`. + +If the provided information is not enough to identify a visualization to adjust its parameters, you can configure {kib} logs to provide a human-readable description and a link to a source of the request: +[source,yml] +---- +logging: + loggers: + - name: execution_context + level: debug + appenders: [console] +---- +Now, you can see the request to {es} has been initiated by the `[Logs] Unique Visitor Heatmap` visualization embedded in the `[Logs] Web Traffic` dashboard. You can navigate to the provided URL to change some parameters of the visualization. + +[source,text] +---- +[DEBUG][execution_context] stored the execution context: { + "parent": { + "type": "application", + "name": "dashboard", + "id": "edf84fe0-e1a0-11e7-b6d5-4dc382ef7f5b", + "description": "[Logs] Web Traffic","url":"/view/edf84fe0-e1a0-11e7-b6d5-4dc382ef7f5b" + }, + "type": "visualization", + "name": "Vega", + "id": "cb099a20-ea66-11eb-9425-113343a037e3", + "description": "[Logs] Unique Visitor Heatmap", + "url": "/app/visualize#/edit/cb099a20-ea66-11eb-9425-113343a037e3" +} +---- diff --git a/docs/user/troubleshooting.asciidoc b/docs/user/troubleshooting/using-server-logs.asciidoc similarity index 98% rename from docs/user/troubleshooting.asciidoc rename to docs/user/troubleshooting/using-server-logs.asciidoc index 8b32471c98d86..acc3830ae61d6 100644 --- a/docs/user/troubleshooting.asciidoc +++ b/docs/user/troubleshooting/using-server-logs.asciidoc @@ -1,6 +1,4 @@ -[[kibana-troubleshooting]] -== Troubleshooting - +[[kibana-troubleshooting-kibana-server-logs]] === Using {kib} server logs {kib} Logs is a great way to see what's going on in your application and to debug performance issues. Navigating through a large number of generated logs can be overwhelming, and following are some techniques that you can use to optimize the process. diff --git a/examples/data_view_field_editor_example/public/app.tsx b/examples/data_view_field_editor_example/public/app.tsx index ac7e3b60482e0..cbad86d7e21d4 100644 --- a/examples/data_view_field_editor_example/public/app.tsx +++ b/examples/data_view_field_editor_example/public/app.tsx @@ -20,23 +20,20 @@ import { DefaultItemAction, } from '@elastic/eui'; import { AppMountParameters } from '../../../src/core/public'; -import { - DataPublicPluginStart, - IndexPattern, - IndexPatternField, -} from '../../../src/plugins/data/public'; +import { DataPublicPluginStart } from '../../../src/plugins/data/public'; +import type { DataView, DataViewField } from '../../../src/plugins/data_views/public'; import { IndexPatternFieldEditorStart } from '../../../src/plugins/data_view_field_editor/public'; interface Props { - indexPattern?: IndexPattern; + dataView?: DataView; dataViewFieldEditor: IndexPatternFieldEditorStart; } -const IndexPatternFieldEditorExample = ({ indexPattern, dataViewFieldEditor }: Props) => { - const [fields, setFields] = useState( - indexPattern?.getNonScriptedFields() || [] +const DataViewFieldEditorExample = ({ dataView, dataViewFieldEditor }: Props) => { + const [fields, setFields] = useState( + dataView?.fields.getAll().filter((f) => !f.scripted) || [] ); - const refreshFields = () => setFields(indexPattern?.getNonScriptedFields() || []); + const refreshFields = () => setFields(dataView?.fields.getAll().filter((f) => !f.scripted) || []); const columns = [ { field: 'name', @@ -51,9 +48,9 @@ const IndexPatternFieldEditorExample = ({ indexPattern, dataViewFieldEditor }: P icon: 'pencil', type: 'icon', 'data-test-subj': 'editField', - onClick: (fld: IndexPatternField) => + onClick: (fld: DataViewField) => dataViewFieldEditor.openEditor({ - ctx: { dataView: indexPattern! }, + ctx: { dataView: dataView! }, fieldName: fld.name, onSave: refreshFields, }), @@ -65,27 +62,27 @@ const IndexPatternFieldEditorExample = ({ indexPattern, dataViewFieldEditor }: P type: 'icon', 'data-test-subj': 'deleteField', available: (fld) => !!fld.runtimeField, - onClick: (fld: IndexPatternField) => + onClick: (fld: DataViewField) => dataViewFieldEditor.openDeleteModal({ fieldName: fld.name, ctx: { - dataView: indexPattern!, + dataView: dataView!, }, onDelete: refreshFields, }), }, - ] as Array>, + ] as Array>, }, ]; - const content = indexPattern ? ( + const content = dataView ? ( <> - Index pattern: {indexPattern?.title} + Data view: {dataView.title}
dataViewFieldEditor.openEditor({ - ctx: { dataView: indexPattern! }, + ctx: { dataView }, onSave: refreshFields, }) } @@ -94,7 +91,7 @@ const IndexPatternFieldEditorExample = ({ indexPattern, dataViewFieldEditor }: P Add field
- + items={fields} columns={columns} pagination={true} @@ -108,13 +105,13 @@ const IndexPatternFieldEditorExample = ({ indexPattern, dataViewFieldEditor }: P /> ) : ( -

Please create an index pattern

+

Please create a data view

); return ( - Index pattern field editor demo + Data view field editor demo {content} @@ -132,12 +129,9 @@ export const renderApp = async ( { data, dataViewFieldEditor }: RenderAppDependencies, { element }: AppMountParameters ) => { - const indexPattern = (await data.indexPatterns.getDefault()) || undefined; + const dataView = (await data.dataViews.getDefault()) || undefined; ReactDOM.render( - , + , element ); diff --git a/examples/data_view_field_editor_example/public/index.ts b/examples/data_view_field_editor_example/public/index.ts index cc509da31d25f..77fcce64d3a9b 100644 --- a/examples/data_view_field_editor_example/public/index.ts +++ b/examples/data_view_field_editor_example/public/index.ts @@ -6,6 +6,6 @@ * Side Public License, v 1. */ -import { IndexPatternFieldEditorPlugin } from './plugin'; +import { DataViewFieldEditorPlugin } from './plugin'; -export const plugin = () => new IndexPatternFieldEditorPlugin(); +export const plugin = () => new DataViewFieldEditorPlugin(); diff --git a/examples/data_view_field_editor_example/public/plugin.tsx b/examples/data_view_field_editor_example/public/plugin.tsx index 92d18030e19b8..3cf0ce618ad3b 100644 --- a/examples/data_view_field_editor_example/public/plugin.tsx +++ b/examples/data_view_field_editor_example/public/plugin.tsx @@ -20,11 +20,11 @@ interface SetupDeps { developerExamples: DeveloperExamplesSetup; } -export class IndexPatternFieldEditorPlugin implements Plugin { +export class DataViewFieldEditorPlugin implements Plugin { public setup(core: CoreSetup, deps: SetupDeps) { core.application.register({ - id: 'indexPatternFieldEditorExample', - title: 'Index pattern field editor example', + id: 'dataViewFieldEditorExample', + title: 'Data view field editor example', navLinkStatus: AppNavLinkStatus.hidden, async mount(params: AppMountParameters) { const [, depsStart] = await core.getStartServices(); @@ -34,13 +34,13 @@ export class IndexPatternFieldEditorPlugin implements Plugin void; + openDateViewNumberFieldEditor: () => void; } const UsingAnExistingFieldFormatExample: React.FC<{ deps: Deps }> = (props) => { @@ -123,15 +123,15 @@ const CreatingCustomFieldFormat: React.FC<{ deps: Deps }> = (props) => {

- Currency formatter that we've just created is already integrated with index patterns. - It can be applied to any numeric field of any index pattern.{' '} - props.deps.openIndexPatternNumberFieldEditor()}> - Open index pattern field editor to give it a try. + Currency formatter that we've just created is already integrated with data views. It + can be applied to any numeric field of any data view.{' '} + props.deps.openDateViewNumberFieldEditor()}> + Open data view field editor to give it a try.

@@ -155,15 +155,15 @@ const CreatingCustomFieldFormatEditor: React.FC<{ deps: Deps }> = (props) => {

- Currency formatter and its custom editor are integrated with index patterns. It can be - applied to any numeric field of any index pattern.{' '} - props.deps.openIndexPatternNumberFieldEditor()}> - Open index pattern field editor to give it a try. + Currency formatter and its custom editor are integrated with data views. It can be applied + to any numeric field of any data view.{' '} + props.deps.openDateViewNumberFieldEditor()}> + Open date view field editor to give it a try.

diff --git a/examples/field_formats_example/public/plugin.tsx b/examples/field_formats_example/public/plugin.tsx index b12304c4ce080..8e8018a0f5e6e 100755 --- a/examples/field_formats_example/public/plugin.tsx +++ b/examples/field_formats_example/public/plugin.tsx @@ -45,29 +45,29 @@ export class FieldFormatsExamplePlugin implements Plugin { + // opens a field editor using default data view and first number field + const openDateViewNumberFieldEditor = async () => { const [, plugins] = await core.getStartServices(); - const indexPattern = await plugins.data.indexPatterns.getDefault(); - if (!indexPattern) { - alert('Creating at least one index pattern to continue with this example'); + const dataView = await plugins.data.dataViews.getDefault(); + if (!dataView) { + alert('Create at least one data view to continue with this example'); return; } - const numberField = indexPattern - .getNonScriptedFields() - .find((f) => !f.name.startsWith('_') && f.type === KBN_FIELD_TYPES.NUMBER); + const numberField = dataView.fields + .getAll() + .find((f) => !f.name.startsWith('_') && f.type === KBN_FIELD_TYPES.NUMBER && !f.scripted); if (!numberField) { alert( - 'Default index pattern needs at least a single field of type `number` to continue with this example' + 'Default data view needs at least a single field of type `number` to continue with this example' ); return; } plugins.dataViewFieldEditor.openEditor({ ctx: { - dataView: indexPattern, + dataView, }, fieldName: numberField.name, }); @@ -81,7 +81,7 @@ export class FieldFormatsExamplePlugin implements Plugin, + , element ); return () => ReactDOM.unmountComponentAtNode(element); diff --git a/examples/search_examples/public/search/app.tsx b/examples/search_examples/public/search/app.tsx index eeceab569d3b3..9220827863852 100644 --- a/examples/search_examples/public/search/app.tsx +++ b/examples/search_examples/public/search/app.tsx @@ -41,11 +41,10 @@ import { PLUGIN_ID, PLUGIN_NAME, SERVER_SEARCH_ROUTE_PATH } from '../../common'; import { DataPublicPluginStart, IKibanaSearchResponse, - IndexPattern, - IndexPatternField, isCompleteResponse, isErrorResponse, } from '../../../../src/plugins/data/public'; +import type { DataViewField, DataView } from '../../../../src/plugins/data_views/public'; import { IMyStrategyResponse } from '../../common/types'; import { AbortError } from '../../../../src/plugins/kibana_utils/common'; @@ -56,22 +55,22 @@ interface SearchExamplesAppDeps { data: DataPublicPluginStart; } -function getNumeric(fields?: IndexPatternField[]) { +function getNumeric(fields?: DataViewField[]) { if (!fields) return []; return fields?.filter((f) => f.type === 'number' && f.aggregatable); } -function getAggregatableStrings(fields?: IndexPatternField[]) { +function getAggregatableStrings(fields?: DataViewField[]) { if (!fields) return []; return fields?.filter((f) => f.type === 'string' && f.aggregatable); } -function formatFieldToComboBox(field?: IndexPatternField | null) { +function formatFieldToComboBox(field?: DataViewField | null) { if (!field) return []; return formatFieldsToComboBox([field]); } -function formatFieldsToComboBox(fields?: IndexPatternField[]) { +function formatFieldsToComboBox(fields?: DataViewField[]) { if (!fields) return []; return fields?.map((field) => { @@ -93,14 +92,14 @@ export const SearchExamplesApp = ({ const [timeTook, setTimeTook] = useState(); const [total, setTotal] = useState(100); const [loaded, setLoaded] = useState(0); - const [indexPattern, setIndexPattern] = useState(); - const [fields, setFields] = useState(); - const [selectedFields, setSelectedFields] = useState([]); + const [dataView, setDataView] = useState(); + const [fields, setFields] = useState(); + const [selectedFields, setSelectedFields] = useState([]); const [selectedNumericField, setSelectedNumericField] = useState< - IndexPatternField | null | undefined + DataViewField | null | undefined >(); const [selectedBucketField, setSelectedBucketField] = useState< - IndexPatternField | null | undefined + DataViewField | null | undefined >(); const [request, setRequest] = useState>({}); const [isLoading, setIsLoading] = useState(false); @@ -115,20 +114,20 @@ export const SearchExamplesApp = ({ setTimeTook(response.rawResponse.took); } - // Fetch the default index pattern using the `data.indexPatterns` service, as the component is mounted. + // Fetch the default data view using the `data.dataViews` service, as the component is mounted. useEffect(() => { - const setDefaultIndexPattern = async () => { - const defaultIndexPattern = await data.indexPatterns.getDefault(); - setIndexPattern(defaultIndexPattern); + const setDefaultDataView = async () => { + const defaultDataView = await data.dataViews.getDefault(); + setDataView(defaultDataView); }; - setDefaultIndexPattern(); + setDefaultDataView(); }, [data]); - // Update the fields list every time the index pattern is modified. + // Update the fields list every time the data view is modified. useEffect(() => { - setFields(indexPattern?.fields); - }, [indexPattern]); + setFields(dataView?.fields); + }, [dataView]); useEffect(() => { setSelectedBucketField(fields?.length ? getAggregatableStrings(fields)[0] : null); setSelectedNumericField(fields?.length ? getNumeric(fields)[0] : null); @@ -140,10 +139,10 @@ export const SearchExamplesApp = ({ addWarning: boolean = false, addError: boolean = false ) => { - if (!indexPattern || !selectedNumericField) return; + if (!dataView || !selectedNumericField) return; // Construct the query portion of the search request - const query = data.query.getEsQuery(indexPattern); + const query = data.query.getEsQuery(dataView); if (addWarning) { query.bool.must.push({ @@ -151,7 +150,7 @@ export const SearchExamplesApp = ({ error_query: { indices: [ { - name: indexPattern.title, + name: dataView.title, error_type: 'warning', message: 'Watch out!', }, @@ -165,7 +164,7 @@ export const SearchExamplesApp = ({ error_query: { indices: [ { - name: indexPattern.title, + name: dataView.title, error_type: 'exception', message: 'Watch out!', }, @@ -176,11 +175,11 @@ export const SearchExamplesApp = ({ // Construct the aggregations portion of the search request by using the `data.search.aggs` service. const aggs = [{ type: 'avg', params: { field: selectedNumericField!.name } }]; - const aggsDsl = data.search.aggs.createAggConfigs(indexPattern, aggs).toDsl(); + const aggsDsl = data.search.aggs.createAggConfigs(dataView, aggs).toDsl(); const req = { params: { - index: indexPattern.title, + index: dataView.title, body: { aggs: aggsDsl, query, @@ -264,11 +263,11 @@ export const SearchExamplesApp = ({ }; const doSearchSourceSearch = async (otherBucket: boolean) => { - if (!indexPattern) return; + if (!dataView) return; const query = data.query.queryString.getQuery(); const filters = data.query.filterManager.getFilters(); - const timefilter = data.query.timefilter.timefilter.createFilter(indexPattern); + const timefilter = data.query.timefilter.timefilter.createFilter(dataView); if (timefilter) { filters.push(timefilter); } @@ -277,7 +276,7 @@ export const SearchExamplesApp = ({ const searchSource = await data.search.searchSource.create(); searchSource - .setField('index', indexPattern) + .setField('index', dataView) .setField('filter', filters) .setField('query', query) .setField('fields', selectedFields.length ? selectedFields.map((f) => f.name) : ['']) @@ -296,7 +295,7 @@ export const SearchExamplesApp = ({ aggDef.push({ type: 'avg', params: { field: selectedNumericField.name } }); } if (aggDef.length > 0) { - const ac = data.search.aggs.createAggConfigs(indexPattern, aggDef); + const ac = data.search.aggs.createAggConfigs(dataView, aggDef); searchSource.setField('aggs', ac); } @@ -407,14 +406,14 @@ export const SearchExamplesApp = ({ }; const onServerClickHandler = async () => { - if (!indexPattern || !selectedNumericField) return; + if (!dataView || !selectedNumericField) return; const abortController = new AbortController(); setAbortController(abortController); setIsLoading(true); try { const res = await http.get(SERVER_SEARCH_ROUTE_PATH, { query: { - index: indexPattern.title, + index: dataView.title, field: selectedNumericField!.name, }, signal: abortController.signal, @@ -510,22 +509,26 @@ export const SearchExamplesApp = ({ appName={PLUGIN_ID} showSearchBar={true} useDefaultBehaviors={true} - indexPatterns={indexPattern ? [indexPattern] : undefined} + indexPatterns={dataView ? [dataView] : undefined} /> - Index Pattern + Data view { - const newIndexPattern = await data.indexPatterns.get(newIndexPatternId); - setIndexPattern(newIndexPattern); + indexPatternId={dataView?.id || ''} + onChange={async (dataViewId?: string) => { + if (dataViewId) { + const newDataView = await data.dataViews.get(dataViewId); + setDataView(newDataView); + } else { + setDataView(undefined); + } }} isClearable={false} - data-test-subj="indexPatternSelector" + data-test-subj="dataViewSelector" /> @@ -536,7 +539,7 @@ export const SearchExamplesApp = ({ singleSelection={true} onChange={(option) => { if (option.length) { - const fld = indexPattern?.getFieldByName(option[0].label); + const fld = dataView?.getFieldByName(option[0].label); setSelectedBucketField(fld || null); } else { setSelectedBucketField(null); @@ -554,7 +557,7 @@ export const SearchExamplesApp = ({ singleSelection={true} onChange={(option) => { if (option.length) { - const fld = indexPattern?.getFieldByName(option[0].label); + const fld = dataView?.getFieldByName(option[0].label); setSelectedNumericField(fld || null); } else { setSelectedNumericField(null); @@ -572,9 +575,9 @@ export const SearchExamplesApp = ({ singleSelection={false} onChange={(option) => { const flds = option - .map((opt) => indexPattern?.getFieldByName(opt?.label)) + .map((opt) => dataView?.getFieldByName(opt?.label)) .filter((f) => f); - setSelectedFields(flds.length ? (flds as IndexPatternField[]) : []); + setSelectedFields(flds.length ? (flds as DataViewField[]) : []); }} sortMatchesBy="startsWith" /> @@ -590,9 +593,8 @@ export const SearchExamplesApp = ({ If you want to fetch data from Elasticsearch, you can use the different services - provided by the data plugin. These help you get the index pattern - and search bar configuration, format them into a DSL query and send it to - Elasticsearch. + provided by the data plugin. These help you get the data view and + search bar configuration, format them into a DSL query and send it to Elasticsearch. { - if (!indexPattern) return; + if (!dataView) return; if (!numericFieldName) return; setIsSearching(true); const requestId = ++nextRequestIdRef.current; - doSearch({ indexPattern, numericFieldName, restoreSearchSessionId }, { data, notifications }) + doSearch({ dataView, numericFieldName, restoreSearchSessionId }, { data, notifications }) .then(({ response: res, request: req, tookMs: _tookMs }) => { if (requestId !== nextRequestIdRef.current) return; // no longer interested in this result if (restoreSearchSessionId) { @@ -220,7 +219,7 @@ export const SearchSessionsExampleApp = ({ setIsSearching(false); }); }, - [data, notifications, indexPattern, numericFieldName] + [data, notifications, dataView, numericFieldName] ); useEffect(() => { @@ -243,9 +242,9 @@ export const SearchSessionsExampleApp = ({ )} - {!indexPattern && ( + {!dataView && ( <> - + )} @@ -280,26 +279,23 @@ export const SearchSessionsExampleApp = ({ appName={PLUGIN_ID} showSearchBar={true} useDefaultBehaviors={true} - indexPatterns={indexPattern ? [indexPattern] : undefined} + indexPatterns={dataView ? [dataView] : undefined} onQuerySubmit={reset} /> - Index Pattern + Data view { if (!id) return; - setIndexPattern(id); + setDataView(id); }} isClearable={false} - data-test-subj="indexPatternSelector" + data-test-subj="dataViewSelector" /> @@ -309,7 +305,7 @@ export const SearchSessionsExampleApp = ({ selectedOptions={formatFieldToComboBox(selectedField)} singleSelection={true} onChange={(option) => { - const fld = indexPattern?.getFieldByName(option[0].label); + const fld = dataView?.getFieldByName(option[0].label); if (!fld) return; setNumericFieldName(fld?.name); }} @@ -336,7 +332,7 @@ export const SearchSessionsExampleApp = ({ size="xs" onClick={() => search()} iconType="play" - disabled={isSearching || !indexPattern || !numericFieldName} + disabled={isSearching || !dataView || !numericFieldName} data-test-subj={'startSearch'} > Start the search from low-level client (data.search.search) @@ -540,7 +536,7 @@ function SearchInspector({ function useAppState({ data }: { data: DataPublicPluginStart }) { const stateContainer = useMemo(() => { - const { filters, time, searchSessionId, numericFieldName, indexPatternId, query } = + const { filters, time, searchSessionId, numericFieldName, dataViewId, query } = getInitialStateFromUrl(); if (filters) { @@ -558,7 +554,7 @@ function useAppState({ data }: { data: DataPublicPluginStart }) { return createStateContainer({ restoreSessionId: searchSessionId, numericFieldName, - indexPatternId, + dataViewId, }); }, [data.query.filterManager, data.query.queryString, data.query.timefilter.timefilter]); const setState = useCallback( @@ -575,78 +571,78 @@ function useAppState({ data }: { data: DataPublicPluginStart }) { }); }, [stateContainer, data.query]); - const [fields, setFields] = useState(); - const [indexPattern, setIndexPattern] = useState(); + const [fields, setFields] = useState(); + const [dataView, setDataView] = useState(); - // Fetch the default index pattern using the `data.indexPatterns` service, as the component is mounted. + // Fetch the default data view using the `data.dataViews` service, as the component is mounted. useEffect(() => { let canceled = false; - const loadIndexPattern = async () => { + const loadDataView = async () => { // eslint-disable-next-line no-console - console.warn('Loading default index pattern'); - let loadedIndexPattern = state.indexPatternId - ? await data.indexPatterns.get(state.indexPatternId) - : await data.indexPatterns.getDefault(); - if (!loadedIndexPattern) { - // try to find any available index pattern - const [id] = await data.indexPatterns.getIds(true); + console.warn('Loading default data view'); + let loadedDataView = state.dataViewId + ? await data.dataViews.get(state.dataViewId) + : await data.dataViews.getDefault(); + if (!loadedDataView) { + // try to find any available data view + const [id] = await data.dataViews.getIds(true); if (id) { - loadedIndexPattern = await data.indexPatterns.get(id); + loadedDataView = await data.dataViews.get(id); } } if (canceled) return; - if (!loadedIndexPattern) { + if (!loadedDataView) { // eslint-disable-next-line no-console - console.warn('No index patterns to pick from'); + console.warn('No data view to pick from'); return; } - if (!state.indexPatternId) { + if (!state.dataViewId) { setState({ - indexPatternId: loadedIndexPattern.id, + dataViewId: loadedDataView.id, }); } - setIndexPattern(loadedIndexPattern); + setDataView(loadedDataView); }; - loadIndexPattern(); + loadDataView(); return () => { canceled = true; }; - }, [data, setState, state.indexPatternId]); + }, [data, setState, state.dataViewId]); - // Update the fields list every time the index pattern is modified. + // Update the fields list every time the data view is modified. useEffect(() => { - setFields(indexPattern?.fields); - }, [indexPattern]); + setFields(dataView?.fields); + }, [dataView]); useEffect(() => { if (state.numericFieldName) return; setState({ numericFieldName: fields?.length ? getNumeric(fields)[0]?.name : undefined }); }, [setState, fields, state.numericFieldName]); - const selectedField: IndexPatternField | undefined = useMemo( - () => indexPattern?.fields.find((field) => field.name === state.numericFieldName), - [indexPattern?.fields, state.numericFieldName] + const selectedField: DataViewField | undefined = useMemo( + () => dataView?.fields.find((field) => field.name === state.numericFieldName), + [dataView?.fields, state.numericFieldName] ); return { selectedField, - indexPattern, + dataView, numericFieldName: state.numericFieldName, fields, setNumericFieldName: (field: string) => setState({ numericFieldName: field }), - setIndexPattern: (indexPatternId: string) => setState({ indexPatternId }), + setDataView: (dataViewId: string) => setState({ dataViewId }), state, }; } function doSearch( { - indexPattern, + dataView, numericFieldName, restoreSearchSessionId, }: { - indexPattern: IndexPattern; + dataView: DataView; numericFieldName: string; restoreSearchSessionId?: string; }, @@ -655,7 +651,7 @@ function doSearch( notifications, }: { data: DataPublicPluginStart; notifications: CoreStart['notifications'] } ): Promise<{ request: IEsSearchRequest; response: IEsSearchResponse; tookMs?: number }> { - if (!indexPattern) return Promise.reject('Select an index patten'); + if (!dataView) return Promise.reject('Select a data view'); if (!numericFieldName) return Promise.reject('Select a field to aggregate on'); // start a new session or restore an existing one @@ -668,7 +664,7 @@ function doSearch( const sessionId = restoreSearchSessionId ? restoreSearchSessionId : data.search.session.start(); // Construct the query portion of the search request - const query = data.query.getEsQuery(indexPattern, restoreTimeRange); + const query = data.query.getEsQuery(dataView, restoreTimeRange); // Construct the aggregations portion of the search request by using the `data.search.aggs` service. @@ -679,11 +675,11 @@ function doSearch( ] : [{ type: 'avg', params: { field: numericFieldName } }]; - const aggsDsl = data.search.aggs.createAggConfigs(indexPattern, aggs).toDsl(); + const aggsDsl = data.search.aggs.createAggConfigs(dataView, aggs).toDsl(); const req = { params: { - index: indexPattern.title, + index: dataView.title, body: { aggs: aggsDsl, query, @@ -728,17 +724,17 @@ function doSearch( .toPromise(); } -function getNumeric(fields?: IndexPatternField[]) { +function getNumeric(fields?: DataViewField[]) { if (!fields) return []; return fields?.filter((f) => f.type === 'number' && f.aggregatable); } -function formatFieldToComboBox(field?: IndexPatternField | null) { +function formatFieldToComboBox(field?: DataViewField | null) { if (!field) return []; return formatFieldsToComboBox([field]); } -function formatFieldsToComboBox(fields?: IndexPatternField[]) { +function formatFieldsToComboBox(fields?: DataViewField[]) { if (!fields) return []; return fields?.map((field) => { @@ -781,10 +777,10 @@ function NoShardDelayCallout() { ); } -function NoIndexPatternsCallout() { +function NoDataViewsCallout() { return ( - Missing index patterns!} color="warning" iconType="help"> -

This demo requires at least one index pattern.

+ Missing data views!} color="warning" iconType="help"> +

This demo requires at least one data view.

); } diff --git a/examples/search_examples/public/search_sessions/app_locator.ts b/examples/search_examples/public/search_sessions/app_locator.ts index 1cbd27887c1c3..f7e59ece3be5d 100644 --- a/examples/search_examples/public/search_sessions/app_locator.ts +++ b/examples/search_examples/public/search_sessions/app_locator.ts @@ -7,7 +7,8 @@ */ import { SerializableRecord } from '@kbn/utility-types'; -import { esFilters, Filter, Query, TimeRange } from '../../../../src/plugins/data/public'; +import { Filter, Query, isFilterPinned } from '@kbn/es-query'; +import type { TimeRange } from '../../../../src/plugins/data/public'; import { getStatesFromKbnUrl, setStateToKbnUrl } from '../../../../src/plugins/kibana_utils/public'; import { LocatorDefinition } from '../../../../src/plugins/share/common'; @@ -19,7 +20,7 @@ export const SEARCH_SESSIONS_EXAMPLES_APP_LOCATOR = 'SEARCH_SESSIONS_EXAMPLES_AP export interface AppUrlState extends SerializableRecord { filters?: Filter[]; query?: Query; - indexPatternId?: string; + dataViewId?: string; numericFieldName?: string; searchSessionId?: string; } @@ -46,8 +47,8 @@ export class SearchSessionsExamplesAppLocatorDefinition STATE_STORAGE_KEY, { query: params.query, - filters: params.filters?.filter((f) => !esFilters.isFilterPinned(f)), - indexPatternId: params.indexPatternId, + filters: params.filters?.filter((f) => !isFilterPinned(f)), + dataViewId: params.dataViewId, numericFieldName: params.numericFieldName, searchSessionId: params.searchSessionId, } as AppUrlState, @@ -59,7 +60,7 @@ export class SearchSessionsExamplesAppLocatorDefinition GLOBAL_STATE_STORAGE_KEY, { time: params.time, - filters: params.filters?.filter((f) => esFilters.isFilterPinned(f)), + filters: params.filters?.filter((f) => isFilterPinned(f)), } as GlobalUrlState, { useHash: false, storeInHashQuery: false }, url @@ -75,7 +76,7 @@ export class SearchSessionsExamplesAppLocatorDefinition export function getInitialStateFromUrl(): SearchSessionsExamplesAppLocatorParams { const { - _a: { numericFieldName, indexPatternId, searchSessionId, filters: aFilters, query } = {}, + _a: { numericFieldName, dataViewId, searchSessionId, filters: aFilters, query } = {}, _g: { filters: gFilters, time } = {}, } = getStatesFromKbnUrl<{ _a: AppUrlState; _g: GlobalUrlState }>( window.location.href, @@ -90,7 +91,7 @@ export function getInitialStateFromUrl(): SearchSessionsExamplesAppLocatorParams searchSessionId, time, filters: [...(gFilters ?? []), ...(aFilters ?? [])], - indexPatternId, + dataViewId, query, }; } diff --git a/examples/search_examples/tsconfig.json b/examples/search_examples/tsconfig.json index 547952b8dd3d8..9c0fad34ef9c0 100644 --- a/examples/search_examples/tsconfig.json +++ b/examples/search_examples/tsconfig.json @@ -15,6 +15,7 @@ "references": [ { "path": "../../src/core/tsconfig.json" }, { "path": "../../src/plugins/data/tsconfig.json" }, + { "path": "../../src/plugins/data_views/tsconfig.json" }, { "path": "../../src/plugins/kibana_utils/tsconfig.json" }, { "path": "../../src/plugins/kibana_react/tsconfig.json" }, { "path": "../../src/plugins/navigation/tsconfig.json" }, diff --git a/examples/state_containers_examples/public/with_data_services/app.tsx b/examples/state_containers_examples/public/with_data_services/app.tsx index a26b28f3cf9f3..881bc07017966 100644 --- a/examples/state_containers_examples/public/with_data_services/app.tsx +++ b/examples/state_containers_examples/public/with_data_services/app.tsx @@ -18,19 +18,18 @@ import { EuiText, EuiTitle, } from '@elastic/eui'; +import { Filter, FilterStateStore } from '@kbn/es-query'; import { CoreStart } from 'kibana/public'; import { NavigationPublicPluginStart } from '../../../../src/plugins/navigation/public'; import { connectToQueryState, DataPublicPluginStart, - esFilters, - Filter, - IndexPattern, Query, QueryState, syncQueryStateWithUrl, } from '../../../../src/plugins/data/public'; +import type { DataView } from '../../../../src/plugins/data_views/public'; import { BaseStateContainer, createStateContainer, @@ -73,13 +72,9 @@ export const App = ({ useGlobalStateSyncing(data.query, kbnUrlStateStorage); useAppStateSyncing(appStateContainer, data.query, kbnUrlStateStorage); - const indexPattern = useIndexPattern(data); - if (!indexPattern) - return ( -
- No index pattern found. Please create an index pattern before trying this example... -
- ); + const dataView = useDataView(data); + if (!dataView) + return
No data view found. Please create a data view before trying this example...
; // Note that `navigation.ui.TopNavMenu` is a stateful component exported on the `navigation` plugin's start contract. return ( @@ -102,7 +97,7 @@ export const App = ({ @@ -126,19 +121,19 @@ export const App = ({ ); }; -function useIndexPattern(data: DataPublicPluginStart) { - const [indexPattern, setIndexPattern] = useState(); +function useDataView(data: DataPublicPluginStart) { + const [dataView, setDataView] = useState(); useEffect(() => { - const fetchIndexPattern = async () => { - const defaultIndexPattern = await data.indexPatterns.getDefault(); - if (defaultIndexPattern) { - setIndexPattern(defaultIndexPattern); + const fetchDataView = async () => { + const defaultDataView = await data.dataViews.getDefault(); + if (defaultDataView) { + setDataView(defaultDataView); } }; - fetchIndexPattern(); - }, [data.indexPatterns]); + fetchDataView(); + }, [data.dataViews]); - return indexPattern; + return dataView; } function useGlobalStateSyncing( @@ -167,7 +162,7 @@ function useAppStateSyncing( const stopSyncingQueryAppStateWithStateContainer = connectToQueryState( query, appStateContainer, - { filters: esFilters.FilterStateStore.APP_STATE, query: true } + { filters: FilterStateStore.APP_STATE, query: true } ); // sets up syncing app state container with url diff --git a/examples/state_containers_examples/tsconfig.json b/examples/state_containers_examples/tsconfig.json index fc266cbe2c83f..40b66f9fc9c7b 100644 --- a/examples/state_containers_examples/tsconfig.json +++ b/examples/state_containers_examples/tsconfig.json @@ -18,6 +18,7 @@ { "path": "../../src/plugins/kibana_react/tsconfig.json" }, { "path": "../../src/plugins/navigation/tsconfig.json" }, { "path": "../../src/plugins/data/tsconfig.json" }, + { "path": "../../src/plugins/data_views/tsconfig.json" }, { "path": "../developer_examples/tsconfig.json" }, ] } diff --git a/package.json b/package.json index 0193797ac82b0..f2a40b4ae564e 100644 --- a/package.json +++ b/package.json @@ -103,11 +103,11 @@ "@elastic/apm-rum": "^5.10.0", "@elastic/apm-rum-react": "^1.3.2", "@elastic/apm-synthtrace": "link:bazel-bin/packages/elastic-apm-synthtrace", - "@elastic/charts": "40.1.0", + "@elastic/charts": "40.2.0", "@elastic/datemath": "link:bazel-bin/packages/elastic-datemath", "@elastic/elasticsearch": "npm:@elastic/elasticsearch-canary@^8.0.0-canary.35", "@elastic/ems-client": "8.0.0", - "@elastic/eui": "41.2.3", + "@elastic/eui": "43.1.1", "@elastic/filesaver": "1.1.2", "@elastic/node-crypto": "1.2.1", "@elastic/numeral": "^2.5.1", @@ -189,6 +189,7 @@ "@turf/helpers": "6.0.1", "@turf/length": "^6.0.2", "@types/jsonwebtoken": "^8.5.6", + "@types/moment-duration-format": "^2.2.3", "JSONStream": "1.3.5", "abort-controller": "^3.0.0", "antlr4ts": "^0.5.0-alpha.3", @@ -197,7 +198,7 @@ "base64-js": "^1.3.1", "bitmap-sdf": "^1.0.3", "brace": "0.11.1", - "broadcast-channel": "^4.7.1", + "broadcast-channel": "^4.8.0", "canvg": "^3.0.9", "chalk": "^4.1.0", "cheerio": "^1.0.0-rc.10", @@ -211,7 +212,7 @@ "constate": "^1.3.2", "content-disposition": "0.5.3", "copy-to-clipboard": "^3.0.8", - "core-js": "^3.19.1", + "core-js": "^3.19.3", "cronstrue": "^1.51.0", "cytoscape": "^3.10.0", "cytoscape-dagre": "^2.2.2", @@ -575,6 +576,24 @@ "@types/kbn__i18n": "link:bazel-bin/packages/kbn-i18n/npm_module_types", "@types/kbn__i18n-react": "link:bazel-bin/packages/kbn-i18n-react/npm_module_types", "@types/kbn__mapbox-gl": "link:bazel-bin/packages/kbn-mapbox-gl/npm_module_types", + "@types/kbn__monaco": "link:bazel-bin/packages/kbn-monaco/npm_module_types", + "@types/kbn__optimizer": "link:bazel-bin/packages/kbn-optimizer/npm_module_types", + "@types/kbn__plugin-generator": "link:bazel-bin/packages/kbn-plugin-generator/npm_module_types", + "@types/kbn__plugin-helpers": "link:bazel-bin/packages/kbn-plugin-helpers/npm_module_types", + "@types/kbn__react-field": "link:bazel-bin/packages/kbn-react-field/npm_module_types", + "@types/kbn__rule-data-utils": "link:bazel-bin/packages/kbn-rule-data-utils/npm_module_types", + "@types/kbn__securitysolution-autocomplete": "link:bazel-bin/packages/kbn-securitysolution-autocomplete/npm_module_types", + "@types/kbn__securitysolution-es-utils": "link:bazel-bin/packages/kbn-securitysolution-es-utils/npm_module_types", + "@types/kbn__securitysolution-hook-utils": "link:bazel-bin/packages/kbn-securitysolution-hook-utils/npm_module_types", + "@types/kbn__securitysolution-io-ts-alerting-types": "link:bazel-bin/packages/kbn-securitysolution-io-ts-alerting-types/npm_module_types", + "@types/kbn__securitysolution-io-ts-list-types": "link:bazel-bin/packages/kbn-securitysolution-io-ts-list-types/npm_module_types", + "@types/kbn__securitysolution-io-ts-types": "link:bazel-bin/packages/kbn-securitysolution-io-ts-types/npm_module_types", + "@types/kbn__securitysolution-list-api": "link:bazel-bin/packages/kbn-securitysolution-list-api/npm_module_types", + "@types/kbn__securitysolution-list-constants": "link:bazel-bin/packages/kbn-securitysolution-list-constants/npm_module_types", + "@types/kbn__securitysolution-list-hooks": "link:bazel-bin/packages/kbn-securitysolution-list-hooks/npm_module_types", + "@types/kbn__securitysolution-rules": "link:bazel-bin/packages/kbn-securitysolution-rules/npm_module_types", + "@types/kbn__securitysolution-t-grid": "link:bazel-bin/packages/kbn-securitysolution-t-grid/npm_module_types", + "@types/kbn__securitysolution-utils": "link:bazel-bin/packages/kbn-securitysolution-utils/npm_module_types", "@types/license-checker": "15.0.0", "@types/listr": "^0.14.0", "@types/loader-utils": "^1.1.3", @@ -631,7 +650,7 @@ "@types/redux-actions": "^2.6.1", "@types/redux-logger": "^3.0.8", "@types/seedrandom": ">=2.0.0 <4.0.0", - "@types/selenium-webdriver": "^4.0.15", + "@types/selenium-webdriver": "^4.0.16", "@types/semver": "^7", "@types/set-value": "^2.0.0", "@types/sinon": "^7.0.13", @@ -789,7 +808,7 @@ "mochawesome-merge": "^4.2.0", "mock-fs": "^5.1.2", "mock-http-server": "1.3.0", - "ms-chromium-edge-driver": "^0.4.2", + "ms-chromium-edge-driver": "^0.4.3", "multimatch": "^4.0.0", "mutation-observer": "^1.0.3", "ncp": "^2.0.0", @@ -814,7 +833,7 @@ "rxjs-marbles": "^5.0.6", "sass-loader": "^10.2.0", "sass-resources-loader": "^2.0.1", - "selenium-webdriver": "^4.0.0", + "selenium-webdriver": "^4.1.0", "serve-static": "1.14.1", "shelljs": "^0.8.4", "simple-git": "1.116.0", diff --git a/packages/BUILD.bazel b/packages/BUILD.bazel index 8990bce70145a..dfe7768e2ad15 100644 --- a/packages/BUILD.bazel +++ b/packages/BUILD.bazel @@ -94,6 +94,24 @@ filegroup( "//packages/kbn-i18n:build_types", "//packages/kbn-i18n-react:build_types", "//packages/kbn-mapbox-gl:build_types", + "//packages/kbn-monaco:build_types", + "//packages/kbn-optimizer:build_types", + "//packages/kbn-plugin-generator:build_types", + "//packages/kbn-plugin-helpers:build_types", + "//packages/kbn-react-field:build_types", + "//packages/kbn-rule-data-utils:build_types", + "//packages/kbn-securitysolution-autocomplete:build_types", + "//packages/kbn-securitysolution-es-utils:build_types", + "//packages/kbn-securitysolution-hook-utils:build_types", + "//packages/kbn-securitysolution-io-ts-alerting-types:build_types", + "//packages/kbn-securitysolution-io-ts-list-types:build_types", + "//packages/kbn-securitysolution-io-ts-types:build_types", + "//packages/kbn-securitysolution-list-api:build_types", + "//packages/kbn-securitysolution-list-constants:build_types", + "//packages/kbn-securitysolution-list-hooks:build_types", + "//packages/kbn-securitysolution-rules:build_types", + "//packages/kbn-securitysolution-t-grid:build_types", + "//packages/kbn-securitysolution-utils:build_types", ], ) diff --git a/packages/elastic-eslint-config-kibana/.eslintrc.js b/packages/elastic-eslint-config-kibana/.eslintrc.js index dc95601fadd1a..fe6ea54bbde05 100644 --- a/packages/elastic-eslint-config-kibana/.eslintrc.js +++ b/packages/elastic-eslint-config-kibana/.eslintrc.js @@ -91,8 +91,6 @@ module.exports = { ...[ '@elastic/eui/dist/eui_theme_light.json', '@elastic/eui/dist/eui_theme_dark.json', - '@elastic/eui/dist/eui_theme_amsterdam_light.json', - '@elastic/eui/dist/eui_theme_amsterdam_dark.json', ].map(from => ({ from, to: false, diff --git a/packages/kbn-cli-dev-mode/BUILD.bazel b/packages/kbn-cli-dev-mode/BUILD.bazel index cdc40e85c972a..22a8137a782a6 100644 --- a/packages/kbn-cli-dev-mode/BUILD.bazel +++ b/packages/kbn-cli-dev-mode/BUILD.bazel @@ -52,7 +52,7 @@ TYPES_DEPS = [ "//packages/kbn-config-schema:npm_module_types", "//packages/kbn-dev-utils:npm_module_types", "//packages/kbn-logging", - "//packages/kbn-optimizer", + "//packages/kbn-optimizer:npm_module_types", "//packages/kbn-server-http-tools", "//packages/kbn-std", "//packages/kbn-utils", diff --git a/packages/kbn-es/src/artifact.test.js b/packages/kbn-es/src/artifact.test.js index 884804ed75a65..8888c8ca2f989 100644 --- a/packages/kbn-es/src/artifact.test.js +++ b/packages/kbn-es/src/artifact.test.js @@ -69,6 +69,18 @@ beforeEach(() => { valid: { archives: [createArchive({ license: 'oss' }), createArchive({ license: 'default' })], }, + invalidArch: { + archives: [ + createArchive({ license: 'oss', architecture: 'invalid_arch' }), + createArchive({ license: 'default', architecture: 'invalid_arch' }), + ], + }, + differentVersion: { + archives: [ + createArchive({ license: 'oss', version: 'another-version' }), + createArchive({ license: 'default', version: 'another-version' }), + ], + }, multipleArch: { archives: [ createArchive({ architecture: 'fake_arch', license: 'oss' }), @@ -116,8 +128,14 @@ describe('Artifact', () => { artifactTest('INVALID_LICENSE', 'default') ); + it('should return an artifact even if the version does not match', async () => { + mockFetch(MOCKS.differentVersion); + artifactTest('default', 'default'); + }); + it('should throw when an artifact cannot be found in the manifest for the specified parameters', async () => { - await expect(Artifact.getSnapshot('default', 'INVALID_VERSION', log)).rejects.toThrow( + mockFetch(MOCKS.invalidArch); + await expect(Artifact.getSnapshot('default', MOCK_VERSION, log)).rejects.toThrow( "couldn't find an artifact" ); }); @@ -144,8 +162,14 @@ describe('Artifact', () => { artifactTest('INVALID_LICENSE', 'default', 2) ); + it('should return an artifact even if the version does not match', async () => { + mockFetch(MOCKS.differentVersion); + artifactTest('default', 'default', 2); + }); + it('should throw when an artifact cannot be found in the manifest for the specified parameters', async () => { - await expect(Artifact.getSnapshot('default', 'INVALID_VERSION', log)).rejects.toThrow( + mockFetch(MOCKS.invalidArch); + await expect(Artifact.getSnapshot('default', MOCK_VERSION, log)).rejects.toThrow( "couldn't find an artifact" ); }); diff --git a/packages/kbn-es/src/artifact.ts b/packages/kbn-es/src/artifact.ts index 9c5935c96e8cd..9ec3b96801dda 100644 --- a/packages/kbn-es/src/artifact.ts +++ b/packages/kbn-es/src/artifact.ts @@ -156,16 +156,18 @@ async function getArtifactSpecForSnapshot( const arch = process.arch === 'arm64' ? 'aarch64' : 'x86_64'; const archive = manifest.archives.find( - (a) => - a.version === desiredVersion && - a.platform === platform && - a.license === desiredLicense && - a.architecture === arch + (a) => a.platform === platform && a.license === desiredLicense && a.architecture === arch ); if (!archive) { throw createCliError( - `Snapshots for ${desiredVersion} are available, but couldn't find an artifact in the manifest for [${desiredVersion}, ${desiredLicense}, ${platform}]` + `Snapshots are available, but couldn't find an artifact in the manifest for [${desiredLicense}, ${platform}, ${arch}]` + ); + } + + if (archive.version !== desiredVersion) { + log.warning( + `Snapshot found, but version does not match Kibana. Kibana: ${desiredVersion}, Snapshot: ${archive.version}` ); } diff --git a/packages/kbn-monaco/BUILD.bazel b/packages/kbn-monaco/BUILD.bazel index 4813f9dd2dc88..c72c46f8ed202 100644 --- a/packages/kbn-monaco/BUILD.bazel +++ b/packages/kbn-monaco/BUILD.bazel @@ -1,10 +1,11 @@ -load("@npm//@bazel/typescript:index.bzl", "ts_config", "ts_project") -load("@build_bazel_rules_nodejs//:index.bzl", "js_library", "pkg_npm") +load("@npm//@bazel/typescript:index.bzl", "ts_config") load("@npm//webpack-cli:index.bzl", webpack = "webpack_cli") -load("//src/dev/bazel:index.bzl", "jsts_transpiler") +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 = "kbn-monaco" PKG_REQUIRE_NAME = "@kbn/monaco" +TYPES_PKG_REQUIRE_NAME = "@types/kbn__monaco" SOURCE_FILES = glob( [ @@ -106,7 +107,7 @@ ts_project( js_library( name = PKG_BASE_NAME, srcs = NPM_MODULE_EXTRA_FILES, - deps = RUNTIME_DEPS + [":target_node", ":target_web", ":target_workers", ":tsc_types"], + deps = RUNTIME_DEPS + [":target_node", ":target_web", ":target_workers"], package_name = PKG_REQUIRE_NAME, visibility = ["//visibility:public"], ) @@ -125,3 +126,20 @@ filegroup( ], visibility = ["//visibility:public"], ) + +pkg_npm_types( + name = "npm_module_types", + srcs = SRCS, + deps = [":tsc_types"], + package_name = TYPES_PKG_REQUIRE_NAME, + tsconfig = ":tsconfig", + visibility = ["//visibility:public"], +) + +filegroup( + name = "build_types", + srcs = [ + ":npm_module_types", + ], + visibility = ["//visibility:public"], +) diff --git a/packages/kbn-monaco/package.json b/packages/kbn-monaco/package.json index ff2f67ec2647c..7761c5a923fdc 100644 --- a/packages/kbn-monaco/package.json +++ b/packages/kbn-monaco/package.json @@ -4,7 +4,6 @@ "private": true, "browser": "target_web/index.js", "main": "target_node/index.js", - "types": "target_types/index.d.ts", "license": "SSPL-1.0 OR Elastic License 2.0", "scripts": { "build:antlr4ts": "../../node_modules/antlr4ts-cli/antlr4ts ./src/painless/antlr/painless_lexer.g4 ./src/painless/antlr/painless_parser.g4 && node ./scripts/fix_generated_antlr.js" diff --git a/packages/kbn-optimizer/BUILD.bazel b/packages/kbn-optimizer/BUILD.bazel index 3bd41249e2d51..4dc5a8676c078 100644 --- a/packages/kbn-optimizer/BUILD.bazel +++ b/packages/kbn-optimizer/BUILD.bazel @@ -1,9 +1,10 @@ -load("@npm//@bazel/typescript:index.bzl", "ts_config", "ts_project") -load("@build_bazel_rules_nodejs//:index.bzl", "js_library", "pkg_npm") -load("//src/dev/bazel:index.bzl", "jsts_transpiler") +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 = "kbn-optimizer" PKG_REQUIRE_NAME = "@kbn/optimizer" +TYPES_PKG_REQUIRE_NAME = "@types/kbn__optimizer" SOURCE_FILES = glob( [ @@ -129,7 +130,7 @@ ts_project( js_library( name = PKG_BASE_NAME, srcs = NPM_MODULE_EXTRA_FILES, - deps = RUNTIME_DEPS + [":target_node", ":tsc_types"], + deps = RUNTIME_DEPS + [":target_node"], package_name = PKG_REQUIRE_NAME, visibility = ["//visibility:public"], ) @@ -148,3 +149,20 @@ filegroup( ], visibility = ["//visibility:public"], ) + +pkg_npm_types( + name = "npm_module_types", + srcs = SRCS, + deps = [":tsc_types"], + package_name = TYPES_PKG_REQUIRE_NAME, + tsconfig = ":tsconfig", + visibility = ["//visibility:public"], +) + +filegroup( + name = "build_types", + srcs = [ + ":npm_module_types", + ], + visibility = ["//visibility:public"], +) diff --git a/packages/kbn-optimizer/package.json b/packages/kbn-optimizer/package.json index 488e1b5dbfde8..a7d8a50927634 100644 --- a/packages/kbn-optimizer/package.json +++ b/packages/kbn-optimizer/package.json @@ -3,6 +3,5 @@ "version": "1.0.0", "private": true, "license": "SSPL-1.0 OR Elastic License 2.0", - "main": "./target_node/index.js", - "types": "./target_types/index.d.ts" + "main": "./target_node/index.js" } \ No newline at end of file diff --git a/packages/kbn-plugin-generator/BUILD.bazel b/packages/kbn-plugin-generator/BUILD.bazel index 488f09bdd5d52..3fef9531b57a1 100644 --- a/packages/kbn-plugin-generator/BUILD.bazel +++ b/packages/kbn-plugin-generator/BUILD.bazel @@ -1,9 +1,10 @@ -load("@npm//@bazel/typescript:index.bzl", "ts_config", "ts_project") -load("@build_bazel_rules_nodejs//:index.bzl", "js_library", "pkg_npm") -load("//src/dev/bazel:index.bzl", "jsts_transpiler") +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 = "kbn-plugin-generator" PKG_REQUIRE_NAME = "@kbn/plugin-generator" +TYPES_PKG_REQUIRE_NAME = "@types/kbn__plugin-generator" SOURCE_FILES = glob( [ @@ -96,7 +97,7 @@ ts_project( js_library( name = PKG_BASE_NAME, srcs = NPM_MODULE_EXTRA_FILES, - deps = RUNTIME_DEPS + [":target_node", ":tsc_types"], + deps = RUNTIME_DEPS + [":target_node"], package_name = PKG_REQUIRE_NAME, visibility = ["//visibility:public"], ) @@ -115,3 +116,20 @@ filegroup( ], visibility = ["//visibility:public"], ) + +pkg_npm_types( + name = "npm_module_types", + srcs = SRCS, + deps = [":tsc_types"], + package_name = TYPES_PKG_REQUIRE_NAME, + tsconfig = ":tsconfig", + visibility = ["//visibility:public"], +) + +filegroup( + name = "build_types", + srcs = [ + ":npm_module_types", + ], + visibility = ["//visibility:public"], +) diff --git a/packages/kbn-plugin-generator/package.json b/packages/kbn-plugin-generator/package.json index d30f25e478dcf..28b7e849ab3c1 100644 --- a/packages/kbn-plugin-generator/package.json +++ b/packages/kbn-plugin-generator/package.json @@ -3,6 +3,5 @@ "version": "1.0.0", "private": true, "license": "SSPL-1.0 OR Elastic License 2.0", - "main": "target_node/index.js", - "types": "target_types/index.d.ts" + "main": "target_node/index.js" } \ No newline at end of file diff --git a/packages/kbn-plugin-helpers/BUILD.bazel b/packages/kbn-plugin-helpers/BUILD.bazel index 47f205f1530b7..eeb5d06a3866a 100644 --- a/packages/kbn-plugin-helpers/BUILD.bazel +++ b/packages/kbn-plugin-helpers/BUILD.bazel @@ -1,10 +1,11 @@ -load("@npm//@bazel/typescript:index.bzl", "ts_config", "ts_project") -load("@build_bazel_rules_nodejs//:index.bzl", "js_library", "pkg_npm") -load("//src/dev/bazel:index.bzl", "jsts_transpiler") +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 = "kbn-plugin-helpers" PKG_REQUIRE_NAME = "@kbn/plugin-helpers" +TYPES_PKG_REQUIRE_NAME = "@types/kbn__plugin-helpers" SOURCE_FILES = glob( [ @@ -43,7 +44,7 @@ RUNTIME_DEPS = [ TYPES_DEPS = [ "//packages/kbn-dev-utils:npm_module_types", - "//packages/kbn-optimizer", + "//packages/kbn-optimizer:npm_module_types", "//packages/kbn-utils", "@npm//del", "@npm//execa", @@ -89,7 +90,7 @@ ts_project( js_library( name = PKG_BASE_NAME, srcs = NPM_MODULE_EXTRA_FILES, - deps = RUNTIME_DEPS + [":target_node", ":tsc_types"], + deps = RUNTIME_DEPS + [":target_node"], package_name = PKG_REQUIRE_NAME, visibility = ["//visibility:public"], ) @@ -108,3 +109,20 @@ filegroup( ], visibility = ["//visibility:public"], ) + +pkg_npm_types( + name = "npm_module_types", + srcs = SRCS, + deps = [":tsc_types"], + package_name = TYPES_PKG_REQUIRE_NAME, + tsconfig = ":tsconfig", + visibility = ["//visibility:public"], +) + +filegroup( + name = "build_types", + srcs = [ + ":npm_module_types", + ], + visibility = ["//visibility:public"], +) diff --git a/packages/kbn-plugin-helpers/package.json b/packages/kbn-plugin-helpers/package.json index 21ed8f46f52fa..cac041762f739 100644 --- a/packages/kbn-plugin-helpers/package.json +++ b/packages/kbn-plugin-helpers/package.json @@ -8,7 +8,6 @@ "devOnly": true }, "main": "target_node/index.js", - "types": "target_types/index.d.ts", "bin": { "plugin-helpers": "bin/plugin-helpers.js" } diff --git a/packages/kbn-react-field/BUILD.bazel b/packages/kbn-react-field/BUILD.bazel index 5165ca2fc90fc..36ab9d7f38c56 100644 --- a/packages/kbn-react-field/BUILD.bazel +++ b/packages/kbn-react-field/BUILD.bazel @@ -1,9 +1,10 @@ -load("@npm//@bazel/typescript:index.bzl", "ts_config", "ts_project") -load("@build_bazel_rules_nodejs//:index.bzl", "js_library", "pkg_npm") -load("//src/dev/bazel:index.bzl", "jsts_transpiler") +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 = "kbn-react-field" PKG_REQUIRE_NAME = "@kbn/react-field" +TYPES_PKG_REQUIRE_NAME = "@types/kbn__react-field" SOURCE_FILES = glob( [ @@ -29,26 +30,22 @@ filegroup( NPM_MODULE_EXTRA_FILES = [ "package.json", "README.md", - "field_button/package.json", - "field_icon/package.json", ] RUNTIME_DEPS = [ + "@npm//@elastic/eui", + "@npm//classnames", "@npm//prop-types", "@npm//react", - "@npm//classnames", - "@npm//@elastic/eui", - "//packages/kbn-i18n", ] TYPES_DEPS = [ - "//packages/kbn-i18n", "@npm//tslib", + "@npm//@elastic/eui", + "@npm//@types/classnames", "@npm//@types/jest", "@npm//@types/prop-types", - "@npm//@types/classnames", "@npm//@types/react", - "@npm//@elastic/eui", ] jsts_transpiler( @@ -98,7 +95,7 @@ ts_project( js_library( name = PKG_BASE_NAME, srcs = NPM_MODULE_EXTRA_FILES, - deps = RUNTIME_DEPS + [":target_node", ":target_webpack", ":tsc_types"], + deps = RUNTIME_DEPS + [":target_node", ":target_webpack"], package_name = PKG_REQUIRE_NAME, visibility = ["//visibility:public"], ) @@ -117,3 +114,20 @@ filegroup( ], visibility = ["//visibility:public"], ) + +pkg_npm_types( + name = "npm_module_types", + srcs = SRCS, + deps = [":tsc_types"], + package_name = TYPES_PKG_REQUIRE_NAME, + tsconfig = ":tsconfig", + visibility = ["//visibility:public"], +) + +filegroup( + name = "build_types", + srcs = [ + ":npm_module_types", + ], + visibility = ["//visibility:public"], +) diff --git a/packages/kbn-react-field/field_button/package.json b/packages/kbn-react-field/field_button/package.json deleted file mode 100644 index dd708dd5cd32d..0000000000000 --- a/packages/kbn-react-field/field_button/package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "main": "../target_node/field_button/index.js", - "browser": "../target_webpack/field_button/index.js", - "types": "../target_types/field_button/index.d.ts" -} \ No newline at end of file diff --git a/packages/kbn-react-field/field_icon/package.json b/packages/kbn-react-field/field_icon/package.json deleted file mode 100644 index e7220f60e5d29..0000000000000 --- a/packages/kbn-react-field/field_icon/package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "main": "../target_node/field_icon/index.js", - "browser": "../target_webpack/field_icon/index.js", - "types": "../target_types/field_icon/index.d.ts" -} \ No newline at end of file diff --git a/packages/kbn-react-field/package.json b/packages/kbn-react-field/package.json index 3cbfdfa010ba0..832284b06ccfe 100644 --- a/packages/kbn-react-field/package.json +++ b/packages/kbn-react-field/package.json @@ -2,7 +2,6 @@ "name": "@kbn/react-field", "main": "./target_node/index.js", "browser": "./target_webpack/index.js", - "types": "./target_types/index.d.ts", "version": "1.0.0", "license": "SSPL-1.0 OR Elastic License 2.0", "private": true diff --git a/packages/kbn-rule-data-utils/BUILD.bazel b/packages/kbn-rule-data-utils/BUILD.bazel index d23cf25f181ca..1e71947566722 100644 --- a/packages/kbn-rule-data-utils/BUILD.bazel +++ b/packages/kbn-rule-data-utils/BUILD.bazel @@ -1,9 +1,10 @@ -load("@npm//@bazel/typescript:index.bzl", "ts_config", "ts_project") -load("@build_bazel_rules_nodejs//:index.bzl", "js_library", "pkg_npm") -load("//src/dev/bazel:index.bzl", "jsts_transpiler") +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 = "kbn-rule-data-utils" PKG_REQUIRE_NAME = "@kbn/rule-data-utils" +TYPES_PKG_REQUIRE_NAME = "@types/kbn__rule-data-utils" SOURCE_FILES = glob( [ @@ -20,10 +21,6 @@ filegroup( NPM_MODULE_EXTRA_FILES = [ "package.json", - "alerts_as_data_rbac/package.json", - "alerts_as_data_severity/package.json", - "alerts_as_data_status/package.json", - "technical_field_names/package.json", ] RUNTIME_DEPS = [ @@ -75,7 +72,7 @@ ts_project( js_library( name = PKG_BASE_NAME, srcs = NPM_MODULE_EXTRA_FILES, - deps = RUNTIME_DEPS + [":target_node", ":tsc_types"], + deps = RUNTIME_DEPS + [":target_node"], package_name = PKG_REQUIRE_NAME, visibility = ["//visibility:public"], ) @@ -94,3 +91,20 @@ filegroup( ], visibility = ["//visibility:public"], ) + +pkg_npm_types( + name = "npm_module_types", + srcs = SRCS, + deps = [":tsc_types"], + package_name = TYPES_PKG_REQUIRE_NAME, + tsconfig = ":tsconfig", + visibility = ["//visibility:public"], +) + +filegroup( + name = "build_types", + srcs = [ + ":npm_module_types", + ], + visibility = ["//visibility:public"], +) diff --git a/packages/kbn-rule-data-utils/alerts_as_data_rbac/package.json b/packages/kbn-rule-data-utils/alerts_as_data_rbac/package.json deleted file mode 100644 index 7f06391bc9590..0000000000000 --- a/packages/kbn-rule-data-utils/alerts_as_data_rbac/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "main": "../target_node/alerts_as_data_rbac", - "types": "../target_types/alerts_as_data_rbac" -} \ No newline at end of file diff --git a/packages/kbn-rule-data-utils/alerts_as_data_severity/package.json b/packages/kbn-rule-data-utils/alerts_as_data_severity/package.json deleted file mode 100644 index b053fc29e47c2..0000000000000 --- a/packages/kbn-rule-data-utils/alerts_as_data_severity/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "main": "../target_node/alerts_as_data_severity", - "types": "../target_types/alerts_as_data_severity" -} \ No newline at end of file diff --git a/packages/kbn-rule-data-utils/alerts_as_data_status/package.json b/packages/kbn-rule-data-utils/alerts_as_data_status/package.json deleted file mode 100644 index 4f621d252a2dc..0000000000000 --- a/packages/kbn-rule-data-utils/alerts_as_data_status/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "main": "../target_node/alerts_as_data_status", - "types": "../target_types/alerts_as_data_status" -} \ No newline at end of file diff --git a/packages/kbn-rule-data-utils/package.json b/packages/kbn-rule-data-utils/package.json index 64bbb69d14403..9372d7e70a8d1 100644 --- a/packages/kbn-rule-data-utils/package.json +++ b/packages/kbn-rule-data-utils/package.json @@ -1,7 +1,6 @@ { "name": "@kbn/rule-data-utils", "main": "./target_node/index.js", - "types": "./target_types/index.d.ts", "version": "1.0.0", "license": "SSPL-1.0 OR Elastic License 2.0", "private": true diff --git a/packages/kbn-rule-data-utils/src/technical_field_names.ts b/packages/kbn-rule-data-utils/src/technical_field_names.ts index db9fded8db917..c6edd30549a76 100644 --- a/packages/kbn-rule-data-utils/src/technical_field_names.ts +++ b/packages/kbn-rule-data-utils/src/technical_field_names.ts @@ -53,15 +53,10 @@ const ALERT_RULE_LICENSE = `${ALERT_RULE_NAMESPACE}.license` as const; const ALERT_RULE_CATEGORY = `${ALERT_RULE_NAMESPACE}.category` as const; const ALERT_RULE_NAME = `${ALERT_RULE_NAMESPACE}.name` as const; const ALERT_RULE_NOTE = `${ALERT_RULE_NAMESPACE}.note` as const; -const ALERT_RULE_PARAMS = `${ALERT_RULE_NAMESPACE}.params` as const; const ALERT_RULE_PARAMETERS = `${ALERT_RULE_NAMESPACE}.parameters` as const; const ALERT_RULE_REFERENCES = `${ALERT_RULE_NAMESPACE}.references` as const; -const ALERT_RULE_RISK_SCORE = `${ALERT_RULE_NAMESPACE}.risk_score` as const; -const ALERT_RULE_RISK_SCORE_MAPPING = `${ALERT_RULE_NAMESPACE}.risk_score_mapping` as const; const ALERT_RULE_RULE_ID = `${ALERT_RULE_NAMESPACE}.rule_id` as const; const ALERT_RULE_RULE_NAME_OVERRIDE = `${ALERT_RULE_NAMESPACE}.rule_name_override` as const; -const ALERT_RULE_SEVERITY = `${ALERT_RULE_NAMESPACE}.severity` as const; -const ALERT_RULE_SEVERITY_MAPPING = `${ALERT_RULE_NAMESPACE}.severity_mapping` as const; const ALERT_RULE_TAGS = `${ALERT_RULE_NAMESPACE}.tags` as const; const ALERT_RULE_TO = `${ALERT_RULE_NAMESPACE}.to` as const; const ALERT_RULE_TYPE = `${ALERT_RULE_NAMESPACE}.type` as const; @@ -113,15 +108,10 @@ const fields = { ALERT_RULE_LICENSE, ALERT_RULE_NAME, ALERT_RULE_NOTE, - ALERT_RULE_PARAMS, ALERT_RULE_PARAMETERS, ALERT_RULE_REFERENCES, - ALERT_RULE_RISK_SCORE, - ALERT_RULE_RISK_SCORE_MAPPING, ALERT_RULE_RULE_ID, ALERT_RULE_RULE_NAME_OVERRIDE, - ALERT_RULE_SEVERITY, - ALERT_RULE_SEVERITY_MAPPING, ALERT_RULE_TAGS, ALERT_RULE_TO, ALERT_RULE_TYPE, @@ -171,14 +161,10 @@ export { ALERT_RULE_LICENSE, ALERT_RULE_NAME, ALERT_RULE_NOTE, - ALERT_RULE_PARAMS, ALERT_RULE_PARAMETERS, ALERT_RULE_REFERENCES, - ALERT_RULE_RISK_SCORE, - ALERT_RULE_RISK_SCORE_MAPPING, ALERT_RULE_RULE_ID, ALERT_RULE_RULE_NAME_OVERRIDE, - ALERT_RULE_SEVERITY_MAPPING, ALERT_RULE_TAGS, ALERT_RULE_TO, ALERT_RULE_TYPE, @@ -186,7 +172,6 @@ export { ALERT_RULE_UPDATED_AT, ALERT_RULE_UPDATED_BY, ALERT_RULE_VERSION, - ALERT_RULE_SEVERITY, ALERT_SEVERITY, ALERT_START, ALERT_SYSTEM_STATUS, diff --git a/packages/kbn-rule-data-utils/technical_field_names/package.json b/packages/kbn-rule-data-utils/technical_field_names/package.json deleted file mode 100644 index cbac9db58f5f8..0000000000000 --- a/packages/kbn-rule-data-utils/technical_field_names/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "main": "../target_node/technical_field_names", - "types": "../target_types/technical_field_names" -} \ No newline at end of file diff --git a/packages/kbn-securitysolution-autocomplete/BUILD.bazel b/packages/kbn-securitysolution-autocomplete/BUILD.bazel index 50df292b8796e..4af6f8d1b0616 100644 --- a/packages/kbn-securitysolution-autocomplete/BUILD.bazel +++ b/packages/kbn-securitysolution-autocomplete/BUILD.bazel @@ -1,10 +1,10 @@ -load("@npm//@bazel/typescript:index.bzl", "ts_config", "ts_project") -load("@build_bazel_rules_nodejs//:index.bzl", "js_library", "pkg_npm") -load("//src/dev/bazel:index.bzl", "jsts_transpiler") +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 = "kbn-securitysolution-autocomplete" - PKG_REQUIRE_NAME = "@kbn/securitysolution-autocomplete" +TYPES_PKG_REQUIRE_NAME = "@types/kbn__securitysolution-autocomplete" SOURCE_FILES = glob( [ @@ -33,9 +33,9 @@ NPM_MODULE_EXTRA_FILES = [ RUNTIME_DEPS = [ "//packages/kbn-es-query", "//packages/kbn-i18n", + "//packages/kbn-securitysolution-io-ts-list-types", "//packages/kbn-securitysolution-list-hooks", "//packages/kbn-securitysolution-list-utils", - "//packages/kbn-securitysolution-io-ts-list-types", "@npm//@elastic/eui", "@npm//@testing-library/react", "@npm//@testing-library/react-hooks", @@ -46,10 +46,10 @@ RUNTIME_DEPS = [ TYPES_DEPS = [ "//packages/kbn-es-query:npm_module_types", - "//packages/kbn-i18n", - "//packages/kbn-securitysolution-list-hooks", + "//packages/kbn-i18n:npm_module_types", + "//packages/kbn-securitysolution-io-ts-list-types:npm_module_types", + "//packages/kbn-securitysolution-list-hooks:npm_module_types", "//packages/kbn-securitysolution-list-utils", - "//packages/kbn-securitysolution-io-ts-list-types", "@npm//@elastic/eui", "@npm//@testing-library/react", "@npm//@testing-library/react-hooks", @@ -99,7 +99,7 @@ ts_project( js_library( name = PKG_BASE_NAME, srcs = NPM_MODULE_EXTRA_FILES, - deps = RUNTIME_DEPS + [":target_node", ":target_web", ":tsc_types"], + deps = RUNTIME_DEPS + [":target_node", ":target_web"], package_name = PKG_REQUIRE_NAME, visibility = ["//visibility:public"], ) @@ -118,3 +118,21 @@ filegroup( ], visibility = ["//visibility:public"], ) + +pkg_npm_types( + name = "npm_module_types", + srcs = SRCS, + deps = [":tsc_types"], + package_name = TYPES_PKG_REQUIRE_NAME, + tsconfig = ":tsconfig", + visibility = ["//visibility:public"], +) + +filegroup( + name = "build_types", + srcs = [ + ":npm_module_types", + ], + visibility = ["//visibility:public"], +) + diff --git a/packages/kbn-securitysolution-autocomplete/package.json b/packages/kbn-securitysolution-autocomplete/package.json index 5cfd18b63256a..53ab4b7e9dccc 100644 --- a/packages/kbn-securitysolution-autocomplete/package.json +++ b/packages/kbn-securitysolution-autocomplete/package.json @@ -5,6 +5,5 @@ "license": "SSPL-1.0 OR Elastic License 2.0", "browser": "./target_web/index.js", "main": "./target_node/index.js", - "types": "./target_types/index.d.ts", "private": true } diff --git a/packages/kbn-securitysolution-es-utils/BUILD.bazel b/packages/kbn-securitysolution-es-utils/BUILD.bazel index 49c23488b3fe3..ceb643246249e 100644 --- a/packages/kbn-securitysolution-es-utils/BUILD.bazel +++ b/packages/kbn-securitysolution-es-utils/BUILD.bazel @@ -1,10 +1,10 @@ -load("@npm//@bazel/typescript:index.bzl", "ts_config", "ts_project") -load("@build_bazel_rules_nodejs//:index.bzl", "js_library", "pkg_npm") -load("//src/dev/bazel:index.bzl", "jsts_transpiler") +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 = "kbn-securitysolution-es-utils" - PKG_REQUIRE_NAME = "@kbn/securitysolution-es-utils" +TYPES_PKG_REQUIRE_NAME = "@types/kbn__securitysolution-es-utils" SOURCE_FILES = glob( [ @@ -76,7 +76,7 @@ ts_project( js_library( name = PKG_BASE_NAME, srcs = NPM_MODULE_EXTRA_FILES, - deps = RUNTIME_DEPS + [":target_node", ":tsc_types"], + deps = RUNTIME_DEPS + [":target_node"], package_name = PKG_REQUIRE_NAME, visibility = ["//visibility:public"], ) @@ -95,3 +95,20 @@ filegroup( ], visibility = ["//visibility:public"], ) + +pkg_npm_types( + name = "npm_module_types", + srcs = SRCS, + deps = [":tsc_types"], + package_name = TYPES_PKG_REQUIRE_NAME, + tsconfig = ":tsconfig", + visibility = ["//visibility:public"], +) + +filegroup( + name = "build_types", + srcs = [ + ":npm_module_types", + ], + visibility = ["//visibility:public"], +) diff --git a/packages/kbn-securitysolution-es-utils/package.json b/packages/kbn-securitysolution-es-utils/package.json index 84c16ad0b7992..57ed8cf46c5b8 100644 --- a/packages/kbn-securitysolution-es-utils/package.json +++ b/packages/kbn-securitysolution-es-utils/package.json @@ -4,6 +4,5 @@ "description": "security solution elastic search utilities to use across plugins such lists, security_solution, cases, etc...", "license": "SSPL-1.0 OR Elastic License 2.0", "main": "./target_node/index.js", - "types": "./target_types/index.d.ts", "private": true } diff --git a/packages/kbn-securitysolution-hook-utils/BUILD.bazel b/packages/kbn-securitysolution-hook-utils/BUILD.bazel index bc7fd3bce1412..4f46992ad13d6 100644 --- a/packages/kbn-securitysolution-hook-utils/BUILD.bazel +++ b/packages/kbn-securitysolution-hook-utils/BUILD.bazel @@ -1,10 +1,10 @@ -load("@npm//@bazel/typescript:index.bzl", "ts_config", "ts_project") -load("@build_bazel_rules_nodejs//:index.bzl", "js_library", "pkg_npm") -load("//src/dev/bazel:index.bzl", "jsts_transpiler") +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 = "kbn-securitysolution-hook-utils" - PKG_REQUIRE_NAME = "@kbn/securitysolution-hook-utils" +TYPES_PKG_REQUIRE_NAME = "@types/kbn__securitysolution-hook-utils" SOURCE_FILES = glob( [ @@ -83,7 +83,7 @@ ts_project( js_library( name = PKG_BASE_NAME, srcs = NPM_MODULE_EXTRA_FILES, - deps = RUNTIME_DEPS + [":target_node", ":target_web", ":tsc_types"], + deps = RUNTIME_DEPS + [":target_node", ":target_web"], package_name = PKG_REQUIRE_NAME, visibility = ["//visibility:public"], ) @@ -102,3 +102,20 @@ filegroup( ], visibility = ["//visibility:public"], ) + +pkg_npm_types( + name = "npm_module_types", + srcs = SRCS, + deps = [":tsc_types"], + package_name = TYPES_PKG_REQUIRE_NAME, + tsconfig = ":tsconfig", + visibility = ["//visibility:public"], +) + +filegroup( + name = "build_types", + srcs = [ + ":npm_module_types", + ], + visibility = ["//visibility:public"], +) diff --git a/packages/kbn-securitysolution-hook-utils/package.json b/packages/kbn-securitysolution-hook-utils/package.json index c13159f0a4657..fb2576a324223 100644 --- a/packages/kbn-securitysolution-hook-utils/package.json +++ b/packages/kbn-securitysolution-hook-utils/package.json @@ -5,6 +5,5 @@ "license": "SSPL-1.0 OR Elastic License 2.0", "browser": "./target_web/index.js", "main": "./target_node/index.js", - "types": "./target_types/index.d.ts", "private": true } diff --git a/packages/kbn-securitysolution-hook-utils/src/index.ts b/packages/kbn-securitysolution-hook-utils/src/index.ts index 47b0a6119f34f..88ae4c01dbf26 100644 --- a/packages/kbn-securitysolution-hook-utils/src/index.ts +++ b/packages/kbn-securitysolution-hook-utils/src/index.ts @@ -6,6 +6,7 @@ * Side Public License, v 1. */ +export * from './types'; export * from './use_async'; export * from './use_is_mounted'; export * from './use_observable'; diff --git a/packages/kbn-securitysolution-io-ts-alerting-types/BUILD.bazel b/packages/kbn-securitysolution-io-ts-alerting-types/BUILD.bazel index cdee3a2f92540..cf982786891cd 100644 --- a/packages/kbn-securitysolution-io-ts-alerting-types/BUILD.bazel +++ b/packages/kbn-securitysolution-io-ts-alerting-types/BUILD.bazel @@ -1,9 +1,10 @@ -load("@npm//@bazel/typescript:index.bzl", "ts_config", "ts_project") -load("@build_bazel_rules_nodejs//:index.bzl", "js_library", "pkg_npm") -load("//src/dev/bazel:index.bzl", "jsts_transpiler") +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 = "kbn-securitysolution-io-ts-alerting-types" PKG_REQUIRE_NAME = "@kbn/securitysolution-io-ts-alerting-types" +TYPES_PKG_REQUIRE_NAME = "@types/kbn__securitysolution-io-ts-alerting-types" SOURCE_FILES = glob( [ @@ -36,7 +37,7 @@ RUNTIME_DEPS = [ ] TYPES_DEPS = [ - "//packages/kbn-securitysolution-io-ts-types", + "//packages/kbn-securitysolution-io-ts-types:npm_module_types", "//packages/kbn-securitysolution-io-ts-utils", "@npm//fp-ts", "@npm//io-ts", @@ -84,7 +85,7 @@ ts_project( js_library( name = PKG_BASE_NAME, srcs = NPM_MODULE_EXTRA_FILES, - deps = RUNTIME_DEPS + [":target_node", ":target_web", ":tsc_types"], + deps = RUNTIME_DEPS + [":target_node", ":target_web"], package_name = PKG_REQUIRE_NAME, visibility = ["//visibility:public"], ) @@ -103,3 +104,20 @@ filegroup( ], visibility = ["//visibility:public"], ) + +pkg_npm_types( + name = "npm_module_types", + srcs = SRCS, + deps = [":tsc_types"], + package_name = TYPES_PKG_REQUIRE_NAME, + tsconfig = ":tsconfig", + visibility = ["//visibility:public"], +) + +filegroup( + name = "build_types", + srcs = [ + ":npm_module_types", + ], + visibility = ["//visibility:public"], +) diff --git a/packages/kbn-securitysolution-io-ts-alerting-types/package.json b/packages/kbn-securitysolution-io-ts-alerting-types/package.json index 45986851bcdf9..d5dd5516cd9f6 100644 --- a/packages/kbn-securitysolution-io-ts-alerting-types/package.json +++ b/packages/kbn-securitysolution-io-ts-alerting-types/package.json @@ -5,6 +5,5 @@ "license": "SSPL-1.0 OR Elastic License 2.0", "browser": "./target_web/index.js", "main": "./target_node/index.js", - "types": "./target_types/index.d.ts", "private": true } diff --git a/packages/kbn-securitysolution-io-ts-list-types/BUILD.bazel b/packages/kbn-securitysolution-io-ts-list-types/BUILD.bazel index ff4f2e80cbd37..d909fb6c20b42 100644 --- a/packages/kbn-securitysolution-io-ts-list-types/BUILD.bazel +++ b/packages/kbn-securitysolution-io-ts-list-types/BUILD.bazel @@ -1,9 +1,10 @@ -load("@npm//@bazel/typescript:index.bzl", "ts_config", "ts_project") -load("@build_bazel_rules_nodejs//:index.bzl", "js_library", "pkg_npm") -load("//src/dev/bazel:index.bzl", "jsts_transpiler") +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 = "kbn-securitysolution-io-ts-list-types" PKG_REQUIRE_NAME = "@kbn/securitysolution-io-ts-list-types" +TYPES_PKG_REQUIRE_NAME = "@types/kbn__securitysolution-io-ts-list-types" SOURCE_FILES = glob( [ @@ -35,7 +36,7 @@ RUNTIME_DEPS = [ ] TYPES_DEPS = [ - "//packages/kbn-securitysolution-io-ts-types", + "//packages/kbn-securitysolution-io-ts-types:npm_module_types", "//packages/kbn-securitysolution-io-ts-utils", "@npm//fp-ts", "@npm//io-ts", @@ -82,7 +83,7 @@ ts_project( js_library( name = PKG_BASE_NAME, srcs = NPM_MODULE_EXTRA_FILES, - deps = RUNTIME_DEPS + [":target_node", ":target_web", ":tsc_types"], + deps = RUNTIME_DEPS + [":target_node", ":target_web"], package_name = PKG_REQUIRE_NAME, visibility = ["//visibility:public"], ) @@ -101,3 +102,20 @@ filegroup( ], visibility = ["//visibility:public"], ) + +pkg_npm_types( + name = "npm_module_types", + srcs = SRCS, + deps = [":tsc_types"], + package_name = TYPES_PKG_REQUIRE_NAME, + tsconfig = ":tsconfig", + visibility = ["//visibility:public"], +) + +filegroup( + name = "build_types", + srcs = [ + ":npm_module_types", + ], + visibility = ["//visibility:public"], +) diff --git a/packages/kbn-securitysolution-io-ts-list-types/package.json b/packages/kbn-securitysolution-io-ts-list-types/package.json index 6e2f564b31fd8..ff4611f469906 100644 --- a/packages/kbn-securitysolution-io-ts-list-types/package.json +++ b/packages/kbn-securitysolution-io-ts-list-types/package.json @@ -5,6 +5,5 @@ "license": "SSPL-1.0 OR Elastic License 2.0", "browser": "./target_web/index.js", "main": "./target_node/index.js", - "types": "./target_types/index.d.ts", "private": true } diff --git a/packages/kbn-securitysolution-io-ts-types/BUILD.bazel b/packages/kbn-securitysolution-io-ts-types/BUILD.bazel index fe2247ac0b614..68b63cca141f7 100644 --- a/packages/kbn-securitysolution-io-ts-types/BUILD.bazel +++ b/packages/kbn-securitysolution-io-ts-types/BUILD.bazel @@ -1,9 +1,10 @@ -load("@npm//@bazel/typescript:index.bzl", "ts_config", "ts_project") -load("@build_bazel_rules_nodejs//:index.bzl", "js_library", "pkg_npm") -load("//src/dev/bazel:index.bzl", "jsts_transpiler") +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 = "kbn-securitysolution-io-ts-types" PKG_REQUIRE_NAME = "@kbn/securitysolution-io-ts-types" +TYPES_PKG_REQUIRE_NAME = "@types/kbn__securitysolution-io-ts-types" SOURCE_FILES = glob( [ @@ -82,7 +83,7 @@ ts_project( js_library( name = PKG_BASE_NAME, srcs = NPM_MODULE_EXTRA_FILES, - deps = RUNTIME_DEPS + [":target_node", ":target_web", ":tsc_types"], + deps = RUNTIME_DEPS + [":target_node", ":target_web"], package_name = PKG_REQUIRE_NAME, visibility = ["//visibility:public"], ) @@ -101,3 +102,20 @@ filegroup( ], visibility = ["//visibility:public"], ) + +pkg_npm_types( + name = "npm_module_types", + srcs = SRCS, + deps = [":tsc_types"], + package_name = TYPES_PKG_REQUIRE_NAME, + tsconfig = ":tsconfig", + visibility = ["//visibility:public"], +) + +filegroup( + name = "build_types", + srcs = [ + ":npm_module_types", + ], + visibility = ["//visibility:public"], +) diff --git a/packages/kbn-securitysolution-io-ts-types/package.json b/packages/kbn-securitysolution-io-ts-types/package.json index 767c8d0f0cbcb..76e405c227053 100644 --- a/packages/kbn-securitysolution-io-ts-types/package.json +++ b/packages/kbn-securitysolution-io-ts-types/package.json @@ -5,6 +5,5 @@ "license": "SSPL-1.0 OR Elastic License 2.0", "browser": "target_web/index.js", "main": "./target_node/index.js", - "types": "./target_types/index.d.ts", "private": true } diff --git a/packages/kbn-securitysolution-list-api/BUILD.bazel b/packages/kbn-securitysolution-list-api/BUILD.bazel index 52a134456cdd9..ed5d11d48a5d4 100644 --- a/packages/kbn-securitysolution-list-api/BUILD.bazel +++ b/packages/kbn-securitysolution-list-api/BUILD.bazel @@ -1,10 +1,10 @@ -load("@npm//@bazel/typescript:index.bzl", "ts_config", "ts_project") -load("@build_bazel_rules_nodejs//:index.bzl", "js_library", "pkg_npm") -load("//src/dev/bazel:index.bzl", "jsts_transpiler") +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 = "kbn-securitysolution-list-api" - PKG_REQUIRE_NAME = "@kbn/securitysolution-list-api" +TYPES_PKG_REQUIRE_NAME = "@types/kbn__securitysolution-list-api" SOURCE_FILES = glob( [ @@ -37,9 +37,9 @@ RUNTIME_DEPS = [ ] TYPES_DEPS = [ - "//packages/kbn-securitysolution-io-ts-list-types", + "//packages/kbn-securitysolution-io-ts-list-types:npm_module_types", "//packages/kbn-securitysolution-io-ts-utils", - "//packages/kbn-securitysolution-list-constants", + "//packages/kbn-securitysolution-list-constants:npm_module_types", "@npm//fp-ts", "@npm//io-ts", "@npm//@types/jest", @@ -85,7 +85,7 @@ ts_project( js_library( name = PKG_BASE_NAME, srcs = NPM_MODULE_EXTRA_FILES, - deps = RUNTIME_DEPS + [":target_node", ":target_web", ":tsc_types"], + deps = RUNTIME_DEPS + [":target_node", ":target_web"], package_name = PKG_REQUIRE_NAME, visibility = ["//visibility:public"], ) @@ -104,3 +104,20 @@ filegroup( ], visibility = ["//visibility:public"], ) + +pkg_npm_types( + name = "npm_module_types", + srcs = SRCS, + deps = [":tsc_types"], + package_name = TYPES_PKG_REQUIRE_NAME, + tsconfig = ":tsconfig", + visibility = ["//visibility:public"], +) + +filegroup( + name = "build_types", + srcs = [ + ":npm_module_types", + ], + visibility = ["//visibility:public"], +) diff --git a/packages/kbn-securitysolution-list-api/package.json b/packages/kbn-securitysolution-list-api/package.json index 8454f13d841b4..d243f71127c1f 100644 --- a/packages/kbn-securitysolution-list-api/package.json +++ b/packages/kbn-securitysolution-list-api/package.json @@ -5,6 +5,5 @@ "license": "SSPL-1.0 OR Elastic License 2.0", "browser": "./target_web/index.js", "main": "./target_node/index.js", - "types": "./target_types/index.d.ts", "private": true } diff --git a/packages/kbn-securitysolution-list-api/src/list_api/index.ts b/packages/kbn-securitysolution-list-api/src/list_api/index.ts index b9d5417f761c0..f489b9292dc87 100644 --- a/packages/kbn-securitysolution-list-api/src/list_api/index.ts +++ b/packages/kbn-securitysolution-list-api/src/list_api/index.ts @@ -46,6 +46,14 @@ import { ImportListParams, } from './types'; +export type { + ApiParams, + DeleteListParams, + ExportListParams, + FindListsParams, + ImportListParams, +} from './types'; + const findLists = async ({ http, cursor, diff --git a/packages/kbn-securitysolution-list-constants/BUILD.bazel b/packages/kbn-securitysolution-list-constants/BUILD.bazel index db4dd94091abf..3802e3a581969 100644 --- a/packages/kbn-securitysolution-list-constants/BUILD.bazel +++ b/packages/kbn-securitysolution-list-constants/BUILD.bazel @@ -1,10 +1,10 @@ -load("@npm//@bazel/typescript:index.bzl", "ts_config", "ts_project") -load("@build_bazel_rules_nodejs//:index.bzl", "js_library", "pkg_npm") -load("//src/dev/bazel:index.bzl", "jsts_transpiler") +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 = "kbn-securitysolution-list-constants" - PKG_REQUIRE_NAME = "@kbn/securitysolution-list-constants" +TYPES_PKG_REQUIRE_NAME = "@types/kbn__securitysolution-list-constants" SOURCE_FILES = glob( [ @@ -74,7 +74,7 @@ ts_project( js_library( name = PKG_BASE_NAME, srcs = NPM_MODULE_EXTRA_FILES, - deps = RUNTIME_DEPS + [":target_node", ":target_web", ":tsc_types"], + deps = RUNTIME_DEPS + [":target_node", ":target_web"], package_name = PKG_REQUIRE_NAME, visibility = ["//visibility:public"], ) @@ -93,3 +93,20 @@ filegroup( ], visibility = ["//visibility:public"], ) + +pkg_npm_types( + name = "npm_module_types", + srcs = SRCS, + deps = [":tsc_types"], + package_name = TYPES_PKG_REQUIRE_NAME, + tsconfig = ":tsconfig", + visibility = ["//visibility:public"], +) + +filegroup( + name = "build_types", + srcs = [ + ":npm_module_types", + ], + visibility = ["//visibility:public"], +) diff --git a/packages/kbn-securitysolution-list-constants/package.json b/packages/kbn-securitysolution-list-constants/package.json index 37f15fd06b0bc..8900265c30cd2 100644 --- a/packages/kbn-securitysolution-list-constants/package.json +++ b/packages/kbn-securitysolution-list-constants/package.json @@ -5,6 +5,5 @@ "license": "SSPL-1.0 OR Elastic License 2.0", "browser": "./target_web/index.js", "main": "./target_node/index.js", - "types": "./target_types/index.d.ts", "private": true } diff --git a/packages/kbn-securitysolution-list-hooks/BUILD.bazel b/packages/kbn-securitysolution-list-hooks/BUILD.bazel index 2a9666bd1429e..d45f6258615fc 100644 --- a/packages/kbn-securitysolution-list-hooks/BUILD.bazel +++ b/packages/kbn-securitysolution-list-hooks/BUILD.bazel @@ -1,10 +1,10 @@ -load("@npm//@bazel/typescript:index.bzl", "ts_config", "ts_project") -load("@build_bazel_rules_nodejs//:index.bzl", "js_library", "pkg_npm") -load("//src/dev/bazel:index.bzl", "jsts_transpiler") +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 = "kbn-securitysolution-list-hooks" - PKG_REQUIRE_NAME = "@kbn/securitysolution-list-hooks" +TYPES_PKG_REQUIRE_NAME = "@types/kbn__securitysolution-list-hooks" SOURCE_FILES = glob( [ @@ -40,12 +40,12 @@ RUNTIME_DEPS = [ ] TYPES_DEPS = [ - "//packages/kbn-securitysolution-hook-utils", - "//packages/kbn-securitysolution-io-ts-list-types", - "//packages/kbn-securitysolution-list-api", - "//packages/kbn-securitysolution-list-constants", + "//packages/kbn-securitysolution-hook-utils:npm_module_types", + "//packages/kbn-securitysolution-io-ts-list-types:npm_module_types", + "//packages/kbn-securitysolution-list-api:npm_module_types", + "//packages/kbn-securitysolution-list-constants:npm_module_types", "//packages/kbn-securitysolution-list-utils", - "//packages/kbn-securitysolution-utils", + "//packages/kbn-securitysolution-utils:npm_module_types", "@npm//@types/jest", "@npm//@types/node", "@npm//@types/react", @@ -91,7 +91,7 @@ ts_project( js_library( name = PKG_BASE_NAME, srcs = NPM_MODULE_EXTRA_FILES, - deps = RUNTIME_DEPS + [":target_node", ":target_web", ":tsc_types"], + deps = RUNTIME_DEPS + [":target_node", ":target_web"], package_name = PKG_REQUIRE_NAME, visibility = ["//visibility:public"], ) @@ -110,3 +110,20 @@ filegroup( ], visibility = ["//visibility:public"], ) + +pkg_npm_types( + name = "npm_module_types", + srcs = SRCS, + deps = [":tsc_types"], + package_name = TYPES_PKG_REQUIRE_NAME, + tsconfig = ":tsconfig", + visibility = ["//visibility:public"], +) + +filegroup( + name = "build_types", + srcs = [ + ":npm_module_types", + ], + visibility = ["//visibility:public"], +) diff --git a/packages/kbn-securitysolution-list-hooks/package.json b/packages/kbn-securitysolution-list-hooks/package.json index ffd4ad61850fc..d6d6077332903 100644 --- a/packages/kbn-securitysolution-list-hooks/package.json +++ b/packages/kbn-securitysolution-list-hooks/package.json @@ -5,6 +5,5 @@ "license": "SSPL-1.0 OR Elastic License 2.0", "browser": "./target_web/index.js", "main": "./target_node/index.js", - "types": "./target_types/index.d.ts", "private": true } diff --git a/packages/kbn-securitysolution-list-utils/BUILD.bazel b/packages/kbn-securitysolution-list-utils/BUILD.bazel index 30568ca725041..fedb8e70a0cb3 100644 --- a/packages/kbn-securitysolution-list-utils/BUILD.bazel +++ b/packages/kbn-securitysolution-list-utils/BUILD.bazel @@ -32,21 +32,25 @@ RUNTIME_DEPS = [ "//packages/kbn-es-query", "//packages/kbn-i18n", "//packages/kbn-securitysolution-io-ts-list-types", + "//packages/kbn-securitysolution-io-ts-utils", "//packages/kbn-securitysolution-list-constants", "//packages/kbn-securitysolution-utils", "@npm//lodash", + "@npm//uuid", ] TYPES_DEPS = [ "//packages/kbn-es-query:npm_module_types", "//packages/kbn-i18n:npm_module_types", - "//packages/kbn-securitysolution-io-ts-list-types", - "//packages/kbn-securitysolution-list-constants", - "//packages/kbn-securitysolution-utils", + "//packages/kbn-securitysolution-io-ts-list-types:npm_module_types", + "//packages/kbn-securitysolution-io-ts-utils", + "//packages/kbn-securitysolution-list-constants:npm_module_types", + "//packages/kbn-securitysolution-utils:npm_module_types", "@npm//@elastic/elasticsearch", "@npm//@types/jest", "@npm//@types/lodash", "@npm//@types/node", + "@npm//@types/uuid", ] jsts_transpiler( diff --git a/packages/kbn-securitysolution-rules/BUILD.bazel b/packages/kbn-securitysolution-rules/BUILD.bazel index d8d0122fc4f5f..7158f759f4466 100644 --- a/packages/kbn-securitysolution-rules/BUILD.bazel +++ b/packages/kbn-securitysolution-rules/BUILD.bazel @@ -1,10 +1,10 @@ -load("@npm//@bazel/typescript:index.bzl", "ts_config", "ts_project") -load("@build_bazel_rules_nodejs//:index.bzl", "js_library", "pkg_npm") -load("//src/dev/bazel:index.bzl", "jsts_transpiler") +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 = "kbn-securitysolution-rules" - PKG_REQUIRE_NAME = "@kbn/securitysolution-rules" +TYPES_PKG_REQUIRE_NAME = "@types/kbn__securitysolution-rules" SOURCE_FILES = glob( [ @@ -74,7 +74,7 @@ ts_project( js_library( name = PKG_BASE_NAME, srcs = NPM_MODULE_EXTRA_FILES, - deps = RUNTIME_DEPS + [":target_node", ":tsc_types"], + deps = RUNTIME_DEPS + [":target_node"], package_name = PKG_REQUIRE_NAME, visibility = ["//visibility:public"], ) @@ -93,3 +93,20 @@ filegroup( ], visibility = ["//visibility:public"], ) + +pkg_npm_types( + name = "npm_module_types", + srcs = SRCS, + deps = [":tsc_types"], + package_name = TYPES_PKG_REQUIRE_NAME, + tsconfig = ":tsconfig", + visibility = ["//visibility:public"], +) + +filegroup( + name = "build_types", + srcs = [ + ":npm_module_types", + ], + visibility = ["//visibility:public"], +) diff --git a/packages/kbn-securitysolution-rules/package.json b/packages/kbn-securitysolution-rules/package.json index 5fdb1e593b042..4962576450f59 100644 --- a/packages/kbn-securitysolution-rules/package.json +++ b/packages/kbn-securitysolution-rules/package.json @@ -4,6 +4,5 @@ "description": "security solution rule utilities to use across plugins", "license": "SSPL-1.0 OR Elastic License 2.0", "main": "./target_node/index.js", - "types": "./target_types/index.d.ts", "private": true } diff --git a/packages/kbn-securitysolution-t-grid/BUILD.bazel b/packages/kbn-securitysolution-t-grid/BUILD.bazel index dd4e73af95720..e0898f90d7f87 100644 --- a/packages/kbn-securitysolution-t-grid/BUILD.bazel +++ b/packages/kbn-securitysolution-t-grid/BUILD.bazel @@ -1,10 +1,10 @@ -load("@npm//@bazel/typescript:index.bzl", "ts_config", "ts_project") -load("@build_bazel_rules_nodejs//:index.bzl", "js_library", "pkg_npm") -load("//src/dev/bazel:index.bzl", "jsts_transpiler") +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 = "kbn-securitysolution-t-grid" - PKG_REQUIRE_NAME = "@kbn/securitysolution-t-grid" +TYPES_PKG_REQUIRE_NAME = "@types/kbn__securitysolution-t-grid" SOURCE_FILES = glob( [ @@ -83,7 +83,7 @@ ts_project( js_library( name = PKG_BASE_NAME, srcs = NPM_MODULE_EXTRA_FILES, - deps = RUNTIME_DEPS + [":target_node", ":target_web", ":tsc_types"], + deps = RUNTIME_DEPS + [":target_node", ":target_web"], package_name = PKG_REQUIRE_NAME, visibility = ["//visibility:public"], ) @@ -102,3 +102,20 @@ filegroup( ], visibility = ["//visibility:public"], ) + +pkg_npm_types( + name = "npm_module_types", + srcs = SRCS, + deps = [":tsc_types"], + package_name = TYPES_PKG_REQUIRE_NAME, + tsconfig = ":tsconfig", + visibility = ["//visibility:public"], +) + +filegroup( + name = "build_types", + srcs = [ + ":npm_module_types", + ], + visibility = ["//visibility:public"], +) diff --git a/packages/kbn-securitysolution-t-grid/package.json b/packages/kbn-securitysolution-t-grid/package.json index 92464f3246ecd..accf7b4d61731 100644 --- a/packages/kbn-securitysolution-t-grid/package.json +++ b/packages/kbn-securitysolution-t-grid/package.json @@ -5,6 +5,5 @@ "license": "SSPL-1.0 OR Elastic License 2.0", "browser": "./target_web/index.js", "main": "./target_node/index.js", - "types": "./target_types/index.d.ts", "private": true } diff --git a/packages/kbn-securitysolution-t-grid/src/mock/mock_event_details.ts b/packages/kbn-securitysolution-t-grid/src/mock/mock_event_details.ts index 8708aa4c07603..93e3cd2a4ce02 100644 --- a/packages/kbn-securitysolution-t-grid/src/mock/mock_event_details.ts +++ b/packages/kbn-securitysolution-t-grid/src/mock/mock_event_details.ts @@ -72,9 +72,7 @@ export const eventHit = { ], astring: 'cool', aNumber: 1, - anObject: { - neat: true, - }, + neat: true, }, ], }, diff --git a/packages/kbn-securitysolution-utils/BUILD.bazel b/packages/kbn-securitysolution-utils/BUILD.bazel index c3d6b92044ef6..d22e31daacd55 100644 --- a/packages/kbn-securitysolution-utils/BUILD.bazel +++ b/packages/kbn-securitysolution-utils/BUILD.bazel @@ -1,10 +1,10 @@ -load("@npm//@bazel/typescript:index.bzl", "ts_config", "ts_project") -load("@build_bazel_rules_nodejs//:index.bzl", "js_library", "pkg_npm") -load("//src/dev/bazel:index.bzl", "jsts_transpiler") +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 = "kbn-securitysolution-utils" - PKG_REQUIRE_NAME = "@kbn/securitysolution-utils" +TYPES_PKG_REQUIRE_NAME = "@types/kbn__securitysolution-utils" SOURCE_FILES = glob( [ @@ -72,7 +72,7 @@ ts_project( js_library( name = PKG_BASE_NAME, srcs = NPM_MODULE_EXTRA_FILES, - deps = RUNTIME_DEPS + [":target_node", ":tsc_types"], + deps = RUNTIME_DEPS + [":target_node"], package_name = PKG_REQUIRE_NAME, visibility = ["//visibility:public"], ) @@ -91,3 +91,20 @@ filegroup( ], visibility = ["//visibility:public"], ) + +pkg_npm_types( + name = "npm_module_types", + srcs = SRCS, + deps = [":tsc_types"], + package_name = TYPES_PKG_REQUIRE_NAME, + tsconfig = ":tsconfig", + visibility = ["//visibility:public"], +) + +filegroup( + name = "build_types", + srcs = [ + ":npm_module_types", + ], + visibility = ["//visibility:public"], +) diff --git a/packages/kbn-securitysolution-utils/package.json b/packages/kbn-securitysolution-utils/package.json index 98f19e33d379b..8f347972f8316 100644 --- a/packages/kbn-securitysolution-utils/package.json +++ b/packages/kbn-securitysolution-utils/package.json @@ -4,6 +4,5 @@ "description": "security solution utilities to use across plugins such lists, security_solution, cases, etc...", "license": "SSPL-1.0 OR Elastic License 2.0", "main": "./target_node/index.js", - "types": "./target_types/index.d.ts", "private": true } diff --git a/packages/kbn-test/src/jest/utils/testbed/README.md b/packages/kbn-test/src/jest/utils/testbed/README.md index 5a05ba3750d3c..87cabd7ca4fa1 100644 --- a/packages/kbn-test/src/jest/utils/testbed/README.md +++ b/packages/kbn-test/src/jest/utils/testbed/README.md @@ -116,7 +116,7 @@ In order to prevent flakiness in component integration tests, please consider th }); ``` -- **Do not use** using `nextTick()`, `waitFor`, or `waitForFunc` helpers in tests. These helpers use `setTimeout` underneath and add latency in the tests, especially on CI where a timeout (even of a few ms) can trigger a timeout error. These helpers will eventually be deprecated once existing tests has been updated. +- **Do not use** using `nextTick()` helper in tests. This helper use `setTimeout` underneath and add latency in the tests, especially on CI where a timeout (even of a few ms) can trigger a timeout error. - **Do not declare** `component.update()` inside `act()`. Each `act()` call should contain a chunk of actions that updates the internal state(s). The `component.update()` that re-renders the internal DOM needs to be called outside, before asserting against the updated DOM. @@ -274,14 +274,11 @@ expect(tableCellsValues).toEqual([ An object with the following methods: -##### `setInputValue(input, value, isAsync)` +##### `setInputValue(input, value)` Set the value of a form input. The input can either be a test subject (a string) or an Enzyme react wrapper. If you specify a test subject, you can provide a nested path to access it by separating the parent and child with a dot (e.g. `myForm.followerIndexName`). -`isAsync`: flag that will return a Promise that resolves on the next "tick". This is useful if updating the input triggers -an async operation (like a HTTP request) and we need it to resolve so the DOM gets updated (default: `false`). - ```js await form.setInputValue('myInput', 'some value', true); ``` diff --git a/packages/kbn-test/src/jest/utils/testbed/testbed.ts b/packages/kbn-test/src/jest/utils/testbed/testbed.ts index 240ec25a9c296..b10f331da10d6 100644 --- a/packages/kbn-test/src/jest/utils/testbed/testbed.ts +++ b/packages/kbn-test/src/jest/utils/testbed/testbed.ts @@ -157,52 +157,17 @@ export function registerTestBed( }); }; - const waitForFn: TestBed['waitForFn'] = async (predicate, errMessage) => { - const triggeredAt = Date.now(); - - const MAX_WAIT_TIME = 30000; - const WAIT_INTERVAL = 50; - - const process = async (): Promise => { - const isOK = await predicate(); - - if (isOK) { - // Great! nothing else to do here. - return; - } - - const timeElapsed = Date.now() - triggeredAt; - if (timeElapsed > MAX_WAIT_TIME) { - throw new Error(errMessage); - } - - return new Promise((resolve) => setTimeout(resolve, WAIT_INTERVAL)).then(() => { - component.update(); - return process(); - }); - }; - - return process(); - }; - - const waitFor: TestBed['waitFor'] = (testSubject: T, count = 1) => { - return waitForFn( - () => Promise.resolve(exists(testSubject, count)), - `I waited patiently for the "${testSubject}" test subject to appear with no luck. It is nowhere to be found!` - ); - }; - /** * ---------------------------------------------------------------- * Forms * ---------------------------------------------------------------- */ - const setInputValue: TestBed['form']['setInputValue'] = ( - input, - value, - isAsync = false - ) => { + const setInputValue: TestBed['form']['setInputValue'] = function (input, value) { + if (arguments.length === 3) { + throw new Error(`Passing the "isAsync" arg is not supported anymore.`); + } + const formInput = typeof input === 'string' ? find(input) : input; if (!formInput.length) { @@ -210,11 +175,6 @@ export function registerTestBed( } formInput.simulate('change', { target: { value } }); component.update(); - - if (!isAsync) { - return; - } - return new Promise((resolve) => setTimeout(resolve)); }; const setSelectValue: TestBed['form']['setSelectValue'] = ( @@ -334,8 +294,6 @@ export function registerTestBed( exists, find, setProps, - waitFor, - waitForFn, table: { getMetaData, }, diff --git a/packages/kbn-test/src/jest/utils/testbed/types.ts b/packages/kbn-test/src/jest/utils/testbed/types.ts index 121b848e51b51..924eaa2f81b15 100644 --- a/packages/kbn-test/src/jest/utils/testbed/types.ts +++ b/packages/kbn-test/src/jest/utils/testbed/types.ts @@ -61,31 +61,14 @@ export interface TestBed { * @param updatedProps The updated prop object */ setProps: (updatedProps: any) => void; - /** - * Helper to wait until an element appears in the DOM as hooks updates cycles are tricky. - * Useful when loading a component that fetches a resource from the server - * and we need to wait for the data to be fetched (and bypass any "loading" state). - */ - waitFor: (testSubject: T, count?: number) => Promise; - waitForFn: (predicate: () => Promise, errMessage: string) => Promise; form: { /** * Set the value of a form text input. * - * In some cases, changing an input value triggers an HTTP request to validate - * the field. Even if we return immediately the response on the mock server we - * still need to wait until the next tick before the DOM updates. - * Setting isAsync to "true" takes care of that. - * * @param input The form input. Can either be a data-test-subj or a reactWrapper (can be a nested path. e.g. "myForm.myInput"). * @param value The value to set - * @param isAsync If set to true will return a Promise that resolves on the next "tick" */ - setInputValue: ( - input: T | ReactWrapper, - value: string, - isAsync?: boolean - ) => Promise | void; + setInputValue: (input: T | ReactWrapper, value: string) => void; /** * Set the value of a or a mocked * For the you need to mock it like this diff --git a/packages/kbn-test/src/kbn_client/kbn_client_saved_objects.ts b/packages/kbn-test/src/kbn_client/kbn_client_saved_objects.ts index 904ccc385bd7d..f70123029e6c4 100644 --- a/packages/kbn-test/src/kbn_client/kbn_client_saved_objects.ts +++ b/packages/kbn-test/src/kbn_client/kbn_client_saved_objects.ts @@ -36,6 +36,7 @@ interface SavedObjectResponse> { interface GetOptions { type: string; id: string; + space?: string; } interface IndexOptions { @@ -110,11 +111,13 @@ export class KbnClientSavedObjects { * Get an object */ public async get>(options: GetOptions) { - this.log.debug('Gettings saved object: %j', options); + this.log.debug('Getting saved object: %j', options); const { data } = await this.requester.request>({ description: 'get saved object', - path: uriencode`/api/saved_objects/${options.type}/${options.id}`, + path: options.space + ? uriencode`/s/${options.space}/api/saved_objects/${options.type}/${options.id}` + : uriencode`/api/saved_objects/${options.type}/${options.id}`, method: 'GET', }); return data; @@ -174,7 +177,9 @@ export class KbnClientSavedObjects { const { data } = await this.requester.request({ description: 'delete saved object', - path: uriencode`/api/saved_objects/${options.type}/${options.id}`, + path: options.space + ? uriencode`/s/${options.space}/api/saved_objects/${options.type}/${options.id}` + : uriencode`/api/saved_objects/${options.type}/${options.id}`, method: 'DELETE', }); diff --git a/packages/kbn-ui-shared-deps-npm/webpack.config.js b/packages/kbn-ui-shared-deps-npm/webpack.config.js index 197ec5e63ad7c..5b030a91e396e 100644 --- a/packages/kbn-ui-shared-deps-npm/webpack.config.js +++ b/packages/kbn-ui-shared-deps-npm/webpack.config.js @@ -70,8 +70,8 @@ module.exports = (_, argv) => { '@elastic/eui/dist/eui_charts_theme', '@elastic/eui/lib/services', '@elastic/eui/lib/services/format', - '@elastic/eui/dist/eui_theme_amsterdam_light.json', - '@elastic/eui/dist/eui_theme_amsterdam_dark.json', + '@elastic/eui/dist/eui_theme_light.json', + '@elastic/eui/dist/eui_theme_dark.json', '@elastic/numeral', '@emotion/react', 'classnames', @@ -96,8 +96,8 @@ module.exports = (_, argv) => { 'styled-components', 'tslib', ], - 'kbn-ui-shared-deps-npm.v8.dark': ['@elastic/eui/dist/eui_theme_amsterdam_dark.css'], - 'kbn-ui-shared-deps-npm.v8.light': ['@elastic/eui/dist/eui_theme_amsterdam_light.css'], + 'kbn-ui-shared-deps-npm.v8.dark': ['@elastic/eui/dist/eui_theme_dark.css'], + 'kbn-ui-shared-deps-npm.v8.light': ['@elastic/eui/dist/eui_theme_light.css'], }, context: __dirname, devtool: 'cheap-source-map', diff --git a/packages/kbn-ui-shared-deps-src/BUILD.bazel b/packages/kbn-ui-shared-deps-src/BUILD.bazel index 454121392ac68..f7e1fe27475c6 100644 --- a/packages/kbn-ui-shared-deps-src/BUILD.bazel +++ b/packages/kbn-ui-shared-deps-src/BUILD.bazel @@ -47,7 +47,7 @@ TYPES_DEPS = [ "//packages/kbn-analytics:npm_module_types", "//packages/kbn-i18n:npm_module_types", "//packages/kbn-i18n-react:npm_module_types", - "//packages/kbn-monaco", + "//packages/kbn-monaco:npm_module_types", "//packages/kbn-std", "//packages/kbn-ui-shared-deps-npm", "@npm//@elastic/eui", diff --git a/packages/kbn-ui-shared-deps-src/src/theme.ts b/packages/kbn-ui-shared-deps-src/src/theme.ts index 33b8a594bfa5d..8fde5c63a292a 100644 --- a/packages/kbn-ui-shared-deps-src/src/theme.ts +++ b/packages/kbn-ui-shared-deps-src/src/theme.ts @@ -7,9 +7,9 @@ */ /* eslint-disable-next-line @kbn/eslint/module_migration */ -import { default as v8Light } from '@elastic/eui/dist/eui_theme_amsterdam_light.json'; +import { default as v8Light } from '@elastic/eui/dist/eui_theme_light.json'; /* eslint-disable-next-line @kbn/eslint/module_migration */ -import { default as v8Dark } from '@elastic/eui/dist/eui_theme_amsterdam_dark.json'; +import { default as v8Dark } from '@elastic/eui/dist/eui_theme_dark.json'; const globals: any = typeof window === 'undefined' ? {} : window; diff --git a/renovate.json b/renovate.json index 362fd9381b617..95358af48a2cc 100644 --- a/renovate.json +++ b/renovate.json @@ -26,7 +26,7 @@ "matchPackageNames": ["@elastic/charts"], "reviewers": ["team:datavis"], "matchBaseBranches": ["main"], - "labels": ["release_note:skip", "v8.0.0", "v7.16.0", "auto-backport"], + "labels": ["release_note:skip", "auto-backport", "Team:DataVis", "v8.1.0", "v7.17.0"], "draftPR": true, "enabled": true }, @@ -35,7 +35,7 @@ "matchPackageNames": ["@elastic/elasticsearch"], "reviewers": ["team:kibana-operations", "team:kibana-core"], "matchBaseBranches": ["main"], - "labels": ["release_note:skip", "v8.0.0", "Team:Operations", "Team:Core", "backport:skip"], + "labels": ["release_note:skip", "backport:skip", "Team:Operations", "Team:Core", "v8.1.0"], "enabled": true }, { @@ -72,6 +72,16 @@ "enabled": true, "stabilityDays": 7 }, + { + "groupName": "typescript", + "matchPackageNames": ["typescript", "prettier", "@types/jsdom"], + "matchPackagePatterns": ["^@typescript-eslint"], + "reviewers": ["team:kibana-operations"], + "matchBaseBranches": ["main"], + "labels": ["Team:Operations", "release_note:skip"], + "enabled": true, + "stabilityDays": 7 + }, { "groupName": "polyfills", "matchPackageNames": ["core-js"], @@ -116,6 +126,21 @@ "matchBaseBranches": ["main"], "labels": ["Team:Security", "release_note:skip", "auto-backport"], "enabled": true + }, + { + "groupName": "ftr", + "packageNames": [ + "@types/chromedriver", + "@types/selenium-webdriver", + "chromedriver", + "geckodriver", + "ms-chromium-edge-driver", + "selenium-webdriver" + ], + "reviewers": ["team:kibana-operations"], + "matchBaseBranches": ["main"], + "labels": ["Team:Operations", "release_note:skip"], + "enabled": true } ] } diff --git a/src/core/public/core_app/status/components/__snapshots__/metric_tiles.test.tsx.snap b/src/core/public/core_app/status/components/__snapshots__/metric_tiles.test.tsx.snap index 2219e0d7609b8..cc4e27a6d6388 100644 --- a/src/core/public/core_app/status/components/__snapshots__/metric_tiles.test.tsx.snap +++ b/src/core/public/core_app/status/components/__snapshots__/metric_tiles.test.tsx.snap @@ -4,17 +4,24 @@ exports[`MetricTile correct displays a byte metric 1`] = ` `; exports[`MetricTile correct displays a float metric 1`] = ` - `; @@ -22,7 +29,7 @@ exports[`MetricTile correct displays a time metric 1`] = ` `; @@ -31,7 +38,29 @@ exports[`MetricTile correct displays an untyped metric 1`] = ` `; + +exports[`MetricTile correctly displays a metric with metadata 1`] = ` + +`; diff --git a/src/core/public/core_app/status/components/metric_tiles.test.tsx b/src/core/public/core_app/status/components/metric_tiles.test.tsx index 76608718e8cd3..8e6d1cf38cd01 100644 --- a/src/core/public/core_app/status/components/metric_tiles.test.tsx +++ b/src/core/public/core_app/status/components/metric_tiles.test.tsx @@ -35,6 +35,18 @@ const timeMetric: Metric = { value: 1234, }; +const metricWithMeta: Metric = { + name: 'Delay', + type: 'time', + value: 1, + meta: { + description: 'Percentiles', + title: '', + value: [1, 5, 10], + type: 'time', + }, +}; + describe('MetricTile', () => { it('correct displays an untyped metric', () => { const component = shallow(); @@ -55,4 +67,9 @@ describe('MetricTile', () => { const component = shallow(); expect(component).toMatchSnapshot(); }); + + it('correctly displays a metric with metadata', () => { + const component = shallow(); + expect(component).toMatchSnapshot(); + }); }); diff --git a/src/core/public/core_app/status/components/metric_tiles.tsx b/src/core/public/core_app/status/components/metric_tiles.tsx index 1eb5ee4c95dd8..18fa9ae738227 100644 --- a/src/core/public/core_app/status/components/metric_tiles.tsx +++ b/src/core/public/core_app/status/components/metric_tiles.tsx @@ -7,24 +7,105 @@ */ import React, { FunctionComponent } from 'react'; -import { EuiFlexGrid, EuiFlexItem, EuiCard } from '@elastic/eui'; -import { formatNumber, Metric } from '../lib'; +import { EuiFlexGrid, EuiFlexItem, EuiCard, EuiStat } from '@elastic/eui'; +import { DataType, formatNumber, Metric } from '../lib'; /* - * Displays a metric with the correct format. + * Displays metadata for a metric. */ -export const MetricTile: FunctionComponent<{ metric: Metric }> = ({ metric }) => { - const { name } = metric; +const MetricCardFooter: FunctionComponent<{ + title: string; + description: string; +}> = ({ title, description }) => { + return ( + + ); +}; + +const DelayMetricTile: FunctionComponent<{ metric: Metric }> = ({ metric }) => { + const { name, meta } = metric; return ( + ) + } + /> + ); +}; + +const LoadMetricTile: FunctionComponent<{ metric: Metric }> = ({ metric }) => { + const { name, meta } = metric; + return ( + } /> ); }; +const ResponseTimeMetric: FunctionComponent<{ metric: Metric }> = ({ metric }) => { + const { name, meta } = metric; + return ( + + ) + } + /> + ); +}; + +/* + * Displays a metric with the correct format. + */ +export const MetricTile: FunctionComponent<{ metric: Metric }> = ({ metric }) => { + const { name } = metric; + switch (name) { + case 'Delay': + return ; + case 'Load': + return ; + case 'Response time avg': + return ; + default: + return ( + + ); + } +}; + /* * Wrapper component that simply maps each metric to MetricTile inside a FlexGroup */ @@ -38,11 +119,20 @@ export const MetricTiles: FunctionComponent<{ metrics: Metric[] }> = ({ metrics
); +// formatting helper functions + const formatMetric = ({ value, type }: Metric) => { const metrics = Array.isArray(value) ? value : [value]; return metrics.map((metric) => formatNumber(metric, type)).join(', '); }; -const formatMetricId = ({ name }: Metric) => { +const formatMetricId = (name: Metric['name']) => { return name.toLowerCase().replace(/[ ]+/g, '-'); }; + +const formatDelayFooterTitle = (values: number[], type?: DataType) => { + return ` + 50: ${formatNumber(values[0], type)}; + 95: ${formatNumber(values[1], type)}; + 99: ${formatNumber(values[2], type)}`; +}; diff --git a/src/core/public/core_app/status/lib/load_status.test.ts b/src/core/public/core_app/status/lib/load_status.test.ts index 555e793b41aa5..f044aa2daa2e9 100644 --- a/src/core/public/core_app/status/lib/load_status.test.ts +++ b/src/core/public/core_app/status/lib/load_status.test.ts @@ -229,13 +229,23 @@ describe('response processing', () => { expect(names).toEqual([ 'Heap total', 'Heap used', + 'Requests per second', 'Load', + 'Delay', 'Response time avg', - 'Response time max', - 'Requests per second', ]); - const values = data.metrics.map((m) => m.value); - expect(values).toEqual([1000000, 100, [4.1, 2.1, 0.1], 4000, 8000, 400]); + expect(values).toEqual([1000000, 100, 400, [4.1, 2.1, 0.1], 1, 4000]); + }); + + test('adds meta details to Load, Delay and Response time', async () => { + const data = await loadStatus({ http, notifications }); + const metricNames = data.metrics.filter((met) => met.meta); + expect(metricNames.map((item) => item.name)).toEqual(['Load', 'Delay', 'Response time avg']); + expect(metricNames.map((item) => item.meta!.description)).toEqual([ + 'Load interval', + 'Percentiles', + 'Response time max', + ]); }); }); diff --git a/src/core/public/core_app/status/lib/load_status.ts b/src/core/public/core_app/status/lib/load_status.ts index 31f20bf5c4edf..2d81d51128926 100644 --- a/src/core/public/core_app/status/lib/load_status.ts +++ b/src/core/public/core_app/status/lib/load_status.ts @@ -13,10 +13,17 @@ import type { HttpSetup } from '../../../http'; import type { NotificationsSetup } from '../../../notifications'; import type { DataType } from '../lib'; +interface MetricMeta { + title: string; + description: string; + value?: number[]; + type?: DataType; +} export interface Metric { name: string; value: number | number[]; type?: DataType; + meta?: MetricMeta; } export interface FormattedStatus { @@ -60,33 +67,62 @@ function formatMetrics({ metrics }: StatusResponse): Metric[] { value: metrics.process.memory.heap.used_in_bytes, type: 'byte', }, + { + name: i18n.translate('core.statusPage.metricsTiles.columns.requestsPerSecHeader', { + defaultMessage: 'Requests per second', + }), + value: (metrics.requests.total * 1000) / metrics.collection_interval_in_millis, + type: 'float', + }, { name: i18n.translate('core.statusPage.metricsTiles.columns.loadHeader', { defaultMessage: 'Load', }), value: [metrics.os.load['1m'], metrics.os.load['5m'], metrics.os.load['15m']], type: 'float', + meta: { + description: i18n.translate('core.statusPage.metricsTiles.columns.load.metaHeader', { + defaultMessage: 'Load interval', + }), + title: Object.keys(metrics.os.load).join('; '), + }, }, { - name: i18n.translate('core.statusPage.metricsTiles.columns.resTimeAvgHeader', { - defaultMessage: 'Response time avg', + name: i18n.translate('core.statusPage.metricsTiles.columns.processDelayHeader', { + defaultMessage: 'Delay', }), - value: metrics.response_times.avg_in_millis, + value: metrics.process.event_loop_delay, type: 'time', + meta: { + description: i18n.translate( + 'core.statusPage.metricsTiles.columns.processDelayDetailsHeader', + { + defaultMessage: 'Percentiles', + } + ), + title: '', + value: [ + metrics.process.event_loop_delay_histogram?.percentiles['50'], + metrics.process.event_loop_delay_histogram?.percentiles['95'], + metrics.process.event_loop_delay_histogram?.percentiles['99'], + ], + type: 'time', + }, }, { - name: i18n.translate('core.statusPage.metricsTiles.columns.resTimeMaxHeader', { - defaultMessage: 'Response time max', + name: i18n.translate('core.statusPage.metricsTiles.columns.resTimeAvgHeader', { + defaultMessage: 'Response time avg', }), - value: metrics.response_times.max_in_millis, + value: metrics.response_times.avg_in_millis, type: 'time', - }, - { - name: i18n.translate('core.statusPage.metricsTiles.columns.requestsPerSecHeader', { - defaultMessage: 'Requests per second', - }), - value: (metrics.requests.total * 1000) / metrics.collection_interval_in_millis, - type: 'float', + meta: { + description: i18n.translate('core.statusPage.metricsTiles.columns.resTimeMaxHeader', { + defaultMessage: 'Response time max', + }), + title: '', + value: [metrics.response_times.max_in_millis], + type: 'time', + }, }, ]; } diff --git a/src/core/public/core_app/styles/_globals_v8dark.scss b/src/core/public/core_app/styles/_globals_v8dark.scss index ce0eeea02eb3b..df9f1a7493473 100644 --- a/src/core/public/core_app/styles/_globals_v8dark.scss +++ b/src/core/public/core_app/styles/_globals_v8dark.scss @@ -2,8 +2,8 @@ // // prepended to all .scss imports (from JS, when v8dark theme selected) -@import '@elastic/eui/src/themes/eui-amsterdam/eui_amsterdam_colors_dark'; -@import '@elastic/eui/src/themes/eui-amsterdam/eui_amsterdam_globals'; +@import '@elastic/eui/src/themes/amsterdam/colors_dark'; +@import '@elastic/eui/src/themes/amsterdam/globals'; @import './mixins'; diff --git a/src/core/public/core_app/styles/_globals_v8light.scss b/src/core/public/core_app/styles/_globals_v8light.scss index 1ec76902f6589..07312b9cf08bf 100644 --- a/src/core/public/core_app/styles/_globals_v8light.scss +++ b/src/core/public/core_app/styles/_globals_v8light.scss @@ -2,8 +2,8 @@ // // prepended to all .scss imports (from JS, when v8light theme selected) -@import '@elastic/eui/src/themes/eui-amsterdam/eui_amsterdam_colors_light'; -@import '@elastic/eui/src/themes/eui-amsterdam/eui_amsterdam_globals'; +@import '@elastic/eui/src/themes/amsterdam/colors_light'; +@import '@elastic/eui/src/themes/amsterdam/globals'; @import './mixins'; diff --git a/src/core/public/doc_links/doc_links_service.ts b/src/core/public/doc_links/doc_links_service.ts index fed3aa3093166..07a7d80ffdec0 100644 --- a/src/core/public/doc_links/doc_links_service.ts +++ b/src/core/public/doc_links/doc_links_service.ts @@ -57,6 +57,9 @@ export class DocLinksService { cloud: { indexManagement: `${ELASTIC_WEBSITE_URL}/guide/en/cloud/current/ec-configure-index-management.html`, }, + console: { + guide: `${KIBANA_DOCS}console-kibana.html`, + }, dashboard: { guide: `${KIBANA_DOCS}dashboard.html`, drilldowns: `${KIBANA_DOCS}drilldowns.html`, @@ -562,7 +565,7 @@ export class DocLinksService { upgradeElasticAgent712lower: `${FLEET_DOCS}upgrade-elastic-agent.html#upgrade-7.12-lower`, learnMoreBlog: `${ELASTIC_WEBSITE_URL}blog/elastic-agent-and-fleet-make-it-easier-to-integrate-your-systems-with-elastic`, apiKeysLearnMore: `${KIBANA_DOCS}api-keys.html`, - onPremRegistry: `${ELASTIC_WEBSITE_URL}guide/en/integrations-developer/${DOC_LINK_VERSION}/air-gapped.html`, + onPremRegistry: `${FLEET_DOCS}air-gapped.html`, }, ecs: { guide: `${ELASTIC_WEBSITE_URL}guide/en/ecs/current/index.html`, @@ -612,6 +615,9 @@ export interface DocLinksStart { readonly cloud: { readonly indexManagement: string; }; + readonly console: { + readonly guide: string; + }; readonly dashboard: { readonly guide: string; readonly drilldowns: string; diff --git a/src/core/public/i18n/__snapshots__/i18n_service.test.tsx.snap b/src/core/public/i18n/__snapshots__/i18n_service.test.tsx.snap index 1c394112a404c..d4a3bd3a7ea74 100644 --- a/src/core/public/i18n/__snapshots__/i18n_service.test.tsx.snap +++ b/src/core/public/i18n/__snapshots__/i18n_service.test.tsx.snap @@ -7,6 +7,9 @@ exports[`#start() returns \`Context\` component 1`] = ` Object { "mapping": Object { "euiAccordion.isLoading": "Loading", + "euiAutoRefresh.autoRefreshLabel": "Auto refresh", + "euiAutoRefresh.buttonLabelOff": "Auto refresh is off", + "euiAutoRefresh.buttonLabelOn": [Function], "euiBasicTable.noItemsMessage": "No items found", "euiBasicTable.selectAllRows": "Select all rows", "euiBasicTable.selectThisRow": "Select this row", @@ -98,6 +101,17 @@ exports[`#start() returns \`Context\` component 1`] = ` "euiDataGridToolbar.fullScreenButtonActive": "Exit full screen", "euiDatePopoverButton.invalidTitle": [Function], "euiDatePopoverButton.outdatedTitle": [Function], + "euiDisplaySelector.buttonText": "Display options", + "euiDisplaySelector.densityLabel": "Density", + "euiDisplaySelector.labelAuto": "Auto fit", + "euiDisplaySelector.labelCompact": "Compact", + "euiDisplaySelector.labelCustom": "Custom", + "euiDisplaySelector.labelExpanded": "Expanded", + "euiDisplaySelector.labelNormal": "Normal", + "euiDisplaySelector.labelSingle": "Single", + "euiDisplaySelector.lineCountLabel": "Lines per row", + "euiDisplaySelector.resetButtonText": "Reset to default", + "euiDisplaySelector.rowHeightLabel": "Row height", "euiErrorBoundary.error": "Error", "euiFieldPassword.maskPassword": "Mask password", "euiFieldPassword.showPassword": "Show password as plain text. Note: this will visually expose your password on the screen.", @@ -145,15 +159,20 @@ exports[`#start() returns \`Context\` component 1`] = ` "euiNotificationEventReadIcon.readAria": [Function], "euiNotificationEventReadIcon.unread": "Unread", "euiNotificationEventReadIcon.unreadAria": [Function], - "euiPagination.disabledNextPage": "Next page", - "euiPagination.disabledPreviousPage": "Previous page", + "euiPagination.collection": "collection", "euiPagination.firstRangeAriaLabel": [Function], + "euiPagination.fromEndLabel": "from end", + "euiPagination.last": "Last", "euiPagination.lastRangeAriaLabel": [Function], - "euiPagination.nextPage": [Function], + "euiPagination.of": "of", + "euiPagination.page": "Page", "euiPagination.pageOfTotalCompressed": [Function], - "euiPagination.previousPage": [Function], "euiPaginationButton.longPageString": [Function], "euiPaginationButton.shortPageString": [Function], + "euiPaginationButtonArrow.firstPage": "First page", + "euiPaginationButtonArrow.lastPage": "Last page", + "euiPaginationButtonArrow.nextPage": "Next page", + "euiPaginationButtonArrow.previousPage": "Previous page", "euiPinnableListGroup.pinExtraActionLabel": "Pin item", "euiPinnableListGroup.pinnedExtraActionLabel": "Unpin item", "euiPopover.screenReaderAnnouncement": "You are in a dialog. To close this dialog, hit escape.", @@ -168,10 +187,9 @@ exports[`#start() returns \`Context\` component 1`] = ` "euiQuickSelect.unitLabel": "Time unit", "euiQuickSelect.valueLabel": "Time value", "euiRecentlyUsed.legend": "Recently used date ranges", - "euiRefreshInterval.fullDescription": [Function], + "euiRefreshInterval.fullDescriptionOff": [Function], + "euiRefreshInterval.fullDescriptionOn": [Function], "euiRefreshInterval.legend": "Refresh every", - "euiRefreshInterval.start": "Start", - "euiRefreshInterval.stop": "Stop", "euiRelativeTab.dateInputError": "Must be a valid range", "euiRelativeTab.fullDescription": [Function], "euiRelativeTab.numberInputError": "Must be >= 0", @@ -213,12 +231,6 @@ exports[`#start() returns \`Context\` component 1`] = ` "euiStepStrings.simpleWarning": [Function], "euiStepStrings.step": [Function], "euiStepStrings.warning": [Function], - "euiStyleSelector.buttonLegend": "Select the display density for the data grid", - "euiStyleSelector.buttonText": "Density", - "euiStyleSelector.labelCompact": "Compact density", - "euiStyleSelector.labelExpanded": "Expanded density", - "euiStyleSelector.labelNormal": "Normal density", - "euiSuperDatePicker.showDatesButtonLabel": "Show dates", "euiSuperSelect.screenReaderAnnouncement": "You are in a form selector and must select a single option. Use the up and down keys to navigate or escape to close.", "euiSuperSelectControl.selectAnOption": [Function], "euiSuperUpdateButton.cannotUpdateTooltip": "Cannot update", diff --git a/src/core/public/i18n/i18n_eui_mapping.tsx b/src/core/public/i18n/i18n_eui_mapping.tsx index e3357d138e794..4603a2074c4d9 100644 --- a/src/core/public/i18n/i18n_eui_mapping.tsx +++ b/src/core/public/i18n/i18n_eui_mapping.tsx @@ -20,6 +20,17 @@ export const getEuiContextMapping = (): EuiTokensObject => { 'euiAccordion.isLoading': i18n.translate('core.euiAccordion.isLoading', { defaultMessage: 'Loading', }), + 'euiAutoRefresh.autoRefreshLabel': i18n.translate('core.euiAutoRefresh.autoRefreshLabel', { + defaultMessage: 'Auto refresh', + }), + 'euiAutoRefresh.buttonLabelOff': i18n.translate('core.euiAutoRefresh.buttonLabelOff', { + defaultMessage: 'Auto refresh is off', + }), + 'euiAutoRefresh.buttonLabelOn': ({ prettyInterval }: EuiValues) => + i18n.translate('core.euiAutoRefresh.buttonLabelOn', { + defaultMessage: 'Auto refresh is on and set to {prettyInterval}', + values: { prettyInterval }, + }), 'euiBasicTable.selectAllRows': i18n.translate('core.euiBasicTable.selectAllRows', { defaultMessage: 'Select all rows', description: 'ARIA and displayed label on a checkbox to select all table rows', @@ -495,6 +506,42 @@ export const getEuiContextMapping = (): EuiTokensObject => { defaultMessage: 'Update needed: {title}', values: { title }, }), + 'euiDisplaySelector.buttonText': i18n.translate('core.euiDisplaySelector.buttonText', { + defaultMessage: 'Display options', + }), + 'euiDisplaySelector.resetButtonText': i18n.translate( + 'core.euiDisplaySelector.resetButtonText', + { + defaultMessage: 'Reset to default', + } + ), + 'euiDisplaySelector.densityLabel': i18n.translate('core.euiDisplaySelector.densityLabel', { + defaultMessage: 'Density', + }), + 'euiDisplaySelector.labelCompact': i18n.translate('core.euiDisplaySelector.labelCompact', { + defaultMessage: 'Compact', + }), + 'euiDisplaySelector.labelNormal': i18n.translate('core.euiDisplaySelector.labelNormal', { + defaultMessage: 'Normal', + }), + 'euiDisplaySelector.labelExpanded': i18n.translate('core.euiDisplaySelector.labelExpanded', { + defaultMessage: 'Expanded', + }), + 'euiDisplaySelector.labelSingle': i18n.translate('core.euiDisplaySelector.labelSingle', { + defaultMessage: 'Single', + }), + 'euiDisplaySelector.labelAuto': i18n.translate('core.euiDisplaySelector.labelAuto', { + defaultMessage: 'Auto fit', + }), + 'euiDisplaySelector.labelCustom': i18n.translate('core.euiDisplaySelector.labelCustom', { + defaultMessage: 'Custom', + }), + 'euiDisplaySelector.rowHeightLabel': i18n.translate('core.euiDisplaySelector.rowHeightLabel', { + defaultMessage: 'Row height', + }), + 'euiDisplaySelector.lineCountLabel': i18n.translate('core.euiDisplaySelector.lineCountLabel', { + defaultMessage: 'Lines per row', + }), 'euiFieldPassword.showPassword': i18n.translate('core.euiFieldPassword.showPassword', { defaultMessage: 'Show password as plain text. Note: this will visually expose your password on the screen.', @@ -708,11 +755,6 @@ export const getEuiContextMapping = (): EuiTokensObject => { defaultMessage: 'hide', } ), - 'euiPagination.nextPage': ({ page }: EuiValues) => - i18n.translate('core.euiPagination.nextPage', { - defaultMessage: 'Next page, {page}', - values: { page }, - }), 'euiPagination.pageOfTotalCompressed': ({ page, total }: EuiValues) => ( { values={{ page, total }} /> ), - 'euiPagination.previousPage': ({ page }: EuiValues) => - i18n.translate('core.euiPagination.previousPage', { - defaultMessage: 'Previous page, {page}', - values: { page }, - }), - 'euiPagination.disabledPreviousPage': i18n.translate( - 'core.euiPagination.disabledPreviousPage', - { - defaultMessage: 'Previous page', - } - ), - 'euiPagination.disabledNextPage': i18n.translate('core.euiPagination.disabledNextPage', { - defaultMessage: 'Next page', - }), 'euiPagination.firstRangeAriaLabel': ({ lastPage }: EuiValues) => i18n.translate('core.euiPagination.firstRangeAriaLabel', { defaultMessage: 'Skipping pages 2 to {lastPage}', @@ -744,6 +772,21 @@ export const getEuiContextMapping = (): EuiTokensObject => { defaultMessage: 'Skipping pages {firstPage} to {lastPage}', values: { firstPage, lastPage }, }), + 'euiPagination.last': i18n.translate('core.euiPagination.last', { + defaultMessage: 'Last', + }), + 'euiPagination.page': i18n.translate('core.euiPagination.page', { + defaultMessage: 'Page', + }), + 'euiPagination.of': i18n.translate('core.euiPagination.of', { + defaultMessage: 'of', + }), + 'euiPagination.collection': i18n.translate('core.euiPagination.collection', { + defaultMessage: 'collection', + }), + 'euiPagination.fromEndLabel': i18n.translate('core.euiPagination.fromEndLabel', { + defaultMessage: 'from end', + }), 'euiPaginationButton.longPageString': ({ page, totalPages }: EuiValues) => i18n.translate('core.euiPaginationButton.longPageString', { defaultMessage: 'Page {page} of {totalPages}', @@ -756,6 +799,24 @@ export const getEuiContextMapping = (): EuiTokensObject => { values: { page }, description: 'Text to describe the current page of a paginated section', }), + 'euiPaginationButtonArrow.nextPage': i18n.translate('core.euiPaginationButtonArrow.nextPage', { + defaultMessage: 'Next page', + }), + 'euiPaginationButtonArrow.previousPage': i18n.translate( + 'core.euiPaginationButtonArrow.previousPage', + { + defaultMessage: 'Previous page', + } + ), + 'euiPaginationButtonArrow.firstPage': i18n.translate( + 'core.euiPaginationButtonArrow.firstPage', + { + defaultMessage: 'First page', + } + ), + 'euiPaginationButtonArrow.lastPage': i18n.translate('core.euiPaginationButtonArrow.lastPage', { + defaultMessage: 'Last page', + }), 'euiPinnableListGroup.pinExtraActionLabel': i18n.translate( 'core.euiPinnableListGroup.pinExtraActionLabel', { @@ -811,20 +872,19 @@ export const getEuiContextMapping = (): EuiTokensObject => { 'euiRecentlyUsed.legend': i18n.translate('core.euiRecentlyUsed.legend', { defaultMessage: 'Recently used date ranges', }), - 'euiRefreshInterval.fullDescription': ({ optionValue, optionText }: EuiValues) => - i18n.translate('core.euiRefreshInterval.fullDescription', { - defaultMessage: 'Refresh interval currently set to {optionValue} {optionText}.', - values: { optionValue, optionText }, - }), 'euiRefreshInterval.legend': i18n.translate('core.euiRefreshInterval.legend', { defaultMessage: 'Refresh every', }), - 'euiRefreshInterval.start': i18n.translate('core.euiRefreshInterval.start', { - defaultMessage: 'Start', - }), - 'euiRefreshInterval.stop': i18n.translate('core.euiRefreshInterval.stop', { - defaultMessage: 'Stop', - }), + 'euiRefreshInterval.fullDescriptionOff': ({ optionValue, optionText }: EuiValues) => + i18n.translate('core.euiRefreshInterval.fullDescriptionOff', { + defaultMessage: 'Refresh is off, interval set to {optionValue} {optionText}.', + values: { optionValue, optionText }, + }), + 'euiRefreshInterval.fullDescriptionOn': ({ optionValue, optionText }: EuiValues) => + i18n.translate('core.euiRefreshInterval.fullDescriptionOn', { + defaultMessage: 'Refresh is on, interval set to {optionValue} {optionText}.', + values: { optionValue, optionText }, + }), 'euiRelativeTab.fullDescription': ({ unit }: EuiValues) => i18n.translate('core.euiRelativeTab.fullDescription', { defaultMessage: 'The unit is changeable. Currently set to {unit}.', @@ -1028,28 +1088,6 @@ export const getEuiContextMapping = (): EuiTokensObject => { defaultMessage: 'Step {number} is loading', values: { number }, }), - 'euiStyleSelector.buttonText': i18n.translate('core.euiStyleSelector.buttonText', { - defaultMessage: 'Density', - }), - 'euiStyleSelector.buttonLegend': i18n.translate('core.euiStyleSelector.buttonLegend', { - defaultMessage: 'Select the display density for the data grid', - }), - 'euiStyleSelector.labelExpanded': i18n.translate('core.euiStyleSelector.labelExpanded', { - defaultMessage: 'Expanded density', - }), - 'euiStyleSelector.labelNormal': i18n.translate('core.euiStyleSelector.labelNormal', { - defaultMessage: 'Normal density', - }), - 'euiStyleSelector.labelCompact': i18n.translate('core.euiStyleSelector.labelCompact', { - defaultMessage: 'Compact density', - }), - 'euiSuperDatePicker.showDatesButtonLabel': i18n.translate( - 'core.euiSuperDatePicker.showDatesButtonLabel', - { - defaultMessage: 'Show dates', - description: 'Displayed in a button that shows date picker', - } - ), 'euiSuperSelect.screenReaderAnnouncement': i18n.translate( 'core.euiSuperSelect.screenReaderAnnouncement', { diff --git a/src/core/public/public.api.md b/src/core/public/public.api.md index 63e0898b5fb90..458e03fbd734e 100644 --- a/src/core/public/public.api.md +++ b/src/core/public/public.api.md @@ -510,6 +510,9 @@ export interface DocLinksStart { readonly cloud: { readonly indexManagement: string; }; + readonly console: { + readonly guide: string; + }; readonly dashboard: { readonly guide: string; readonly drilldowns: string; diff --git a/src/core/public/theme/convert_core_theme.ts b/src/core/public/theme/convert_core_theme.ts index 78acef40764b6..e0251de1d31be 100644 --- a/src/core/public/theme/convert_core_theme.ts +++ b/src/core/public/theme/convert_core_theme.ts @@ -6,12 +6,13 @@ * Side Public License, v 1. */ -import type { EuiThemeSystem, EuiThemeColorMode } from '@elastic/eui'; +import { COLOR_MODES_STANDARD } from '@elastic/eui'; +import type { EuiThemeSystem, EuiThemeColorModeStandard } from '@elastic/eui'; import type { CoreTheme } from './types'; /** @internal */ export interface EuiTheme { - colorMode: EuiThemeColorMode; + colorMode: EuiThemeColorModeStandard; euiThemeSystem?: EuiThemeSystem; } @@ -19,6 +20,6 @@ export interface EuiTheme { export const convertCoreTheme = (coreTheme: CoreTheme): EuiTheme => { const { darkMode } = coreTheme; return { - colorMode: darkMode ? 'DARK' : 'LIGHT', + colorMode: darkMode ? COLOR_MODES_STANDARD.dark : COLOR_MODES_STANDARD.light, }; }; diff --git a/src/core/public/theme/core_theme_provider.test.tsx b/src/core/public/theme/core_theme_provider.test.tsx index baa354f10f428..a0f0faf13b9da 100644 --- a/src/core/public/theme/core_theme_provider.test.tsx +++ b/src/core/public/theme/core_theme_provider.test.tsx @@ -11,12 +11,13 @@ import { act } from 'react-dom/test-utils'; import type { ReactWrapper } from 'enzyme'; import { of, BehaviorSubject } from 'rxjs'; import { useEuiTheme } from '@elastic/eui'; +import type { UseEuiTheme } from '@elastic/eui'; import { mountWithIntl } from '@kbn/test/jest'; import { CoreThemeProvider } from './core_theme_provider'; import type { CoreTheme } from './types'; describe('CoreThemeProvider', () => { - let euiTheme: ReturnType | undefined; + let euiTheme: UseEuiTheme | undefined; beforeEach(() => { euiTheme = undefined; diff --git a/src/core/public/theme/core_theme_provider.tsx b/src/core/public/theme/core_theme_provider.tsx index 9f40cbd5393b8..ee6ecbea836b5 100644 --- a/src/core/public/theme/core_theme_provider.tsx +++ b/src/core/public/theme/core_theme_provider.tsx @@ -9,7 +9,9 @@ import React, { FC, useMemo } from 'react'; import { Observable } from 'rxjs'; import useObservable from 'react-use/lib/useObservable'; -import { EuiThemeProvider } from '@elastic/eui'; +import createCache from '@emotion/cache'; +import { EuiProvider } from '@elastic/eui'; +import { EUI_STYLES_GLOBAL } from '../../utils'; import { CoreTheme } from './types'; import { convertCoreTheme } from './convert_core_theme'; @@ -21,16 +23,25 @@ interface CoreThemeProviderProps { theme$: Observable; } +const emotionCache = createCache({ + key: 'eui-styles', + container: document.querySelector(`meta[name="${EUI_STYLES_GLOBAL}"]`) as HTMLElement, +}); + /** - * Wrapper around `EuiThemeProvider` converting (and exposing) core's theme to EUI theme. + * Wrapper around `EuiProvider` converting (and exposing) core's theme to EUI theme. * @internal Only meant to be used within core for internal usages of EUI/React */ export const CoreThemeProvider: FC = ({ theme$, children }) => { const coreTheme = useObservable(theme$, defaultTheme); const euiTheme = useMemo(() => convertCoreTheme(coreTheme), [coreTheme]); return ( - + {children} - + ); }; diff --git a/src/core/server/http/cookie_session_storage.test.ts b/src/core/server/http/integration_tests/cookie_session_storage.test.ts similarity index 88% rename from src/core/server/http/cookie_session_storage.test.ts rename to src/core/server/http/integration_tests/cookie_session_storage.test.ts index 8e2cd58733faf..61da92a8ffdbd 100644 --- a/src/core/server/http/cookie_session_storage.test.ts +++ b/src/core/server/http/integration_tests/cookie_session_storage.test.ts @@ -11,18 +11,20 @@ import supertest from 'supertest'; import { REPO_ROOT } from '@kbn/utils'; import { ByteSizeValue } from '@kbn/config-schema'; import { BehaviorSubject } from 'rxjs'; +import { duration as momentDuration } from 'moment'; -import { CoreContext } from '../core_context'; -import { HttpService } from './http_service'; -import { Env } from '../config'; +import { CoreContext } from '../../core_context'; +import { HttpService } from './../http_service'; +import { Env } from '../../config'; -import { contextServiceMock } from '../context/context_service.mock'; -import { executionContextServiceMock } from '../execution_context/execution_context_service.mock'; -import { loggingSystemMock } from '../logging/logging_system.mock'; -import { getEnvOptions, configServiceMock } from '../config/mocks'; -import { httpServerMock } from './http_server.mocks'; +import { contextServiceMock } from '../../context/context_service.mock'; +import { executionContextServiceMock } from '../../execution_context/execution_context_service.mock'; +import { loggingSystemMock } from '../../logging/logging_system.mock'; +import { getEnvOptions, configServiceMock } from '../../config/mocks'; +import { httpServerMock } from '../http_server.mocks'; -import { createCookieSessionStorageFactory } from './cookie_session_storage'; +import { createCookieSessionStorageFactory } from '../cookie_session_storage'; +import { ensureRawRequest } from '../router'; let server: HttpService; @@ -31,17 +33,23 @@ let env: Env; let coreContext: CoreContext; const configService = configServiceMock.create(); const contextSetup = contextServiceMock.createSetupContract(); +const contextPreboot = contextServiceMock.createPrebootContract(); const setupDeps = { context: contextSetup, executionContext: executionContextServiceMock.createInternalSetupContract(), }; +const prebootDeps = { + context: contextPreboot, +}; + configService.atPath.mockImplementation((path) => { if (path === 'server') { return new BehaviorSubject({ hosts: ['http://1.2.3.4'], maxPayload: new ByteSizeValue(1024), + shutdownTimeout: momentDuration('5s'), autoListen: true, healthCheck: { delay: 2000, @@ -55,6 +63,7 @@ configService.atPath.mockImplementation((path) => { allowlist: [], }, customResponseHeaders: {}, + securityResponseHeaders: {}, requestId: { allowFromAnyIp: true, ipAllowlist: [], @@ -79,18 +88,6 @@ configService.atPath.mockImplementation((path) => { throw new Error(`Unexpected config path: ${path}`); }); -beforeEach(() => { - logger = loggingSystemMock.create(); - env = Env.createDefault(REPO_ROOT, getEnvOptions()); - - coreContext = { coreId: Symbol(), env, logger, configService: configService as any }; - server = new HttpService(coreContext); -}); - -afterEach(async () => { - await server.stop(); -}); - interface User { id: string; roles?: string[]; @@ -129,11 +126,22 @@ const cookieOptions = { path, }; -// FLAKY: https://github.com/elastic/kibana/issues/89318 -// https://github.com/elastic/kibana/issues/89319 -describe.skip('Cookie based SessionStorage', () => { +describe('Cookie based SessionStorage', () => { + beforeEach(async () => { + logger = loggingSystemMock.create(); + env = Env.createDefault(REPO_ROOT, getEnvOptions()); + + coreContext = { coreId: Symbol(), env, logger, configService: configService as any }; + server = new HttpService(coreContext); + }); + + afterEach(async () => { + await server.stop(); + }); + describe('#set()', () => { it('Should write to session storage & set cookies', async () => { + await server.preboot(prebootDeps); const { server: innerServer, createRouter } = await server.setup(setupDeps); const router = createRouter(''); @@ -167,6 +175,7 @@ describe.skip('Cookie based SessionStorage', () => { describe('#get()', () => { it('reads from session storage', async () => { + await server.preboot(prebootDeps); const { server: innerServer, createRouter } = await server.setup(setupDeps); const router = createRouter(''); @@ -202,6 +211,7 @@ describe.skip('Cookie based SessionStorage', () => { }); it('returns null for empty session', async () => { + await server.preboot(prebootDeps); const { server: innerServer, createRouter } = await server.setup(setupDeps); const router = createRouter(''); @@ -225,6 +235,7 @@ describe.skip('Cookie based SessionStorage', () => { }); it('returns null for invalid session (expired) & clean cookies', async () => { + await server.preboot(prebootDeps); const { server: innerServer, createRouter } = await server.setup(setupDeps); const router = createRouter(''); @@ -270,6 +281,7 @@ describe.skip('Cookie based SessionStorage', () => { }); it('returns null for invalid session (incorrect path) & clean cookies accurately', async () => { + await server.preboot(prebootDeps); const { server: innerServer, createRouter } = await server.setup(setupDeps); const router = createRouter(''); @@ -337,7 +349,10 @@ describe.skip('Cookie based SessionStorage', () => { expect(session).toBe(null); expect(mockServer.auth.test).toBeCalledTimes(1); - expect(mockServer.auth.test).toHaveBeenCalledWith('security-cookie', mockRequest); + expect(mockServer.auth.test).toHaveBeenCalledWith( + 'security-cookie', + ensureRawRequest(mockRequest) + ); expect(loggingSystemMock.collect(logger).warn).toEqual([ ['Found 2 auth sessions when we were only expecting 1.'], @@ -368,7 +383,10 @@ describe.skip('Cookie based SessionStorage', () => { expect(session).toBe('foo'); expect(mockServer.auth.test).toBeCalledTimes(1); - expect(mockServer.auth.test).toHaveBeenCalledWith('security-cookie', mockRequest); + expect(mockServer.auth.test).toHaveBeenCalledWith( + 'security-cookie', + ensureRawRequest(mockRequest) + ); }); it('logs the reason of validation function failure.', async () => { @@ -402,6 +420,7 @@ describe.skip('Cookie based SessionStorage', () => { describe('#clear()', () => { it('clears session storage & remove cookies', async () => { + await server.preboot(prebootDeps); const { server: innerServer, createRouter } = await server.setup(setupDeps); const router = createRouter(''); @@ -443,6 +462,7 @@ describe.skip('Cookie based SessionStorage', () => { describe('#options', () => { describe('#SameSite', () => { it('throws an exception if "SameSite: None" set on not Secure connection', async () => { + await server.preboot(prebootDeps); const { server: innerServer } = await server.setup(setupDeps); expect( @@ -457,6 +477,7 @@ describe.skip('Cookie based SessionStorage', () => { for (const sameSite of ['Strict', 'Lax', 'None'] as const) { it(`sets and parses SameSite = ${sameSite} correctly`, async () => { + await server.preboot(prebootDeps); const { server: innerServer, createRouter } = await server.setup(setupDeps); const router = createRouter(''); @@ -485,7 +506,7 @@ describe.skip('Cookie based SessionStorage', () => { expect(cookies).toHaveLength(1); const sessionCookie = retrieveSessionCookie(cookies[0]); - expect(sessionCookie.extensions).toContain(`SameSite=${sameSite}`); + expect(sessionCookie.sameSite).toEqual(sameSite.toLowerCase()); await supertest(innerServer.listener) .get('/') diff --git a/src/core/server/rendering/views/styles.tsx b/src/core/server/rendering/views/styles.tsx index fbeab4fb4388f..9830cac55e9eb 100644 --- a/src/core/server/rendering/views/styles.tsx +++ b/src/core/server/rendering/views/styles.tsx @@ -50,6 +50,10 @@ const InlineStyles: FC<{ darkMode: boolean }> = ({ darkMode }) => { display: block; } + html { + background-color: ${darkMode ? '#141519' : '#F8FAFD'} + } + .kbnWelcomeView { line-height: 1.5; height: 100%; diff --git a/src/core/server/rendering/views/template.tsx b/src/core/server/rendering/views/template.tsx index 971a9e22e4fcc..47d9c98318c88 100644 --- a/src/core/server/rendering/views/template.tsx +++ b/src/core/server/rendering/views/template.tsx @@ -8,6 +8,7 @@ import React, { FunctionComponent, createElement } from 'react'; +import { EUI_STYLES_GLOBAL } from '../../../utils'; import { RenderingMetadata } from '../types'; import { Fonts } from './fonts'; import { Styles } from './styles'; @@ -42,6 +43,8 @@ export const Template: FunctionComponent = ({ + {/* Inject EUI reset and global styles before all other component styles */} + {/* Inject stylesheets into the before scripts so that KP plugins with bundled styles will override them */} diff --git a/src/core/utils/index.ts b/src/core/utils/index.ts index 73980983a12e1..82b636685a4d4 100644 --- a/src/core/utils/index.ts +++ b/src/core/utils/index.ts @@ -8,3 +8,4 @@ export { DEFAULT_APP_CATEGORIES } from './default_app_categories'; export { APP_WRAPPER_CLASS } from './app_wrapper_class'; +export { EUI_STYLES_GLOBAL } from './meta'; diff --git a/src/core/utils/meta.ts b/src/core/utils/meta.ts new file mode 100644 index 0000000000000..7d5e8b8ee63f9 --- /dev/null +++ b/src/core/utils/meta.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 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 EUI_STYLES_GLOBAL = 'eui-styles-global'; diff --git a/src/dev/build/args.test.ts b/src/dev/build/args.test.ts index 354de9fee60d7..5601e063414b3 100644 --- a/src/dev/build/args.test.ts +++ b/src/dev/build/args.test.ts @@ -28,10 +28,10 @@ it('build default and oss dist for current platform, without packages, by defaul "buildOptions": Object { "createArchives": true, "createDebPackage": false, - "createDockerCentOS": false, "createDockerCloud": false, "createDockerContexts": true, "createDockerUBI": false, + "createDockerUbuntu": false, "createExamplePlugins": false, "createGenericFolders": true, "createPlatformFolders": true, @@ -58,10 +58,10 @@ it('builds packages if --all-platforms is passed', () => { "buildOptions": Object { "createArchives": true, "createDebPackage": true, - "createDockerCentOS": true, "createDockerCloud": true, "createDockerContexts": true, "createDockerUBI": true, + "createDockerUbuntu": true, "createExamplePlugins": false, "createGenericFolders": true, "createPlatformFolders": true, @@ -88,10 +88,10 @@ it('limits packages if --rpm passed with --all-platforms', () => { "buildOptions": Object { "createArchives": true, "createDebPackage": false, - "createDockerCentOS": false, "createDockerCloud": false, "createDockerContexts": true, "createDockerUBI": false, + "createDockerUbuntu": false, "createExamplePlugins": false, "createGenericFolders": true, "createPlatformFolders": true, @@ -118,10 +118,10 @@ it('limits packages if --deb passed with --all-platforms', () => { "buildOptions": Object { "createArchives": true, "createDebPackage": true, - "createDockerCentOS": false, "createDockerCloud": false, "createDockerContexts": true, "createDockerUBI": false, + "createDockerUbuntu": false, "createExamplePlugins": false, "createGenericFolders": true, "createPlatformFolders": true, @@ -149,10 +149,10 @@ it('limits packages if --docker passed with --all-platforms', () => { "buildOptions": Object { "createArchives": true, "createDebPackage": false, - "createDockerCentOS": true, "createDockerCloud": true, "createDockerContexts": true, "createDockerUBI": true, + "createDockerUbuntu": true, "createExamplePlugins": false, "createGenericFolders": true, "createPlatformFolders": true, @@ -187,10 +187,10 @@ it('limits packages if --docker passed with --skip-docker-ubi and --all-platform "buildOptions": Object { "createArchives": true, "createDebPackage": false, - "createDockerCentOS": true, "createDockerCloud": true, "createDockerContexts": true, "createDockerUBI": false, + "createDockerUbuntu": true, "createExamplePlugins": false, "createGenericFolders": true, "createPlatformFolders": true, @@ -211,17 +211,17 @@ it('limits packages if --docker passed with --skip-docker-ubi and --all-platform `); }); -it('limits packages if --all-platforms passed with --skip-docker-centos', () => { - expect(readCliArgs(['node', 'scripts/build', '--all-platforms', '--skip-docker-centos'])) +it('limits packages if --all-platforms passed with --skip-docker-ubuntu', () => { + expect(readCliArgs(['node', 'scripts/build', '--all-platforms', '--skip-docker-ubuntu'])) .toMatchInlineSnapshot(` Object { "buildOptions": Object { "createArchives": true, "createDebPackage": true, - "createDockerCentOS": false, "createDockerCloud": true, "createDockerContexts": true, "createDockerUBI": true, + "createDockerUbuntu": false, "createExamplePlugins": false, "createGenericFolders": true, "createPlatformFolders": true, diff --git a/src/dev/build/args.ts b/src/dev/build/args.ts index 78f097b595c40..d890dbef4e74f 100644 --- a/src/dev/build/args.ts +++ b/src/dev/build/args.ts @@ -26,7 +26,7 @@ export function readCliArgs(argv: string[]) { 'docker-push', 'skip-docker-contexts', 'skip-docker-ubi', - 'skip-docker-centos', + 'skip-docker-ubuntu', 'skip-docker-cloud', 'release', 'skip-node-download', @@ -109,8 +109,8 @@ export function readCliArgs(argv: string[]) { createExamplePlugins: Boolean(flags['example-plugins']), createRpmPackage: isOsPackageDesired('rpm'), createDebPackage: isOsPackageDesired('deb'), - createDockerCentOS: - isOsPackageDesired('docker-images') && !Boolean(flags['skip-docker-centos']), + createDockerUbuntu: + isOsPackageDesired('docker-images') && !Boolean(flags['skip-docker-ubuntu']), createDockerCloud: isOsPackageDesired('docker-images') && !Boolean(flags['skip-docker-cloud']), createDockerUBI: isOsPackageDesired('docker-images') && !Boolean(flags['skip-docker-ubi']), createDockerContexts: !Boolean(flags['skip-docker-contexts']), diff --git a/src/dev/build/build_distributables.ts b/src/dev/build/build_distributables.ts index 9e3a419d63964..992486796dfad 100644 --- a/src/dev/build/build_distributables.ts +++ b/src/dev/build/build_distributables.ts @@ -24,7 +24,7 @@ export interface BuildOptions { createRpmPackage: boolean; createDebPackage: boolean; createDockerUBI: boolean; - createDockerCentOS: boolean; + createDockerUbuntu: boolean; createDockerCloud: boolean; createDockerContexts: boolean; versionQualifier: string | undefined; @@ -126,9 +126,9 @@ export async function buildDistributables(log: ToolingLog, options: BuildOptions await run(Tasks.CreateDockerUBI); } - if (options.createDockerCentOS) { - // control w/ --docker-images or --skip-docker-centos or --skip-os-packages - await run(Tasks.CreateDockerCentOS); + if (options.createDockerUbuntu) { + // control w/ --docker-images or --skip-docker-ubuntu or --skip-os-packages + await run(Tasks.CreateDockerUbuntu); } if (options.createDockerCloud) { diff --git a/src/dev/build/cli.ts b/src/dev/build/cli.ts index c727c26d7dcd3..323a40d02de66 100644 --- a/src/dev/build/cli.ts +++ b/src/dev/build/cli.ts @@ -41,7 +41,7 @@ if (showHelp) { --docker-images {dim Only build the Docker images} --docker-contexts {dim Only build the Docker build contexts} --skip-docker-ubi {dim Don't build the docker ubi image} - --skip-docker-centos {dim Don't build the docker centos image} + --skip-docker-ubuntu {dim Don't build the docker ubuntu image} --release {dim Produce a release-ready distributable} --version-qualifier {dim Suffix version with a qualifier} --skip-node-download {dim Reuse existing downloads of node.js} diff --git a/src/dev/build/tasks/os_packages/create_os_package_tasks.ts b/src/dev/build/tasks/os_packages/create_os_package_tasks.ts index ab9a7ce65cbc6..b4724085c5184 100644 --- a/src/dev/build/tasks/os_packages/create_os_package_tasks.ts +++ b/src/dev/build/tasks/os_packages/create_os_package_tasks.ts @@ -59,20 +59,22 @@ export const CreateRpmPackage: Task = { }; const dockerBuildDate = new Date().toISOString(); -export const CreateDockerCentOS: Task = { - description: 'Creating Docker CentOS image', +export const CreateDockerUbuntu: Task = { + description: 'Creating Docker Ubuntu image', async run(config, log, build) { await runDockerGenerator(config, log, build, { architecture: 'x64', context: false, image: true, + ubuntu: true, dockerBuildDate, }); await runDockerGenerator(config, log, build, { architecture: 'aarch64', context: false, image: true, + ubuntu: true, dockerBuildDate, }); }, @@ -99,12 +101,14 @@ export const CreateDockerCloud: Task = { architecture: 'x64', context: false, cloud: true, + ubuntu: true, image: true, }); await runDockerGenerator(config, log, build, { architecture: 'aarch64', context: false, cloud: true, + ubuntu: true, image: true, }); }, diff --git a/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker b/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker index a7d8fe684ef95..c46a41eb5c3a0 100755 --- a/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker +++ b/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker @@ -254,6 +254,7 @@ kibana_vars=( xpack.fleet.agents.kibana.host xpack.fleet.agents.tlsCheckDisabled xpack.fleet.packages + xpack.fleet.registryProxyUrl xpack.fleet.registryUrl xpack.graph.canEditDrillDownUrls xpack.graph.savePolicy diff --git a/src/dev/build/tasks/os_packages/docker_generator/run.ts b/src/dev/build/tasks/os_packages/docker_generator/run.ts index 085b4393caa66..657efc8d7bd99 100644 --- a/src/dev/build/tasks/os_packages/docker_generator/run.ts +++ b/src/dev/build/tasks/os_packages/docker_generator/run.ts @@ -32,13 +32,15 @@ export async function runDockerGenerator( context: boolean; image: boolean; ubi?: boolean; + ubuntu?: boolean; ironbank?: boolean; cloud?: boolean; dockerBuildDate?: string; } ) { - // UBI var config - const baseOSImage = flags.ubi ? 'docker.elastic.co/ubi8/ubi-minimal:latest' : 'centos:8'; + let baseOSImage = ''; + if (flags.ubuntu) baseOSImage = 'ubuntu:20.04'; + if (flags.ubi) baseOSImage = 'docker.elastic.co/ubi8/ubi-minimal:latest'; const ubiVersionTag = 'ubi8'; let imageFlavor = ''; @@ -91,6 +93,7 @@ export async function runDockerGenerator( baseOSImage, dockerBuildDate, ubi: flags.ubi, + ubuntu: flags.ubuntu, cloud: flags.cloud, metricbeatTarball, filebeatTarball, diff --git a/src/dev/build/tasks/os_packages/docker_generator/template_context.ts b/src/dev/build/tasks/os_packages/docker_generator/template_context.ts index 143fcf16ace56..a715bfaa5d50d 100644 --- a/src/dev/build/tasks/os_packages/docker_generator/template_context.ts +++ b/src/dev/build/tasks/os_packages/docker_generator/template_context.ts @@ -23,6 +23,7 @@ export interface TemplateContext { dockerBuildDate: string; usePublicArtifact?: boolean; ubi?: boolean; + ubuntu?: boolean; cloud?: boolean; metricbeatTarball?: string; filebeatTarball?: string; diff --git a/src/dev/build/tasks/os_packages/docker_generator/templates/base/Dockerfile b/src/dev/build/tasks/os_packages/docker_generator/templates/base/Dockerfile index 90a622e64efe4..54af1c41b2da9 100644 --- a/src/dev/build/tasks/os_packages/docker_generator/templates/base/Dockerfile +++ b/src/dev/build/tasks/os_packages/docker_generator/templates/base/Dockerfile @@ -14,6 +14,9 @@ FROM {{{baseOSImage}}} AS builder {{#ubi}} RUN {{packageManager}} install -y findutils tar gzip {{/ubi}} +{{#ubuntu}} +RUN {{packageManager}} update && DEBIAN_FRONTEND=noninteractive {{packageManager}} install -y curl +{{/ubuntu}} {{#usePublicArtifact}} RUN cd /tmp && \ @@ -55,18 +58,28 @@ FROM {{{baseOSImage}}} EXPOSE 5601 {{#ubi}} - # https://github.com/rpm-software-management/microdnf/issues/50 - RUN mkdir -p /run/user/$(id -u) -{{/ubi}} - RUN for iter in {1..10}; do \ {{packageManager}} update --setopt=tsflags=nodocs -y && \ {{packageManager}} install --setopt=tsflags=nodocs -y \ - fontconfig freetype shadow-utils nss {{#ubi}}findutils{{/ubi}} && \ + fontconfig freetype shadow-utils nss findutils && \ {{packageManager}} clean all && exit_code=0 && break || exit_code=$? && echo "{{packageManager}} error: retry $iter in 10s" && \ sleep 10; \ done; \ (exit $exit_code) +{{/ubi}} +{{#ubuntu}} +RUN for iter in {1..10}; do \ + export DEBIAN_FRONTEND=noninteractive && \ + {{packageManager}} update && \ + {{packageManager}} upgrade -y && \ + {{packageManager}} install -y --no-install-recommends \ + fontconfig fonts-liberation libnss3 libfontconfig1 ca-certificates curl && \ + {{packageManager}} clean && \ + rm -rf /var/lib/apt/lists/* && exit_code=0 && break || exit_code=$? && echo "{{packageManager}} error: retry $iter in 10s" && \ + sleep 10; \ + done; \ + (exit $exit_code) +{{/ubuntu}} # Add an init process, check the checksum to make sure it's a match RUN set -e ; \ @@ -164,7 +177,7 @@ ENTRYPOINT ["/bin/tini", "--"] CMD ["/app/kibana.sh"] # Generate a stub command that will be overwritten at runtime RUN mkdir /app && \ - echo -e '#!/bin/sh\nexec /usr/local/bin/kibana-docker' > /app/kibana.sh && \ + echo -e '#!/bin/bash\nexec /usr/local/bin/kibana-docker' > /app/kibana.sh && \ chmod 0555 /app/kibana.sh {{/cloud}} diff --git a/src/dev/build/tasks/os_packages/docker_generator/templates/dockerfile.template.ts b/src/dev/build/tasks/os_packages/docker_generator/templates/dockerfile.template.ts index e668299a3acc3..94068f2b64b12 100755 --- a/src/dev/build/tasks/os_packages/docker_generator/templates/dockerfile.template.ts +++ b/src/dev/build/tasks/os_packages/docker_generator/templates/dockerfile.template.ts @@ -16,7 +16,7 @@ function generator(options: TemplateContext) { const dir = options.ironbank ? 'ironbank' : 'base'; const template = readFileSync(resolve(__dirname, dir, './Dockerfile')); return Mustache.render(template.toString(), { - packageManager: options.ubi ? 'microdnf' : 'yum', + packageManager: options.ubi ? 'microdnf' : 'apt-get', ...options, }); } diff --git a/src/dev/license_checker/config.ts b/src/dev/license_checker/config.ts index 9674694c0d655..d1df68685a288 100644 --- a/src/dev/license_checker/config.ts +++ b/src/dev/license_checker/config.ts @@ -76,6 +76,6 @@ export const LICENSE_OVERRIDES = { 'jsts@1.6.2': ['Eclipse Distribution License - v 1.0'], // cf. https://github.com/bjornharrtell/jsts '@mapbox/jsonlint-lines-primitives@2.0.2': ['MIT'], // license in readme https://github.com/tmcw/jsonlint '@elastic/ems-client@8.0.0': ['Elastic License 2.0'], - '@elastic/eui@41.2.3': ['SSPL-1.0 OR Elastic License 2.0'], + '@elastic/eui@43.1.1': ['SSPL-1.0 OR Elastic License 2.0'], 'language-subtag-registry@0.3.21': ['CC-BY-4.0'], // retired ODC‑By license https://github.com/mattcg/language-subtag-registry }; diff --git a/src/plugins/chart_expressions/expression_gauge/public/components/index.scss b/src/plugins/chart_expressions/expression_gauge/public/components/index.scss index a221ba25fcc5c..22a1e4318b5e5 100644 --- a/src/plugins/chart_expressions/expression_gauge/public/components/index.scss +++ b/src/plugins/chart_expressions/expression_gauge/public/components/index.scss @@ -4,7 +4,7 @@ width: 100%; // the FocusTrap is adding extra divs which are making the visualization redraw twice // with a visible glitch. This make the chart library resilient to this extra reflow - overflow: auto hidden; + overflow: hidden; user-select: text; padding: $euiSizeS; -} \ No newline at end of file +} diff --git a/src/plugins/chart_expressions/expression_gauge/public/components/utils.test.ts b/src/plugins/chart_expressions/expression_gauge/public/components/utils.test.ts index d45ff5c11a223..570ed0db986c9 100644 --- a/src/plugins/chart_expressions/expression_gauge/public/components/utils.test.ts +++ b/src/plugins/chart_expressions/expression_gauge/public/components/utils.test.ts @@ -51,7 +51,7 @@ describe('expression gauge utils', () => { expect(getMaxValue({ metric: 10 }, localState)).toEqual(15); expect(getMaxValue({ min: 0, metric: 2 }, localState)).toEqual(4); expect(getMaxValue({ min: -100, metric: 2 }, localState)).toEqual(50); - expect(getMaxValue({ min: -0.001, metric: 0 }, localState)).toEqual(0.001); + expect(getMaxValue({ min: -0.001, metric: 0 }, localState)).toEqual(1); expect(getMaxValue({ min: -2000, metric: -1000 }, localState)).toEqual(-500); expect(getMaxValue({ min: 0.5, metric: 1.5 }, localState)).toEqual(2); }); diff --git a/src/plugins/chart_expressions/expression_gauge/public/components/utils.ts b/src/plugins/chart_expressions/expression_gauge/public/components/utils.ts index a60c4a8a0a608..c2a11515a5b0a 100644 --- a/src/plugins/chart_expressions/expression_gauge/public/components/utils.ts +++ b/src/plugins/chart_expressions/expression_gauge/public/components/utils.ts @@ -40,7 +40,7 @@ function getNiceRange(min: number, max: number) { const tickSpacing = getNiceNumber(range / (maxTicks - 1)); return { min: Math.floor(min / tickSpacing) * tickSpacing, - max: Math.ceil(offsetMax / tickSpacing) * tickSpacing, + max: Math.ceil(Math.ceil(offsetMax / tickSpacing) * tickSpacing), }; } diff --git a/src/plugins/chart_expressions/expression_gauge/public/index.ts b/src/plugins/chart_expressions/expression_gauge/public/index.ts index c01a3a9a42b9b..62e287520b45a 100644 --- a/src/plugins/chart_expressions/expression_gauge/public/index.ts +++ b/src/plugins/chart_expressions/expression_gauge/public/index.ts @@ -12,5 +12,5 @@ export function plugin() { return new ExpressionGaugePlugin(); } -export { getGoalValue, getMaxValue, getMinValue } from './components/utils'; +export { getGoalValue, getMaxValue, getMinValue, getValueFromAccessor } from './components/utils'; export { GaugeIconVertical, GaugeIconHorizontal } from './components/gauge_icon'; diff --git a/src/plugins/console/public/application/components/help_panel.tsx b/src/plugins/console/public/application/components/help_panel.tsx index cdb45f929459d..50238006f6ce2 100644 --- a/src/plugins/console/public/application/components/help_panel.tsx +++ b/src/plugins/console/public/application/components/help_panel.tsx @@ -15,14 +15,18 @@ import { EuiFlyoutBody, EuiTitle, EuiSpacer, + EuiLink, } from '@elastic/eui'; import { EditorExample } from './editor_example'; +import { useServicesContext } from '../contexts'; interface Props { onClose: () => void; } export function HelpPanel(props: Props) { + const { docLinks } = useServicesContext(); + return ( @@ -43,7 +47,25 @@ export function HelpPanel(props: Props) {

+

+

+ + Console + + ), + queryDsl: ( + + Query DSL + + ), + }} />

diff --git a/src/plugins/console/public/application/contexts/services_context.mock.ts b/src/plugins/console/public/application/contexts/services_context.mock.ts index 90a5d9ddce010..0b3e0fb3adec5 100644 --- a/src/plugins/console/public/application/contexts/services_context.mock.ts +++ b/src/plugins/console/public/application/contexts/services_context.mock.ts @@ -8,6 +8,7 @@ import { notificationServiceMock } from '../../../../../core/public/mocks'; import { httpServiceMock, themeServiceMock } from '../../../../../core/public/mocks'; +import { docLinksServiceMock } from '../../../../../core/public/mocks'; import type { ObjectStorageClient } from '../../../common/types'; import { HistoryMock } from '../../services/history.mock'; @@ -36,6 +37,7 @@ export const serviceContextMock = { }, docLinkVersion: 'NA', theme$: themeServiceMock.create().start().theme$, + docLinks: docLinksServiceMock.createStartContract().links, }; }, }; diff --git a/src/plugins/console/public/application/contexts/services_context.tsx b/src/plugins/console/public/application/contexts/services_context.tsx index 5912de0375590..e4aeb2d38104e 100644 --- a/src/plugins/console/public/application/contexts/services_context.tsx +++ b/src/plugins/console/public/application/contexts/services_context.tsx @@ -8,7 +8,7 @@ import React, { createContext, useContext, useEffect } from 'react'; import { Observable } from 'rxjs'; -import { NotificationsSetup, CoreTheme } from 'kibana/public'; +import { NotificationsSetup, CoreTheme, DocLinksStart } from 'kibana/public'; import { History, Settings, Storage } from '../../services'; import { ObjectStorageClient } from '../../../common/types'; @@ -29,6 +29,7 @@ export interface ContextValue { services: ContextServices; docLinkVersion: string; theme$: Observable; + docLinks: DocLinksStart['links']; } interface ContextProps { diff --git a/src/plugins/console/public/application/index.tsx b/src/plugins/console/public/application/index.tsx index 719975874cd44..8e67c2e360369 100644 --- a/src/plugins/console/public/application/index.tsx +++ b/src/plugins/console/public/application/index.tsx @@ -9,7 +9,13 @@ import React from 'react'; import { render, unmountComponentAtNode } from 'react-dom'; import { Observable } from 'rxjs'; -import { HttpSetup, NotificationsSetup, I18nStart, CoreTheme } from 'src/core/public'; +import { + HttpSetup, + NotificationsSetup, + I18nStart, + CoreTheme, + DocLinksStart, +} from 'src/core/public'; import { UsageCollectionSetup } from '../../../usage_collection/public'; import { KibanaThemeProvider } from '../shared_imports'; @@ -28,6 +34,7 @@ export interface BootDependencies { usageCollection?: UsageCollectionSetup; element: HTMLElement; theme$: Observable; + docLinks: DocLinksStart['links']; } export function renderApp({ @@ -38,6 +45,7 @@ export function renderApp({ element, http, theme$, + docLinks, }: BootDependencies) { const trackUiMetric = createUsageTracker(usageCollection); trackUiMetric.load('opened_app'); @@ -58,6 +66,7 @@ export function renderApp({ { expect(timefilter.getRefreshInterval()).toEqual({ pause: true, value: 0 }); }); - test('should set pause to true when interval is zero', () => { + test('should set pause to true when interval is changed to zero from non-zero', () => { + timefilter.setRefreshInterval({ value: 1000, pause: false }); timefilter.setRefreshInterval({ value: 0, pause: false }); expect(timefilter.getRefreshInterval()).toEqual({ pause: true, value: 0 }); }); diff --git a/src/plugins/data/public/query/timefilter/timefilter.ts b/src/plugins/data/public/query/timefilter/timefilter.ts index e13e8b17a7f43..d289a90149fdd 100644 --- a/src/plugins/data/public/query/timefilter/timefilter.ts +++ b/src/plugins/data/public/query/timefilter/timefilter.ts @@ -151,10 +151,16 @@ export class Timefilter { public setRefreshInterval = (refreshInterval: Partial) => { const prevRefreshInterval = this.getRefreshInterval(); const newRefreshInterval = { ...prevRefreshInterval, ...refreshInterval }; + let shouldUnpauseRefreshLoop = + newRefreshInterval.pause === false && prevRefreshInterval != null; + if (prevRefreshInterval?.value > 0 && newRefreshInterval.value <= 0) { + shouldUnpauseRefreshLoop = false; + } // If the refresh interval is <= 0 handle that as a paused refresh + // unless the user has un-paused the refresh loop and the value is not going from > 0 to 0 if (newRefreshInterval.value <= 0) { newRefreshInterval.value = 0; - newRefreshInterval.pause = true; + newRefreshInterval.pause = shouldUnpauseRefreshLoop ? false : true; } this._refreshInterval = { value: newRefreshInterval.value, diff --git a/src/plugins/data/public/ui/query_string_input/query_bar_top_row.tsx b/src/plugins/data/public/ui/query_string_input/query_bar_top_row.tsx index a5f59b976d3ba..76d4b9dd8e801 100644 --- a/src/plugins/data/public/ui/query_string_input/query_bar_top_row.tsx +++ b/src/plugins/data/public/ui/query_string_input/query_bar_top_row.tsx @@ -32,33 +32,34 @@ const QueryStringInput = withKibana(QueryStringInputUI); // @internal export interface QueryBarTopRowProps { - query?: Query; - onSubmit: (payload: { dateRange: TimeRange; query?: Query }) => void; - onChange: (payload: { dateRange: TimeRange; query?: Query }) => void; - onRefresh?: (payload: { dateRange: TimeRange }) => void; + customSubmitButton?: any; dataTestSubj?: string; + dateRangeFrom?: string; + dateRangeTo?: string; disableAutoFocus?: boolean; - screenTitle?: string; + fillSubmitButton: boolean; + iconType?: EuiIconProps['type']; indexPatterns?: Array; + indicateNoData?: boolean; + isClearable?: boolean; + isDirty: boolean; isLoading?: boolean; + isRefreshPaused?: boolean; + nonKqlMode?: 'lucene' | 'text'; + nonKqlModeHelpText?: string; + onChange: (payload: { dateRange: TimeRange; query?: Query }) => void; + onRefresh?: (payload: { dateRange: TimeRange }) => void; + onRefreshChange?: (options: { isPaused: boolean; refreshInterval: number }) => void; + onSubmit: (payload: { dateRange: TimeRange; query?: Query }) => void; + placeholder?: string; prepend?: React.ComponentProps['prepend']; + query?: Query; + refreshInterval?: number; + screenTitle?: string; showQueryInput?: boolean; showDatePicker?: boolean; - dateRangeFrom?: string; - dateRangeTo?: string; - isRefreshPaused?: boolean; - refreshInterval?: number; showAutoRefreshOnly?: boolean; - onRefreshChange?: (options: { isPaused: boolean; refreshInterval: number }) => void; - customSubmitButton?: any; - isDirty: boolean; timeHistory?: TimeHistoryContract; - indicateNoData?: boolean; - iconType?: EuiIconProps['type']; - placeholder?: string; - isClearable?: boolean; - nonKqlMode?: 'lucene' | 'text'; - nonKqlModeHelpText?: string; timeRangeForSuggestionsOverride?: boolean; } @@ -229,7 +230,7 @@ export default function QueryBarTopRow(props: QueryBarTopRowProps) { isDisabled={isDateRangeInvalid} isLoading={props.isLoading} onClick={onClickSubmitButton} - fill={false} + fill={props.fillSubmitButton} data-test-subj="querySubmitButton" /> ); diff --git a/src/plugins/data/public/ui/search_bar/search_bar.tsx b/src/plugins/data/public/ui/search_bar/search_bar.tsx index 3fef455be41c3..87b6480096551 100644 --- a/src/plugins/data/public/ui/search_bar/search_bar.tsx +++ b/src/plugins/data/public/ui/search_bar/search_bar.tsx @@ -77,6 +77,8 @@ export interface SearchBarOwnProps { nonKqlModeHelpText?: string; // defines padding; use 'inPage' to avoid extra padding; use 'detached' if the searchBar appears at the very top of the view, without any wrapper displayStyle?: 'inPage' | 'detached'; + // super update button background fill control + fillSubmitButton?: boolean; } export type SearchBarProps = SearchBarOwnProps & SearchBarInjectedDeps; @@ -365,6 +367,7 @@ class SearchBarUI extends Component { onSubmit={this.onQueryBarSubmit} indexPatterns={this.props.indexPatterns} isLoading={this.props.isLoading} + fillSubmitButton={this.props.fillSubmitButton || false} prepend={this.props.showFilterBar ? savedQueryManagement : undefined} showDatePicker={this.props.showDatePicker} dateRangeFrom={this.state.dateRangeFrom} diff --git a/src/plugins/data/public/utils/table_inspector_view/components/__snapshots__/data_view.test.tsx.snap b/src/plugins/data/public/utils/table_inspector_view/components/__snapshots__/data_view.test.tsx.snap index 3262ee70dff86..4db3f780fdebe 100644 --- a/src/plugins/data/public/utils/table_inspector_view/components/__snapshots__/data_view.test.tsx.snap +++ b/src/plugins/data/public/utils/table_inspector_view/components/__snapshots__/data_view.test.tsx.snap @@ -1416,54 +1416,57 @@ exports[`Inspector Data View component should render single table without select aria-label="Pagination for table: " className="euiPagination" > - + + Page 1 of 1 + + + - - - - - - + /> + + + +
- - - - - - - + /> + + + + @@ -3002,54 +2997,57 @@ exports[`Inspector Data View component should support multiple datatables 1`] = aria-label="Pagination for table: " className="euiPagination" > - + + Page 1 of 1 + + + - - - - - - + /> + + + +
- - - - - - - + /> + + + + diff --git a/src/plugins/data_view_field_editor/__jest__/client_integration/helpers/setup_environment.tsx b/src/plugins/data_view_field_editor/__jest__/client_integration/helpers/setup_environment.tsx index 577aac09a744e..722b1b1ec2cea 100644 --- a/src/plugins/data_view_field_editor/__jest__/client_integration/helpers/setup_environment.tsx +++ b/src/plugins/data_view_field_editor/__jest__/client_integration/helpers/setup_environment.tsx @@ -6,6 +6,7 @@ * Side Public License, v 1. */ +// eslint-disable-next-line max-classes-per-file import './jest.mocks'; import React, { FunctionComponent } from 'react'; @@ -19,10 +20,12 @@ import { FieldEditorProvider, Context } from '../../../public/components/field_e import { FieldPreviewProvider } from '../../../public/components/preview'; import { initApi, ApiService } from '../../../public/lib'; import { init as initHttpRequests } from './http_requests'; +import { fieldFormatsMock as fieldFormats } from '../../../../field_formats/common/mocks'; +import { FieldFormat } from '../../../../field_formats/common'; const mockHttpClient = axios.create({ adapter: axiosXhrAdapter }); const dataStart = dataPluginMock.createStartContract(); -const { search, fieldFormats } = dataStart; +const { search } = dataStart; export const spySearchQuery = jest.fn(); export const spySearchQueryResponse = jest.fn(() => Promise.resolve({})); @@ -68,8 +71,20 @@ export const setupEnvironment = () => { }; }; +class MockDefaultFieldFormat extends FieldFormat { + static id = 'testDefaultFormat'; + static title = 'TestDefaultFormat'; +} + +class MockCustomFieldFormat extends FieldFormat { + static id = 'upper'; + static title = 'UpperCaseString'; + + htmlConvert = (value: string) => `${value.toUpperCase()}`; +} + // The format options available in the dropdown select for our tests. -export const fieldFormatsOptions = [{ id: 'upper', title: 'UpperCaseString' } as any]; +export const fieldFormatsOptions = [MockCustomFieldFormat]; export const indexPatternNameForTest = 'testIndexPattern'; @@ -86,22 +101,24 @@ export const WithFieldEditorDependencies = ( fieldFormats.getDefaultType as jest.MockedFunction - ).mockReturnValue({ id: 'testDefaultFormat', title: 'TestDefaultFormat' } as any); + ).mockReturnValue(MockDefaultFieldFormat); ( fieldFormats.getInstance as jest.MockedFunction ).mockImplementation((id: string) => { - if (id === 'upper') { - return { - convertObject: { - html(value: string = '') { - return `${value.toUpperCase()}`; - }, - }, - } as any; + if (id === MockCustomFieldFormat.id) { + return new MockCustomFieldFormat(); + } else { + return new MockDefaultFieldFormat(); } }); + ( + fieldFormats.getDefaultInstance as jest.MockedFunction + ).mockImplementation(() => { + return new MockDefaultFieldFormat(); + }); + const dependencies: Context = { dataView: { title: indexPatternNameForTest, diff --git a/src/plugins/data_view_field_editor/public/components/field_format_editor/field_format_editor.tsx b/src/plugins/data_view_field_editor/public/components/field_format_editor/field_format_editor.tsx index 468435a92b44f..3879abeab2f58 100644 --- a/src/plugins/data_view_field_editor/public/components/field_format_editor/field_format_editor.tsx +++ b/src/plugins/data_view_field_editor/public/components/field_format_editor/field_format_editor.tsx @@ -109,7 +109,6 @@ export class FormatSelectEditor extends PureComponent< render() { const { fieldFormatEditors, onError, value, fieldFormats, esTypes } = this.props; const fieldFormatId = value?.id; - const fieldFormatParams = value?.params; const { kbnType } = this.state; const { fieldTypeFormats } = this.state; @@ -121,6 +120,8 @@ export class FormatSelectEditor extends PureComponent< ? fieldFormats.getInstance(value?.id, value?.params) : fieldFormats.getDefaultInstance(kbnType, esTypes); + const fieldFormatParams = format.params(); + const label = defaultFormat ? ( { this.onFormatChange(fieldFormatId, params); diff --git a/src/plugins/data_view_field_editor/public/components/preview/field_preview_context.tsx b/src/plugins/data_view_field_editor/public/components/preview/field_preview_context.tsx index f560cee59372f..a4a09562c300f 100644 --- a/src/plugins/data_view_field_editor/public/components/preview/field_preview_context.tsx +++ b/src/plugins/data_view_field_editor/public/components/preview/field_preview_context.tsx @@ -19,6 +19,7 @@ import React, { import useDebounce from 'react-use/lib/useDebounce'; import { i18n } from '@kbn/i18n'; import { get } from 'lodash'; +import { castEsToKbnFieldTypeName } from '@kbn/field-types'; import { parseEsError } from '../../lib/runtime_field_validation'; import { useFieldEditorContext } from '../field_editor_context'; @@ -165,13 +166,21 @@ export const FieldPreviewProvider: FunctionComponent = ({ children }) => { if (format?.id) { const formatter = fieldFormats.getInstance(format.id, format.params); if (formatter) { - return formatter.convertObject?.html(value) ?? JSON.stringify(value); + return formatter.getConverterFor('html')(value) ?? JSON.stringify(value); + } + } + + if (type) { + const fieldType = castEsToKbnFieldTypeName(type); + const defaultFormatterForType = fieldFormats.getDefaultInstance(fieldType); + if (defaultFormatterForType) { + return defaultFormatterForType.getConverterFor('html')(value) ?? JSON.stringify(value); } } return defaultValueFormatter(value); }, - [format, fieldFormats] + [format, type, fieldFormats] ); const fetchSampleDocuments = useCallback( diff --git a/src/plugins/discover/public/application/context/context_app_route.tsx b/src/plugins/discover/public/application/context/context_app_route.tsx index 80feea833ec94..b58bbebcd0973 100644 --- a/src/plugins/discover/public/application/context/context_app_route.tsx +++ b/src/plugins/discover/public/application/context/context_app_route.tsx @@ -10,26 +10,19 @@ import { useParams } from 'react-router-dom'; import { i18n } from '@kbn/i18n'; import { EuiEmptyPrompt } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; -import { DiscoverServices } from '../../build_services'; import { ContextApp } from './context_app'; import { getRootBreadcrumbs } from '../../utils/breadcrumbs'; import { LoadingIndicator } from '../../components/common/loading_indicator'; import { useIndexPattern } from '../../utils/use_index_pattern'; +import { DiscoverRouteProps } from '../types'; import { useMainRouteBreadcrumb } from '../../utils/use_navigation_props'; -export interface ContextAppProps { - /** - * Kibana core services used by discover - */ - services: DiscoverServices; -} - export interface ContextUrlParams { indexPatternId: string; id: string; } -export function ContextAppRoute(props: ContextAppProps) { +export function ContextAppRoute(props: DiscoverRouteProps) { const { services } = props; const { chrome } = services; diff --git a/src/plugins/discover/public/application/doc/single_doc_route.tsx b/src/plugins/discover/public/application/doc/single_doc_route.tsx index 0a5cc3a8a82b6..0d65bbeb714cf 100644 --- a/src/plugins/discover/public/application/doc/single_doc_route.tsx +++ b/src/plugins/discover/public/application/doc/single_doc_route.tsx @@ -6,21 +6,22 @@ * Side Public License, v 1. */ import React, { useEffect } from 'react'; -import { useLocation, useParams } from 'react-router-dom'; +import { useParams } from 'react-router-dom'; import { EuiEmptyPrompt } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; -import { DiscoverServices } from '../../build_services'; import { getRootBreadcrumbs } from '../../utils/breadcrumbs'; -import { Doc } from './components/doc'; import { LoadingIndicator } from '../../components/common/loading_indicator'; import { useIndexPattern } from '../../utils/use_index_pattern'; +import { withQueryParams } from '../../utils/with_query_params'; import { useMainRouteBreadcrumb } from '../../utils/use_navigation_props'; +import { DiscoverRouteProps } from '../types'; +import { Doc } from './components/doc'; -export interface SingleDocRouteProps { +export interface SingleDocRouteProps extends DiscoverRouteProps { /** - * Kibana core services used by discover + * Document id */ - services: DiscoverServices; + id: string; } export interface DocUrlParams { @@ -28,28 +29,21 @@ export interface DocUrlParams { index: string; } -function useQuery() { - return new URLSearchParams(useLocation().search); -} - -export function SingleDocRoute(props: SingleDocRouteProps) { - const { services } = props; +const SingleDoc = (props: SingleDocRouteProps) => { + const { id, services } = props; const { chrome, timefilter } = services; const { indexPatternId, index } = useParams(); const breadcrumb = useMainRouteBreadcrumb(); - const query = useQuery(); - const docId = query.get('id') || ''; - useEffect(() => { chrome.setBreadcrumbs([ ...getRootBreadcrumbs(breadcrumb), { - text: `${index}#${docId}`, + text: `${index}#${id}`, }, ]); - }, [chrome, index, docId, breadcrumb]); + }, [chrome, index, id, breadcrumb]); useEffect(() => { timefilter.disableAutoRefreshSelector(); @@ -86,7 +80,9 @@ export function SingleDocRoute(props: SingleDocRouteProps) { return (
- +
); -} +}; + +export const SingleDocRoute = withQueryParams(SingleDoc, ['id']); 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 6864a1c5c2d4a..96fe46acba513 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 @@ -24,8 +24,7 @@ import { import { i18n } from '@kbn/i18n'; import { UiCounterMetricType } from '@kbn/analytics'; import classNames from 'classnames'; -import { FieldIcon } from '@kbn/react-field/field_icon'; -import { FieldButton } from '@kbn/react-field/field_button'; +import { FieldButton, FieldIcon } from '@kbn/react-field'; import { DiscoverFieldDetails } from './discover_field_details'; import { FieldDetails } from './types'; import { IndexPatternField, IndexPattern } from '../../../../../../data/public'; diff --git a/src/plugins/discover/public/application/main/components/sidebar/discover_sidebar_responsive.tsx b/src/plugins/discover/public/application/main/components/sidebar/discover_sidebar_responsive.tsx index 6316369ff4c6f..27f2845503978 100644 --- a/src/plugins/discover/public/application/main/components/sidebar/discover_sidebar_responsive.tsx +++ b/src/plugins/discover/public/application/main/components/sidebar/discover_sidebar_responsive.tsx @@ -123,16 +123,11 @@ export function DiscoverSidebarResponsive(props: DiscoverSidebarResponsiveProps) const [fieldFilter, setFieldFilter] = useState(getDefaultFieldFilter()); const [isFlyoutVisible, setIsFlyoutVisible] = useState(false); /** - * needed for merging new with old field counts, high likely legacy, but kept this behavior - * because not 100% sure in this case + * fieldCounts are used to determine which fields are actually used in the given set of documents */ const fieldCounts = useRef | null>(null); if (fieldCounts.current === null) { - fieldCounts.current = calcFieldCounts( - {}, - props.documents$.getValue().result, - selectedIndexPattern - ); + fieldCounts.current = calcFieldCounts(props.documents$.getValue().result, selectedIndexPattern); } const [documentState, setDocumentState] = useState(props.documents$.getValue()); @@ -140,11 +135,7 @@ export function DiscoverSidebarResponsive(props: DiscoverSidebarResponsiveProps) const subscription = props.documents$.subscribe((next) => { if (next.fetchStatus !== documentState.fetchStatus) { if (next.result) { - fieldCounts.current = calcFieldCounts( - next.result.length && fieldCounts.current ? fieldCounts.current : {}, - next.result, - selectedIndexPattern! - ); + fieldCounts.current = calcFieldCounts(next.result, selectedIndexPattern!); } setDocumentState({ ...documentState, ...next }); } 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 d226e5ef9748b..b2576a3b5d582 100644 --- a/src/plugins/discover/public/application/main/discover_main_route.tsx +++ b/src/plugins/discover/public/application/main/discover_main_route.tsx @@ -8,11 +8,8 @@ import React, { useEffect, useState, memo } from 'react'; import { History } from 'history'; import { useParams } from 'react-router-dom'; -import { i18n } from '@kbn/i18n'; -import { EuiEmptyPrompt } from '@elastic/eui'; import { IndexPatternAttributes, ISearchSource, SavedObject } from 'src/plugins/data/common'; -import { DiscoverServices } from '../../build_services'; import { SavedSearch, getSavedSearch, @@ -26,39 +23,22 @@ import { redirectWhenMissing } from '../../../../kibana_utils/public'; import { DataViewSavedObjectConflictError } from '../../../../data_views/common'; import { getUrlTracker } from '../../kibana_services'; import { LoadingIndicator } from '../../components/common/loading_indicator'; +import { DiscoverError } from '../../components/common/error_alert'; +import { DiscoverRouteProps } from '../types'; const DiscoverMainAppMemoized = memo(DiscoverMainApp); -export interface DiscoverMainProps { +export interface DiscoverMainProps extends DiscoverRouteProps { /** * Instance of browser history */ history: History; - /** - * Kibana core services used by discover - */ - services: DiscoverServices; } interface DiscoverLandingParams { id: string; } -const DiscoverError = ({ error }: { error: Error }) => ( - - {i18n.translate('discover.discoverError.title', { - defaultMessage: 'Error loading Discover', - })} - - } - body={

{error.message}

} - /> -); - export function DiscoverMainRoute({ services, history }: DiscoverMainProps) { const { core, diff --git a/src/plugins/discover/public/application/main/utils/calc_field_counts.test.ts b/src/plugins/discover/public/application/main/utils/calc_field_counts.test.ts index 28d814b871104..2ed564194bd25 100644 --- a/src/plugins/discover/public/application/main/utils/calc_field_counts.test.ts +++ b/src/plugins/discover/public/application/main/utils/calc_field_counts.test.ts @@ -16,7 +16,7 @@ describe('calcFieldCounts', () => { { _id: 1, _source: { message: 'test1', bytes: 20 } }, { _id: 2, _source: { name: 'test2', extension: 'jpg' } }, ] as unknown as ElasticSearchHit[]; - const result = calcFieldCounts({}, rows, indexPatternMock); + const result = calcFieldCounts(rows, indexPatternMock); expect(result).toMatchInlineSnapshot(` Object { "_index": 2, @@ -33,14 +33,14 @@ describe('calcFieldCounts', () => { { _id: 1, _source: { message: 'test1', bytes: 20 } }, { _id: 2, _source: { name: 'test2', extension: 'jpg' } }, ] as unknown as ElasticSearchHit[]; - const result = calcFieldCounts({ message: 2 }, rows, indexPatternMock); + const result = calcFieldCounts(rows, indexPatternMock); expect(result).toMatchInlineSnapshot(` Object { "_index": 2, "_score": 2, "bytes": 1, "extension": 1, - "message": 3, + "message": 1, "name": 1, } `); diff --git a/src/plugins/discover/public/application/main/utils/calc_field_counts.ts b/src/plugins/discover/public/application/main/utils/calc_field_counts.ts index 9a7f68550d840..e315ec15d9284 100644 --- a/src/plugins/discover/public/application/main/utils/calc_field_counts.ts +++ b/src/plugins/discover/public/application/main/utils/calc_field_counts.ts @@ -10,14 +10,11 @@ import { flattenHit, IndexPattern } from '../../../../../data/common'; import { ElasticSearchHit } from '../../../types'; /** - * This function is recording stats of the available fields, for usage in sidebar and sharing + * This function is calculating stats of the available fields, for usage in sidebar and sharing * Note that this values aren't displayed, but used for internal calculations */ -export function calcFieldCounts( - counts = {} as Record, - rows?: ElasticSearchHit[], - indexPattern?: IndexPattern -) { +export function calcFieldCounts(rows?: ElasticSearchHit[], indexPattern?: IndexPattern) { + const counts: Record = {}; if (!rows || !indexPattern) { return {}; } diff --git a/src/plugins/discover/public/application/main/utils/fetch_all.test.ts b/src/plugins/discover/public/application/main/utils/fetch_all.test.ts index a2dae5cc99b7d..1ea9ec0bb3582 100644 --- a/src/plugins/discover/public/application/main/utils/fetch_all.test.ts +++ b/src/plugins/discover/public/application/main/utils/fetch_all.test.ts @@ -77,6 +77,7 @@ describe('test fetchAll', () => { searchSessionId: '123', initialFetchStatus: FetchStatus.UNINITIALIZED, useNewFieldsApi: true, + savedSearch: savedSearchMock, services: discoverServiceMock, }; searchSource = savedSearchMock.searchSource.createChild(); diff --git a/src/plugins/discover/public/application/main/utils/fetch_all.ts b/src/plugins/discover/public/application/main/utils/fetch_all.ts index 29279152ca321..4109cbb73788f 100644 --- a/src/plugins/discover/public/application/main/utils/fetch_all.ts +++ b/src/plugins/discover/public/application/main/utils/fetch_all.ts @@ -14,7 +14,7 @@ import { sendResetMsg, } from './use_saved_search_messages'; import { updateSearchSource } from './update_search_source'; -import type { SortOrder } from '../../../services/saved_searches'; +import type { SavedSearch, SortOrder } from '../../../services/saved_searches'; import { fetchDocuments } from './fetch_documents'; import { fetchTotalHits } from './fetch_total_hits'; import { fetchChart } from './fetch_chart'; @@ -34,6 +34,17 @@ import { DiscoverServices } from '../../../build_services'; import { ReduxLikeStateContainer } from '../../../../../kibana_utils/common'; import { DataViewType } from '../../../../../data_views/common'; +export interface FetchDeps { + abortController: AbortController; + appStateContainer: ReduxLikeStateContainer; + data: DataPublicPluginStart; + initialFetchStatus: FetchStatus; + inspectorAdapters: Adapters; + savedSearch: SavedSearch; + searchSessionId: string; + services: DiscoverServices; + useNewFieldsApi: boolean; +} /** * This function starts fetching all required queries in Discover. This will be the query to load the individual * documents, and depending on whether a chart is shown either the aggregation query to load the chart data @@ -46,16 +57,7 @@ export function fetchAll( dataSubjects: SavedSearchData, searchSource: ISearchSource, reset = false, - fetchDeps: { - abortController: AbortController; - appStateContainer: ReduxLikeStateContainer; - inspectorAdapters: Adapters; - data: DataPublicPluginStart; - initialFetchStatus: FetchStatus; - searchSessionId: string; - services: DiscoverServices; - useNewFieldsApi: boolean; - } + fetchDeps: FetchDeps ): Promise { const { initialFetchStatus, appStateContainer, services, useNewFieldsApi, data } = fetchDeps; diff --git a/src/plugins/discover/public/application/main/utils/fetch_chart.test.ts b/src/plugins/discover/public/application/main/utils/fetch_chart.test.ts index b8c2f643acae7..4c68eff54f579 100644 --- a/src/plugins/discover/public/application/main/utils/fetch_chart.test.ts +++ b/src/plugins/discover/public/application/main/utils/fetch_chart.test.ts @@ -14,6 +14,55 @@ import { AppState } from '../services/discover_state'; import { discoverServiceMock } from '../../../__mocks__/services'; import { calculateBounds, IKibanaSearchResponse } from '../../../../../data/common'; import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; +import { FetchDeps } from './fetch_all'; + +function getDeps() { + const deps = { + appStateContainer: { + getState: () => { + return { interval: 'auto' }; + }, + } as ReduxLikeStateContainer, + abortController: new AbortController(), + data: discoverServiceMock.data, + inspectorAdapters: { requests: new RequestAdapter() }, + onResults: jest.fn(), + savedSearch: savedSearchMockWithTimeField, + searchSessionId: '123', + } as unknown as FetchDeps; + deps.data.query.timefilter.timefilter.getTime = () => { + return { from: '2021-07-07T00:05:13.590', to: '2021-07-07T11:20:13.590' }; + }; + + deps.data.query.timefilter.timefilter.calculateBounds = (timeRange) => calculateBounds(timeRange); + return deps; +} + +const requestResult = { + id: 'Fjk5bndxTHJWU2FldVRVQ0tYR0VqOFEcRWtWNDhOdG5SUzJYcFhONVVZVTBJQToxMDMwOQ==', + rawResponse: { + took: 2, + timed_out: false, + _shards: { total: 1, successful: 1, skipped: 0, failed: 0 }, + hits: { max_score: null, hits: [], total: 42 }, + aggregations: { + '2': { + buckets: [ + { + key_as_string: '2021-07-07T06:36:00.000+02:00', + key: 1625632560000, + doc_count: 1, + }, + ], + }, + }, + }, + isPartial: false, + isRunning: false, + total: 1, + loaded: 1, + isRestored: false, +} as unknown as IKibanaSearchResponse>; describe('test fetchCharts', () => { test('updateSearchSource helper function', () => { @@ -52,76 +101,36 @@ describe('test fetchCharts', () => { }); test('resolves with summarized chart data', async () => { - const deps = { - appStateContainer: { - getState: () => { - return { interval: 'auto' }; - }, - } as ReduxLikeStateContainer, - abortController: new AbortController(), - data: discoverServiceMock.data, - inspectorAdapters: { requests: new RequestAdapter() }, - onResults: jest.fn(), - searchSessionId: '123', - }; - deps.data.query.timefilter.timefilter.getTime = () => { - return { from: '2021-07-07T00:05:13.590', to: '2021-07-07T11:20:13.590' }; - }; - - deps.data.query.timefilter.timefilter.calculateBounds = (timeRange) => - calculateBounds(timeRange); - - savedSearchMockWithTimeField.searchSource.fetch$ = () => - of({ - id: 'Fjk5bndxTHJWU2FldVRVQ0tYR0VqOFEcRWtWNDhOdG5SUzJYcFhONVVZVTBJQToxMDMwOQ==', - rawResponse: { - took: 2, - timed_out: false, - _shards: { total: 1, successful: 1, skipped: 0, failed: 0 }, - hits: { max_score: null, hits: [], total: 42 }, - aggregations: { - '2': { - buckets: [ - { - key_as_string: '2021-07-07T06:36:00.000+02:00', - key: 1625632560000, - doc_count: 1, - }, - ], - }, - }, - }, - isPartial: false, - isRunning: false, - total: 1, - loaded: 1, - isRestored: false, - } as unknown as IKibanaSearchResponse>); + savedSearchMockWithTimeField.searchSource.fetch$ = () => of(requestResult); - const result = await fetchChart(savedSearchMockWithTimeField.searchSource, deps); + const result = await fetchChart(savedSearchMockWithTimeField.searchSource, getDeps()); expect(result).toHaveProperty('totalHits', 42); expect(result).toHaveProperty('bucketInterval.description', '0 milliseconds'); expect(result).toHaveProperty('chartData'); }); test('rejects promise on query failure', async () => { - const deps = { - appStateContainer: { - getState: () => { - return { interval: 'auto' }; - }, - } as ReduxLikeStateContainer, - abortController: new AbortController(), - data: discoverServiceMock.data, - inspectorAdapters: { requests: new RequestAdapter() }, - onResults: jest.fn(), - searchSessionId: '123', - }; - savedSearchMockWithTimeField.searchSource.fetch$ = () => throwErrorRx({ msg: 'Oh noes!' }); - await expect(fetchChart(savedSearchMockWithTimeField.searchSource, deps)).rejects.toEqual({ + await expect(fetchChart(savedSearchMockWithTimeField.searchSource, getDeps())).rejects.toEqual({ msg: 'Oh noes!', }); }); + + test('fetch$ is called with execution context containing savedSearch id', async () => { + const fetch$Mock = jest.fn().mockReturnValue(of(requestResult)); + + savedSearchMockWithTimeField.searchSource.fetch$ = fetch$Mock; + + await fetchChart(savedSearchMockWithTimeField.searchSource, getDeps()); + expect(fetch$Mock.mock.calls[0][0].executionContext).toMatchInlineSnapshot(` + Object { + "description": "fetch chart data and total hits", + "id": "the-saved-search-id-with-timefield", + "name": "discover", + "type": "application", + "url": "/", + } + `); + }); }); diff --git a/src/plugins/discover/public/application/main/utils/fetch_chart.ts b/src/plugins/discover/public/application/main/utils/fetch_chart.ts index 7f74f693eb784..00cb9c43caccf 100644 --- a/src/plugins/discover/public/application/main/utils/fetch_chart.ts +++ b/src/plugins/discover/public/application/main/utils/fetch_chart.ts @@ -13,13 +13,11 @@ import { search, ISearchSource, } from '../../../../../data/public'; -import { Adapters } from '../../../../../inspector'; import { getChartAggConfigs, getDimensions } from './index'; import { tabifyAggResponse } from '../../../../../data/common'; import { buildPointSeriesData, Chart } from '../components/chart/point_series'; import { TimechartBucketInterval } from './use_saved_search'; -import { AppState } from '../services/discover_state'; -import { ReduxLikeStateContainer } from '../../../../../kibana_utils/common'; +import { FetchDeps } from './fetch_all'; interface Result { totalHits: number; @@ -35,13 +33,8 @@ export function fetchChart( data, inspectorAdapters, searchSessionId, - }: { - abortController: AbortController; - appStateContainer: ReduxLikeStateContainer; - data: DataPublicPluginStart; - inspectorAdapters: Adapters; - searchSessionId: string; - } + savedSearch, + }: FetchDeps ): Promise { const interval = appStateContainer.getState().interval ?? 'auto'; const chartAggConfigs = updateSearchSource(searchSource, interval, data); @@ -51,7 +44,7 @@ export function fetchChart( name: 'discover', description: 'fetch chart data and total hits', url: window.location.pathname, - id: '', + id: savedSearch.id ?? '', }; const fetch$ = searchSource diff --git a/src/plugins/discover/public/application/main/utils/fetch_documents.test.ts b/src/plugins/discover/public/application/main/utils/fetch_documents.test.ts index 1342378f5a90b..000d3282c38b3 100644 --- a/src/plugins/discover/public/application/main/utils/fetch_documents.test.ts +++ b/src/plugins/discover/public/application/main/utils/fetch_documents.test.ts @@ -8,18 +8,22 @@ import { fetchDocuments } from './fetch_documents'; import { throwError as throwErrorRx, of } from 'rxjs'; import { RequestAdapter } from '../../../../../inspector'; -import { savedSearchMock } from '../../../__mocks__/saved_search'; +import { savedSearchMock, savedSearchMockWithTimeField } from '../../../__mocks__/saved_search'; import { discoverServiceMock } from '../../../__mocks__/services'; import { IKibanaSearchResponse } from 'src/plugins/data/common'; import { SearchResponse } from '@elastic/elasticsearch/lib/api/types'; +import { FetchDeps } from './fetch_all'; +import { fetchTotalHits } from './fetch_total_hits'; -const getDeps = () => ({ - abortController: new AbortController(), - inspectorAdapters: { requests: new RequestAdapter() }, - onResults: jest.fn(), - searchSessionId: '123', - services: discoverServiceMock, -}); +const getDeps = () => + ({ + abortController: new AbortController(), + inspectorAdapters: { requests: new RequestAdapter() }, + onResults: jest.fn(), + searchSessionId: '123', + services: discoverServiceMock, + savedSearch: savedSearchMock, + } as unknown as FetchDeps); describe('test fetchDocuments', () => { test('resolves with returned documents', async () => { @@ -39,4 +43,25 @@ describe('test fetchDocuments', () => { msg: 'Oh noes!', }); }); + + test('fetch$ is called with execution context containing savedSearch id', async () => { + const fetch$Mock = jest.fn().mockReturnValue( + of({ + rawResponse: { hits: { hits: [] } }, + } as unknown as IKibanaSearchResponse) + ); + + savedSearchMockWithTimeField.searchSource.fetch$ = fetch$Mock; + + await fetchTotalHits(savedSearchMockWithTimeField.searchSource, getDeps()); + expect(fetch$Mock.mock.calls[0][0].executionContext).toMatchInlineSnapshot(` + Object { + "description": "fetch total hits", + "id": "the-saved-search-id", + "name": "discover", + "type": "application", + "url": "/", + } + `); + }); }); diff --git a/src/plugins/discover/public/application/main/utils/fetch_documents.ts b/src/plugins/discover/public/application/main/utils/fetch_documents.ts index 0c83b85b2bc62..dbf972265547e 100644 --- a/src/plugins/discover/public/application/main/utils/fetch_documents.ts +++ b/src/plugins/discover/public/application/main/utils/fetch_documents.ts @@ -7,10 +7,9 @@ */ import { i18n } from '@kbn/i18n'; import { filter, map } from 'rxjs/operators'; -import { Adapters } from '../../../../../inspector/common'; import { isCompleteResponse, ISearchSource } from '../../../../../data/common'; import { SAMPLE_SIZE_SETTING } from '../../../../common'; -import { DiscoverServices } from '../../../build_services'; +import { FetchDeps } from './fetch_all'; /** * Requests the documents for Discover. This will return a promise that will resolve @@ -18,17 +17,7 @@ import { DiscoverServices } from '../../../build_services'; */ export const fetchDocuments = ( searchSource: ISearchSource, - { - abortController, - inspectorAdapters, - searchSessionId, - services, - }: { - abortController: AbortController; - inspectorAdapters: Adapters; - searchSessionId: string; - services: DiscoverServices; - } + { abortController, inspectorAdapters, searchSessionId, services, savedSearch }: FetchDeps ) => { searchSource.setField('size', services.uiSettings.get(SAMPLE_SIZE_SETTING)); searchSource.setField('trackTotalHits', false); @@ -47,7 +36,7 @@ export const fetchDocuments = ( name: 'discover', description: 'fetch documents', url: window.location.pathname, - id: '', + id: savedSearch.id ?? '', }; const fetch$ = searchSource diff --git a/src/plugins/discover/public/application/main/utils/fetch_total_hits.test.ts b/src/plugins/discover/public/application/main/utils/fetch_total_hits.test.ts index 7b564906f95a7..ba7b6a765aa2e 100644 --- a/src/plugins/discover/public/application/main/utils/fetch_total_hits.test.ts +++ b/src/plugins/discover/public/application/main/utils/fetch_total_hits.test.ts @@ -7,18 +7,21 @@ */ import { throwError as throwErrorRx, of } from 'rxjs'; import { RequestAdapter } from '../../../../../inspector'; -import { savedSearchMock } from '../../../__mocks__/saved_search'; +import { savedSearchMock, savedSearchMockWithTimeField } from '../../../__mocks__/saved_search'; import { fetchTotalHits } from './fetch_total_hits'; import { discoverServiceMock } from '../../../__mocks__/services'; import { SearchResponse } from '@elastic/elasticsearch/lib/api/types'; import { IKibanaSearchResponse } from 'src/plugins/data/common'; +import { FetchDeps } from './fetch_all'; -const getDeps = () => ({ - abortController: new AbortController(), - inspectorAdapters: { requests: new RequestAdapter() }, - searchSessionId: '123', - data: discoverServiceMock.data, -}); +const getDeps = () => + ({ + abortController: new AbortController(), + inspectorAdapters: { requests: new RequestAdapter() }, + searchSessionId: '123', + data: discoverServiceMock.data, + savedSearch: savedSearchMock, + } as FetchDeps); describe('test fetchTotalHits', () => { test('resolves returned promise with hit count', async () => { @@ -35,4 +38,24 @@ describe('test fetchTotalHits', () => { msg: 'Oh noes!', }); }); + test('fetch$ is called with execution context containing savedSearch id', async () => { + const fetch$Mock = jest + .fn() + .mockReturnValue( + of({ rawResponse: { hits: { total: 45 } } } as IKibanaSearchResponse) + ); + + savedSearchMockWithTimeField.searchSource.fetch$ = fetch$Mock; + + await fetchTotalHits(savedSearchMockWithTimeField.searchSource, getDeps()); + expect(fetch$Mock.mock.calls[0][0].executionContext).toMatchInlineSnapshot(` + Object { + "description": "fetch total hits", + "id": "the-saved-search-id", + "name": "discover", + "type": "application", + "url": "/", + } + `); + }); }); diff --git a/src/plugins/discover/public/application/main/utils/fetch_total_hits.ts b/src/plugins/discover/public/application/main/utils/fetch_total_hits.ts index 55fc9c1c17235..af2d55e23cf32 100644 --- a/src/plugins/discover/public/application/main/utils/fetch_total_hits.ts +++ b/src/plugins/discover/public/application/main/utils/fetch_total_hits.ts @@ -10,19 +10,11 @@ import { i18n } from '@kbn/i18n'; import { filter, map } from 'rxjs/operators'; import { isCompleteResponse, ISearchSource } from '../../../../../data/public'; import { DataViewType } from '../../../../../data_views/common'; -import { Adapters } from '../../../../../inspector/common'; +import { FetchDeps } from './fetch_all'; export function fetchTotalHits( searchSource: ISearchSource, - { - abortController, - inspectorAdapters, - searchSessionId, - }: { - abortController: AbortController; - inspectorAdapters: Adapters; - searchSessionId: string; - } + { abortController, inspectorAdapters, searchSessionId, savedSearch }: FetchDeps ) { searchSource.setField('trackTotalHits', true); searchSource.setField('size', 0); @@ -42,7 +34,7 @@ export function fetchTotalHits( name: 'discover', description: 'fetch total hits', url: window.location.pathname, - id: '', + id: savedSearch.id ?? '', }; const fetch$ = searchSource diff --git a/src/plugins/discover/public/application/main/utils/use_discover_state.ts b/src/plugins/discover/public/application/main/utils/use_discover_state.ts index a4ef9382b4995..f5270e9f306df 100644 --- a/src/plugins/discover/public/application/main/utils/use_discover_state.ts +++ b/src/plugins/discover/public/application/main/utils/use_discover_state.ts @@ -92,6 +92,7 @@ export function useDiscoverState({ const { data$, refetch$, reset, inspectorAdapters } = useSavedSearchData({ initialFetchStatus, searchSessionManager, + savedSearch, searchSource, services, stateContainer, diff --git a/src/plugins/discover/public/application/main/utils/use_saved_search.test.ts b/src/plugins/discover/public/application/main/utils/use_saved_search.test.ts index 2788d63fdf983..0430b5672aebd 100644 --- a/src/plugins/discover/public/application/main/utils/use_saved_search.test.ts +++ b/src/plugins/discover/public/application/main/utils/use_saved_search.test.ts @@ -28,6 +28,7 @@ describe('test useSavedSearch', () => { const { result } = renderHook(() => { return useSavedSearch({ initialFetchStatus: FetchStatus.LOADING, + savedSearch: savedSearchMock, searchSessionManager, searchSource: savedSearchMock.searchSource.createCopy(), services: discoverServiceMock, @@ -66,6 +67,7 @@ describe('test useSavedSearch', () => { const { result, waitForValueToChange } = renderHook(() => { return useSavedSearch({ initialFetchStatus: FetchStatus.LOADING, + savedSearch: savedSearchMock, searchSessionManager, searchSource: resultState.current.searchSource, services: discoverServiceMock, @@ -108,6 +110,7 @@ describe('test useSavedSearch', () => { const { result, waitForValueToChange } = renderHook(() => { return useSavedSearch({ initialFetchStatus: FetchStatus.LOADING, + savedSearch: savedSearchMock, searchSessionManager, searchSource: resultState.current.searchSource, services: discoverServiceMock, diff --git a/src/plugins/discover/public/application/main/utils/use_saved_search.ts b/src/plugins/discover/public/application/main/utils/use_saved_search.ts index f37fdef4bd655..dadf4dec76452 100644 --- a/src/plugins/discover/public/application/main/utils/use_saved_search.ts +++ b/src/plugins/discover/public/application/main/utils/use_saved_search.ts @@ -23,6 +23,7 @@ import { useBehaviorSubject } from './use_behavior_subject'; import { sendResetMsg } from './use_saved_search_messages'; import { getFetch$ } from './get_fetch_observable'; import { ElasticSearchHit } from '../../../types'; +import { SavedSearch } from '../../../services/saved_searches'; export interface SavedSearchData { main$: DataMain$; @@ -83,6 +84,7 @@ export interface DataChartsMessage extends DataMsg { */ export const useSavedSearch = ({ initialFetchStatus, + savedSearch, searchSessionManager, searchSource, services, @@ -90,6 +92,7 @@ export const useSavedSearch = ({ useNewFieldsApi, }: { initialFetchStatus: FetchStatus; + savedSearch: SavedSearch; searchSessionManager: DiscoverSearchSessionManager; searchSource: ISearchSource; services: DiscoverServices; @@ -172,9 +175,10 @@ export const useSavedSearch = ({ await fetchAll(dataSubjects, searchSource, val === 'reset', { abortController: refs.current.abortController, appStateContainer: stateContainer.appStateContainer, - inspectorAdapters, data, initialFetchStatus, + inspectorAdapters, + savedSearch, searchSessionId: searchSessionManager.getNextSearchSessionId(), services, useNewFieldsApi, @@ -200,6 +204,7 @@ export const useSavedSearch = ({ inspectorAdapters, main$, refetch$, + savedSearch, searchSessionManager, searchSessionManager.newSearchSessionIdFromURL$, searchSource, diff --git a/src/plugins/discover/public/application/types.ts b/src/plugins/discover/public/application/types.ts index f04f3bf77c2f9..f33b8bb22b58c 100644 --- a/src/plugins/discover/public/application/types.ts +++ b/src/plugins/discover/public/application/types.ts @@ -6,6 +6,7 @@ * Side Public License, v 1. */ import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; +import { DiscoverServices } from '../build_services'; export enum FetchStatus { UNINITIALIZED = 'uninitialized', @@ -24,3 +25,10 @@ export type EsHitRecord = Required< isAnchor?: boolean; }; export type EsHitRecordList = EsHitRecord[]; + +export interface DiscoverRouteProps { + /** + * Kibana core services used by discover + */ + services: DiscoverServices; +} diff --git a/src/plugins/discover/public/components/common/error_alert.tsx b/src/plugins/discover/public/components/common/error_alert.tsx new file mode 100644 index 0000000000000..38e2a41f6f40e --- /dev/null +++ b/src/plugins/discover/public/components/common/error_alert.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 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, EuiEmptyPrompt } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { useHistory } from 'react-router-dom'; + +export const DiscoverError = ({ error }: { error: Error }) => { + const history = useHistory(); + + const goToMain = () => { + history.push('/'); + }; + + return ( + + {i18n.translate('discover.discoverError.title', { + defaultMessage: 'Cannot load this page', + })} + + } + body={

{error.message}

} + actions={ + + + + } + /> + ); +}; diff --git a/src/plugins/discover/public/components/discover_grid/constants.ts b/src/plugins/discover/public/components/discover_grid/constants.ts index 1126c6cbbf279..80900c06d4932 100644 --- a/src/plugins/discover/public/components/discover_grid/constants.ts +++ b/src/plugins/discover/public/components/discover_grid/constants.ts @@ -23,7 +23,7 @@ export const toolbarVisibility = { allowHide: false, allowReorder: true, }, - showStyleSelector: false, + showDisplaySelector: false, }; export const defaultMonacoEditorWidth = 370; diff --git a/src/plugins/discover/public/components/discover_grid/discover_grid_columns.test.tsx b/src/plugins/discover/public/components/discover_grid/discover_grid_columns.test.tsx index ea9cd5034551e..ef3e954d41cfc 100644 --- a/src/plugins/discover/public/components/discover_grid/discover_grid_columns.test.tsx +++ b/src/plugins/discover/public/components/discover_grid/discover_grid_columns.test.tsx @@ -10,7 +10,7 @@ import { indexPatternMock } from '../../__mocks__/index_pattern'; import { getEuiGridColumns } from './discover_grid_columns'; import { indexPatternWithTimefieldMock } from '../../__mocks__/index_pattern_with_timefield'; -describe('Discover grid columns ', function () { +describe('Discover grid columns', function () { it('returns eui grid columns without time column', async () => { const actual = getEuiGridColumns( ['extension', 'message'], @@ -123,6 +123,11 @@ describe('Discover grid columns ', function () { , diff --git a/src/plugins/discover/public/components/discover_grid/discover_grid_columns.tsx b/src/plugins/discover/public/components/discover_grid/discover_grid_columns.tsx index 872fa3133a024..c4e2f03f2fc36 100644 --- a/src/plugins/discover/public/components/discover_grid/discover_grid_columns.tsx +++ b/src/plugins/discover/public/components/discover_grid/discover_grid_columns.tsx @@ -99,7 +99,12 @@ export function buildEuiGridColumn( column.display = ( {indexPatternField?.customLabel ?? indexPattern.timeFieldName}{' '} - + ); column.initialWidth = defaultTimeColumnWidth; diff --git a/src/plugins/discover/public/components/field_name/field_name.tsx b/src/plugins/discover/public/components/field_name/field_name.tsx index 02d7c6f082db3..a13b339a39a93 100644 --- a/src/plugins/discover/public/components/field_name/field_name.tsx +++ b/src/plugins/discover/public/components/field_name/field_name.tsx @@ -11,7 +11,7 @@ import './field_name.scss'; import { EuiBadge, EuiFlexGroup, EuiFlexItem, EuiToolTip } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; import { i18n } from '@kbn/i18n'; -import { FieldIcon, FieldIconProps } from '@kbn/react-field/field_icon'; +import { FieldIcon, FieldIconProps } from '@kbn/react-field'; import { getFieldTypeName } from './field_type_name'; import { IndexPatternField } from '../../../../data/public'; import { getFieldSubtypeMulti } from '../../../../data/common'; diff --git a/src/plugins/discover/public/utils/with_query_params.test.tsx b/src/plugins/discover/public/utils/with_query_params.test.tsx new file mode 100644 index 0000000000000..d897c3327a06f --- /dev/null +++ b/src/plugins/discover/public/utils/with_query_params.test.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 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, { ReactElement } from 'react'; +import { Router } from 'react-router-dom'; +import { createMemoryHistory } from 'history'; +import { mountWithIntl } from '@kbn/test/jest'; +import { withQueryParams } from './with_query_params'; +import { DiscoverServices } from '../build_services'; +import { DiscoverRouteProps } from '../application/types'; + +interface ComponentProps extends DiscoverRouteProps { + id: string; + query: string; +} + +const mountComponent = (children: ReactElement, query = '') => { + const history = createMemoryHistory({ + initialEntries: ['/' + query], + }); + return mountWithIntl({children}); +}; + +describe('withQueryParams', () => { + it('should display error message, when query does not contain required parameters', () => { + const Component = withQueryParams(() =>
, ['id', 'query']); + const component = mountComponent(); + + expect(component.html()).toContain('Cannot load this page'); + expect(component.html()).toContain('URL query string is missing id, query.'); + }); + + it('should not display error message, when query contain required parameters', () => { + const Component = withQueryParams( + ({ id, query }: ComponentProps) => ( +
+ {id} and {query} are presented +
+ ), + ['id', 'query'] + ); + const component = mountComponent( + , + '?id=one&query=another' + ); + + expect(component.html()).toContain('one and another are presented'); + expect(component.html()).not.toContain('URL query string is missing id, query.'); + }); +}); diff --git a/src/plugins/discover/public/utils/with_query_params.tsx b/src/plugins/discover/public/utils/with_query_params.tsx new file mode 100644 index 0000000000000..66f0dd72c64de --- /dev/null +++ b/src/plugins/discover/public/utils/with_query_params.tsx @@ -0,0 +1,47 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 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 } from 'react'; +import { i18n } from '@kbn/i18n'; +import { useLocation } from 'react-router-dom'; +import { DiscoverRouteProps } from '../application/types'; +import { DiscoverError } from '../components/common/error_alert'; + +function useQuery() { + const { search } = useLocation(); + return useMemo(() => new URLSearchParams(search), [search]); +} + +export const withQueryParams =

( + Component: React.ComponentType

, + requiredParams: string[] +) => { + return (routeProps: DiscoverRouteProps) => { + const query = useQuery(); + + const missingParamNames = useMemo( + () => requiredParams.filter((currentParamName) => !query.get(currentParamName)), + [query] + ); + + if (missingParamNames.length !== 0) { + const missingParamsList = missingParamNames.join(', '); + const errorMessage = i18n.translate('discover.discoverError.missingQueryParamsError', { + defaultMessage: 'URL query string is missing {missingParamsList}.', + values: { missingParamsList }, + }); + + return ; + } + + const queryProps = Object.fromEntries( + requiredParams.map((current) => [[current], query.get(current)]) + ); + return ; + }; +}; diff --git a/src/plugins/embeddable/common/index.ts b/src/plugins/embeddable/common/index.ts index b6a6fe101668e..4eed6531cf7d5 100644 --- a/src/plugins/embeddable/common/index.ts +++ b/src/plugins/embeddable/common/index.ts @@ -6,8 +6,13 @@ * Side Public License, v 1. */ -// TODO: https://github.com/elastic/kibana/issues/109903 -/* eslint-disable @kbn/eslint/no_export_all */ - -export * from './types'; -export * from './lib'; +export type { + EmbeddableInput, + CommonEmbeddableStartContract, + EmbeddableStateWithType, + PanelState, + EmbeddablePersistableStateService, +} from './types'; +export { ViewMode } from './types'; +export type { SavedObjectEmbeddableInput } from './lib'; +export { isSavedObjectEmbeddableInput } from './lib'; diff --git a/src/plugins/embeddable/common/lib/index.ts b/src/plugins/embeddable/common/lib/index.ts index c7e8473937cc7..4cc8715334cf8 100644 --- a/src/plugins/embeddable/common/lib/index.ts +++ b/src/plugins/embeddable/common/lib/index.ts @@ -6,9 +6,10 @@ * Side Public License, v 1. */ -export * from './extract'; -export * from './inject'; -export * from './migrate'; -export * from './migrate_base_input'; -export * from './telemetry'; -export * from './saved_object_embeddable'; +export { getExtractFunction } from './extract'; +export { getInjectFunction } from './inject'; +export type { MigrateFunction } from './migrate'; +export { getMigrateFunction } from './migrate'; +export { getTelemetryFunction } from './telemetry'; +export type { SavedObjectEmbeddableInput } from './saved_object_embeddable'; +export { isSavedObjectEmbeddableInput } from './saved_object_embeddable'; diff --git a/src/plugins/interactive_setup/public/theme/utils.ts b/src/plugins/interactive_setup/public/theme/utils.ts index 55730974afc16..052804073f226 100644 --- a/src/plugins/interactive_setup/public/theme/utils.ts +++ b/src/plugins/interactive_setup/public/theme/utils.ts @@ -6,14 +6,14 @@ * Side Public License, v 1. */ -import type { EuiThemeColorMode } from '@elastic/eui/src/services/theme/types'; +import { COLOR_MODES_STANDARD } from '@elastic/eui'; +import type { EuiThemeColorModeStandard } from '@elastic/eui'; import type { CoreTheme } from '../../../../core/public'; /** * Copied from the `kibana_react` plugin, remove once https://github.com/elastic/kibana/issues/119204 is implemented. */ -export const getColorMode = (theme: CoreTheme): EuiThemeColorMode => { - // COLOR_MODES_STANDARD is not exported from eui - return theme.darkMode ? 'DARK' : 'LIGHT'; +export const getColorMode = (theme: CoreTheme): EuiThemeColorModeStandard => { + return theme.darkMode ? COLOR_MODES_STANDARD.dark : COLOR_MODES_STANDARD.light; }; 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 1cf6a3409539e..b05abbcece0b9 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 @@ -215,6 +215,7 @@ exports[` is rendered 1`] = ` " >

+