diff --git a/.buildkite/pipelines/pull_request/scout_ui_tests.yml b/.buildkite/pipelines/pull_request/scout_ui_tests.yml
new file mode 100644
index 0000000000000..37ea1567c4f42
--- /dev/null
+++ b/.buildkite/pipelines/pull_request/scout_ui_tests.yml
@@ -0,0 +1,18 @@
+steps:
+ - command: .buildkite/scripts/steps/functional/scout_ui_tests.sh
+ label: 'Scout UI Tests'
+ agents:
+ machineType: n2-standard-4
+ preemptible: true
+ depends_on:
+ - build
+ - quick_checks
+ - checks
+ - linting
+ - linting_with_types
+ - check_types
+ timeout_in_minutes: 30
+ retry:
+ automatic:
+ - exit_status: '-1'
+ limit: 2
diff --git a/.buildkite/scripts/pipelines/pull_request/pipeline.ts b/.buildkite/scripts/pipelines/pull_request/pipeline.ts
index ab0c84e5eb93d..403dbe53350f8 100644
--- a/.buildkite/scripts/pipelines/pull_request/pipeline.ts
+++ b/.buildkite/scripts/pipelines/pull_request/pipeline.ts
@@ -302,7 +302,7 @@ const getPipeline = (filename: string, removeSteps = true) => {
/^packages\/kbn-grouping/,
/^packages\/kbn-resizable-layout/,
/^packages\/kbn-rison/,
- /^packages\/kbn-rule-data-utils/,
+ /^src\/platform\/packages\/shared\/kbn-rule-data-utils/,
/^packages\/kbn-safer-lodash-set/,
/^packages\/kbn-search-types/,
/^packages\/kbn-securitysolution-.*/,
@@ -386,6 +386,16 @@ const getPipeline = (filename: string, removeSteps = true) => {
);
}
+ if (
+ (await doAnyChangesMatch([
+ /^x-pack\/plugins\/discover_enhanced\/ui_tests/,
+ /^packages\/kbn-scout/,
+ ])) ||
+ GITHUB_PR_LABELS.includes('ci:scout-ui-tests')
+ ) {
+ pipeline.push(getPipeline('.buildkite/pipelines/pull_request/scout_ui_tests.yml'));
+ }
+
pipeline.push(getPipeline('.buildkite/pipelines/pull_request/post_build.yml'));
// remove duplicated steps
diff --git a/.buildkite/scripts/steps/code_generation/security_solution_codegen.sh b/.buildkite/scripts/steps/code_generation/security_solution_codegen.sh
index 13bd0aaf7189a..5f140efc5db8d 100755
--- a/.buildkite/scripts/steps/code_generation/security_solution_codegen.sh
+++ b/.buildkite/scripts/steps/code_generation/security_solution_codegen.sh
@@ -7,7 +7,7 @@ source .buildkite/scripts/common/util.sh
echo --- Security Solution OpenAPI Code Generation
echo -e "\n[Security Solution OpenAPI Code Generation] OpenAPI Common Package\n"
-(cd packages/kbn-openapi-common && yarn openapi:generate)
+(cd src/platform/packages/shared/kbn-openapi-common && yarn openapi:generate)
echo -e "\n[Security Solution OpenAPI Code Generation] Lists Common Package\n"
(cd x-pack/solutions/security/packages/kbn-securitysolution-lists-common && yarn openapi:generate)
diff --git a/.buildkite/scripts/steps/functional/scout_ui_tests.sh b/.buildkite/scripts/steps/functional/scout_ui_tests.sh
new file mode 100755
index 0000000000000..652749bbfa89a
--- /dev/null
+++ b/.buildkite/scripts/steps/functional/scout_ui_tests.sh
@@ -0,0 +1,13 @@
+#!/usr/bin/env bash
+
+set -euo pipefail
+
+source .buildkite/scripts/steps/functional/common.sh
+
+export JOB=kibana-scout-ui-tests
+
+TEST_CONFIG="x-pack/plugins/discover_enhanced/ui_tests/playwright.config.ts"
+KIBANA_DIR="$KIBANA_BUILD_LOCATION"
+
+echo "--- Stateful: 'discover_enhanced' plugin UI Tests"
+node scripts/scout run-tests --stateful --config "$TEST_CONFIG" --kibana-install-dir "$KIBANA_DIR"
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index dc9a8e3887c80..988ef63ca4877 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -683,7 +683,7 @@ x-pack/packages/observability/observability_utils/observability_utils_server @el
x-pack/test/security_api_integration/plugins/oidc_provider @elastic/kibana-security
test/common/plugins/otel_metrics @elastic/obs-ux-infra_services-team
packages/kbn-openapi-bundler @elastic/security-detection-rule-management
-packages/kbn-openapi-common @elastic/security-detection-rule-management
+src/platform/packages/shared/kbn-openapi-common @elastic/security-detection-rule-management
packages/kbn-openapi-generator @elastic/security-detection-rule-management
packages/kbn-optimizer @elastic/kibana-operations
packages/kbn-optimizer-webpack-helpers @elastic/kibana-operations
@@ -758,7 +758,7 @@ packages/kbn-router-to-openapispec @elastic/kibana-core
packages/kbn-router-utils @elastic/obs-ux-logs-team
examples/routing_example @elastic/kibana-core
packages/kbn-rrule @elastic/response-ops
-packages/kbn-rule-data-utils @elastic/security-detections-response @elastic/response-ops @elastic/obs-ux-management-team
+src/platform/packages/shared/kbn-rule-data-utils @elastic/security-detections-response @elastic/response-ops @elastic/obs-ux-management-team
x-pack/plugins/rule_registry @elastic/response-ops @elastic/obs-ux-management-team
x-pack/platform/plugins/private/runtime_fields @elastic/kibana-management
packages/kbn-safer-lodash-set @elastic/kibana-security
@@ -1039,7 +1039,7 @@ packages/kbn-whereis-pkg-cli @elastic/kibana-operations
packages/kbn-xstate-utils @elastic/obs-ux-logs-team
packages/kbn-yarn-lock-validator @elastic/kibana-operations
packages/kbn-zod @elastic/kibana-core
-packages/kbn-zod-helpers @elastic/security-detection-rule-management
+src/platform/packages/shared/kbn-zod-helpers @elastic/security-detection-rule-management
####
## Everything below this line overrides the default assignments for each package.
## Items lower in the file have higher precedence:
diff --git a/dev_docs/key_concepts/building_blocks.mdx b/dev_docs/key_concepts/building_blocks.mdx
index 29cf2df7a764f..1afac686d1adc 100644
--- a/dev_docs/key_concepts/building_blocks.mdx
+++ b/dev_docs/key_concepts/building_blocks.mdx
@@ -42,7 +42,7 @@ and . Every feature that is added to a registered (Lens, Maps, Saved Searches and more) will be available automatically, as well as any that are added to the Embeddable context menu panel (for example, drilldowns, custom panel time ranges, and "share to" features).
+with the . Every feature that is added to a registered (Lens, Maps, Discover sessions and more) will be available automatically, as well as any that are added to the Embeddable context menu panel (for example, drilldowns, custom panel time ranges, and "share to" features).
The Dashboard Embeddable is one of the highest-level UI components you can add to your application.
diff --git a/dev_docs/tutorials/performance/adding_custom_performance_metrics.mdx b/dev_docs/tutorials/performance/adding_custom_performance_metrics.mdx
index 41570826ad2bd..7ebd918f4a331 100644
--- a/dev_docs/tutorials/performance/adding_custom_performance_metrics.mdx
+++ b/dev_docs/tutorials/performance/adding_custom_performance_metrics.mdx
@@ -298,7 +298,7 @@ This event will be indexed with the following structure:
The meta field supports telemetry on time ranges, providing calculated metrics for enhanced context. This includes:
-- **Query range in ceconds:**
+- **Query range in seconds:**
- Calculated as the time difference in seconds between `rangeFrom` and `rangeTo`.
diff --git a/docs/concepts/data-views.asciidoc b/docs/concepts/data-views.asciidoc
index 02922b2989762..eb090554186a8 100644
--- a/docs/concepts/data-views.asciidoc
+++ b/docs/concepts/data-views.asciidoc
@@ -166,7 +166,7 @@ clusters or indicies from cross-cluster search].
When you delete a {data-source}, you cannot recover the associated field formatters, runtime fields, source filters,
and field popularity data. Deleting a {data-source} does not remove any indices or data documents from {es}.
-WARNING: Deleting a {data-source} breaks all visualizations, saved searches, and other saved objects that reference the data view.
+WARNING: Deleting a {data-source} breaks all visualizations, saved Discover sessions, and other saved objects that reference the data view.
. Go to the **Data Views** management page using the navigation menu or the <>.
diff --git a/docs/concepts/esql.asciidoc b/docs/concepts/esql.asciidoc
index a3a091a4c6d0a..0b9af290c2d8d 100644
--- a/docs/concepts/esql.asciidoc
+++ b/docs/concepts/esql.asciidoc
@@ -26,7 +26,7 @@ disabled using the `enableESQL` setting from the
{kibana-ref}/advanced-options.html[Advanced Settings].
This will hide the {esql} user interface from various applications.
-However, users will be able to access existing {esql} artifacts like saved searches and visualizations.
+However, users will be able to access existing {esql} artifacts like saved Discover sessions and visualizations.
====
[float]
diff --git a/docs/concepts/save-query.asciidoc b/docs/concepts/save-query.asciidoc
index b249f7e9aea26..a4d6dd28ea6e1 100644
--- a/docs/concepts/save-query.asciidoc
+++ b/docs/concepts/save-query.asciidoc
@@ -11,10 +11,10 @@ Save this query, and you can embed the search results in dashboards,
use them as a foundation for building a visualization,
and share them in a link or CVS form.
-Saved queries are different than <>,
+Saved queries are different than <>,
which include the *Discover* configuration—selected columns in the document table, sort order, and
{data-source}—in addition to the query.
-Saved searches are primarily used for adding search results to a dashboard.
+Discover sessions are primarily used for adding search results to a dashboard.
[role="xpack"]
==== Read-only access
diff --git a/docs/developer/plugin-list.asciidoc b/docs/developer/plugin-list.asciidoc
index 60db19c0ca09f..9a783e0274b01 100644
--- a/docs/developer/plugin-list.asciidoc
+++ b/docs/developer/plugin-list.asciidoc
@@ -309,6 +309,7 @@ oss plugins.
|{kib-repo}blob/{branch}/src/plugins/saved_search/README.md[savedSearch]
|Contains the saved search saved object definition and helpers.
+This object is created when a user saves their current session in the Discover app.
|{kib-repo}blob/{branch}/src/plugins/screenshot_mode/README.md[screenshotMode]
diff --git a/docs/discover/document-explorer.asciidoc b/docs/discover/document-explorer.asciidoc
index 47b4a5bc3fcfd..d026cf2930f1f 100644
--- a/docs/discover/document-explorer.asciidoc
+++ b/docs/discover/document-explorer.asciidoc
@@ -36,7 +36,7 @@ In the pop-up, drag the column names to their new order.
* To resize a column, drag the right edge of the column header until the column is the width that you want.
+
-Column widths are stored with a saved search. When you visualize saved searches on dashboards, the saved search appears the same as in **Discover**.
+Column widths are stored with a Discover session. When you add a Discover session as a dashboard panel, it appears the same as in **Discover**.
[float]
[[document-explorer-density]]
diff --git a/docs/discover/get-started-discover.asciidoc b/docs/discover/get-started-discover.asciidoc
index ec44f977f4aac..f3ffcc92b582d 100644
--- a/docs/discover/get-started-discover.asciidoc
+++ b/docs/discover/get-started-discover.asciidoc
@@ -293,24 +293,24 @@ Learn more about how to use ES|QL queries in <>.
[float]
[[save-discover-search]]
-==== Save your search for later use
+==== Save your Discover session for later use
-Save your search so you can use it later, generate a CSV report, or use it to create visualizations, dashboards, and Canvas workpads.
-Saving a search saves the query text, filters,
+Save your Discover session so you can use it later, generate a CSV report, or use it to create visualizations, dashboards, and Canvas workpads.
+Saving a Discover session saves the query text, filters,
and current view of *Discover*, including the columns selected in
the document table, the sort order, and the {data-source}.
. In the application menu bar, click **Save**.
-. Give your search a title and a description.
+. Give your session a title and a description.
-. Optionally store <> and the time range with the search.
+. Optionally store <> and the time range with the session.
. Click **Save**.
[float]
[[share-your-findings]]
-==== Share your search
+==== Share your Discover session
To share your search and **Discover** view with a larger audience, click *Share* in the application menu bar.
For detailed information about the sharing options, refer to <>.
diff --git a/docs/discover/save-search.asciidoc b/docs/discover/save-search.asciidoc
index 024fd97ab107b..d661e8c01b830 100644
--- a/docs/discover/save-search.asciidoc
+++ b/docs/discover/save-search.asciidoc
@@ -1,9 +1,9 @@
[[save-open-search]]
-== Save a search for reuse
+== Save a Discover session for reuse
-A saved search is a convenient way to reuse a search
+A saved Discover session is a convenient way to reuse a search
that you've created in *Discover*.
-Saved searches are good for adding search results to a dashboard,
+Discover sessions are good for saving a configured view of Discover to use later or adding search results to a dashboard,
and can also serve as a foundation for building visualizations.
[role="xpack"]
@@ -16,27 +16,27 @@ displayed and the *Save* button is not visible. For more information, refer to <
[role="screenshot"]
image::discover/images/read-only-badge.png[Example of Discover's read only access indicator in Kibana's header]
[float]
-=== Save a search
+=== Save a Discover session
-By default, a saved search stores the query text, filters, and
+By default, a Discover session stores the query text, filters, and
current view of *Discover*, including the columns and sort order in the document table, and the {data-source}.
-. Once you've created a search worth saving, click *Save* in the toolbar.
-. Enter a name for the search.
-. Optionally store <> and the time range with the search.
+. Once you've created a view worth saving, click *Save* in the toolbar.
+. Enter a name for the session.
+. Optionally store <> and the time range with the session.
. Click *Save*.
-. To reload your search results in *Discover*, click *Open* in the toolbar, and select the saved search.
+. To reload your search results in *Discover*, click *Open* in the toolbar, and select the saved Discover session.
+
-If the saved search is associated with a different {data-source} than is currently
-selected, opening the saved search changes the selected {data-source}. The query language
-used for the saved search is also automatically selected.
+If the saved Discover session is associated with a different {data-source} than is currently
+selected, opening the saved Discover session changes the selected {data-source}. The query language
+used for the saved Discover session is also automatically selected.
[float]
-=== Duplicate a search
-. In **Discover**, open the search that you want to duplicate.
+=== Duplicate a Discover session
+. In **Discover**, open the Discover session that you want to duplicate.
. In the toolbar, click *Save*.
-. Give the search a new name.
-. Turn on **Save as new search**.
+. Give the session a new name.
+. Turn on **Save as new Discover session**.
. Click *Save*.
@@ -46,5 +46,5 @@ used for the saved search is also automatically selected.
. Go to *Dashboards*.
. Open or create the dashboard, then click *Edit*.
. Click *Add from library*.
-. From the *Types* dropdown, select *Saved search*.
-. Select the saved search that you want to visualize, then click *X* to close the list.
+. From the *Types* dropdown, select *Discover session*.
+. Select the Discover session that you want to add, then click *X* to close the list.
diff --git a/docs/discover/search-sessions.asciidoc b/docs/discover/search-sessions.asciidoc
index fe1e945e676ff..5d6b4a2d00435 100644
--- a/docs/discover/search-sessions.asciidoc
+++ b/docs/discover/search-sessions.asciidoc
@@ -52,7 +52,7 @@ image::images/search-session-awhile.png[Search Session indicator displaying the
Once you save a search session, you can start a new search,
navigate to a different application, or close the browser.
-. To view your saved searches, go to the
+. To view your saved search sessions, go to the
*Search Sessions* management page using the navigation menu or the <>.
For a saved or completed session, you can also open this view from the search sessions popup.
diff --git a/docs/discover/search.asciidoc b/docs/discover/search.asciidoc
index 439c5c443cc02..c7fde4159ec98 100644
--- a/docs/discover/search.asciidoc
+++ b/docs/discover/search.asciidoc
@@ -92,10 +92,10 @@ status:[400 TO 499] AND (extension:php OR extension:html)
[[save-open-search]]
-=== Save a search
-A saved search persists your current view of Discover for later retrieval and reuse. You can reload a saved search into Discover, add it to a dashboard, and use it as the basis for a visualization.
+=== Save a Discover session
+A saved Discover session persists your current view of Discover for later retrieval and reuse. You can reload a saved session into Discover, add it to a dashboard, and use it as the basis for a visualization.
-A saved search includes the query text, filters, and optionally, the time filter. A saved search also includes the selected columns in the document table, the sort order, and the current index pattern.
+A Discover session includes the query text, filters, and optionally, the time filter. A Discover session also includes the selected columns in the document table, the sort order, and the current {data-source}.
[role="xpack"]
[[discover-read-only-access]]
@@ -107,23 +107,23 @@ Kibana see <>.
[role="screenshot"]
image::discover/images/read-only-badge.png[Example of Discover's read only access indicator in Kibana's header]
-==== Save a search
-To save the current search:
+==== Save a Discover session
+To save the current session:
. Click *Save* in the toolbar.
-. Enter a name for the search and click *Save*.
+. Enter a name for the session and click *Save*.
-To import, export, and delete saved searches, go to the *Saved Objects* management page using the navigation menu or the <>.
+To import, export, and delete saved Discover sessions, go to the *Saved Objects* management page using the navigation menu or the <>.
-==== Open a saved search
-To load a saved search into Discover:
+==== Open a saved Discover session
+To load a saved session into Discover:
. Click *Open* in the toolbar.
-. Select the search you want to open.
+. Select the session you want to open.
-If the saved search is associated with a different index pattern than is currently
-selected, opening the saved search changes the selected index pattern. The query language
-used for the saved search will also be automatically selected.
+If the saved Discover session is associated with a different {data-source} than is currently
+selected, opening the saved Discover session changes the selected {data-source}. The query language
+used for the saved Discover session will also be automatically selected.
[[save-load-delete-query]]
=== Save a query
@@ -133,7 +133,7 @@ A saved query is a portable collection of query text and filters that you can re
* View the results of the same query in multiple apps
* Share your query
-Saved queries don't include information specific to Discover, such as the currently selected columns in the document table, the sort order, and the index pattern. If you want to save your current view of Discover for later retrieval and reuse, create a <> instead.
+Saved queries don't include information specific to Discover, such as the currently selected columns in the document table, the sort order, and the {data-source}. If you want to save your current view of Discover for later retrieval and reuse, create a <> instead.
[role="xpack"]
==== Read-only access
diff --git a/docs/fleet/fleet.asciidoc b/docs/fleet/fleet.asciidoc
index 52c2825557001..366d28fae3f5e 100644
--- a/docs/fleet/fleet.asciidoc
+++ b/docs/fleet/fleet.asciidoc
@@ -18,7 +18,7 @@ It is recommended for advanced users only.
[role="screenshot"]
image::fleet/images/fleet-start.png[{fleet} app in {kib}]
-Most integration content installed by {fleet} isn’t editable. This content is tagged with a **Managed** badge in the {kib} UI. Managed content itself cannot be edited or deleted, however managed visualizations, dashboards, and saved searches can be cloned.
+Most integration content installed by {fleet} isn’t editable. This content is tagged with a **Managed** badge in the {kib} UI. Managed content itself cannot be edited or deleted, however managed visualizations, dashboards, and Discover sessions can be cloned.
[role="screenshot"]
image::fleet/images/system-managed.png[An image of the new managed badge.]
@@ -37,7 +37,7 @@ To clone a dashboard:
. Click *Save and return* after editing the dashboard.
. Click *Save*.
-To clone managed content relating to specific visualization editors, such as Lens, TSVB, and Maps, view the visualization in the editor then begin to make edits. Unlike cloning dashboards, and dashboard panels, the cloned content retains the original configurations. Once finished you are prompted to save the edits as a new visualization. The same applies for altering any saved searches in a managed visualization.
+To clone managed content relating to specific visualization editors, such as Lens, TSVB, and Maps, view the visualization in the editor then begin to make edits. Unlike cloning dashboards, and dashboard panels, the cloned content retains the original configurations. Once finished you are prompted to save the edits as a new visualization. The same applies for altering any linked Discover sessions in a managed visualization.
[float]
== Get started
diff --git a/docs/management/advanced-options.asciidoc b/docs/management/advanced-options.asciidoc
index f6b8e6844ce04..631ca58416bd4 100644
--- a/docs/management/advanced-options.asciidoc
+++ b/docs/management/advanced-options.asciidoc
@@ -321,7 +321,7 @@ When disabled, *Discover* loads fields using the {es} search API's
[[discover-searchonpageload]]`discover:searchOnPageLoad`::
Controls whether a search is executed when *Discover* first loads. This setting
-does not have an effect when loading a saved search.
+does not have an effect when loading a saved Discover session.
[[discover:showFieldStatistics]]`discover:showFieldStatistics`::
beta[] Enables the Field statistics view. Examine details such as
@@ -334,10 +334,10 @@ Controls the display of multi-fields in the expanded document view.
The default sort direction for time-based data views.
[[doctable-hidetimecolumn]]`doc_table:hideTimeColumn`::
-Hides the "Time" column in *Discover* and in all saved searches on dashboards.
+Hides the "Time" column in *Discover* and in all Discover session panels on dashboards.
[[doctable-highlight]]`doc_table:highlight`::
-Highlights results in *Discover* and saved searches on dashboards. Highlighting
+Highlights search results in *Discover* and Discover session panels on dashboards. Highlighting
slows requests when working on big documents.
[[doctable-legacy]]`doc_table:legacy`::
diff --git a/docs/setup/configuring-reporting.asciidoc b/docs/setup/configuring-reporting.asciidoc
index 990e814267ae6..a76bc6ed3db52 100644
--- a/docs/setup/configuring-reporting.asciidoc
+++ b/docs/setup/configuring-reporting.asciidoc
@@ -134,8 +134,8 @@ PUT :/api/security/role/custom_reporting_user
// CONSOLE
<1> Grants access to generate PNG and PDF reports in *Dashboard*.
-<2> Grants access to generate CSV reports from saved search panels in *Dashboard*.
-<3> Grants access to generate CSV reports from saved searches in *Discover*.
+<2> Grants access to generate CSV reports from saved Discover session panels in *Dashboard*.
+<3> Grants access to generate CSV reports from saved Discover sessions in *Discover*.
<4> Grants access to generate PDF reports in *Canvas*.
<5> Grants access to generate PNG and PDF reports in *Visualize Library*.
@@ -170,8 +170,8 @@ PUT localhost:5601/api/security/role/custom_reporting_user
---------------------------------------------------------------
// CONSOLE
-<1> Grants access to generate CSV reports from saved searches in *Discover*.
-<2> Grants access to generate CSV reports from saved search panels in *Dashboard*.
+<1> Grants access to generate CSV reports from saved Discover sessions in *Discover*.
+<2> Grants access to generate CSV reports from saved Discover session panels in *Dashboard*.
[float]
[[grant-user-access-external-provider]]
diff --git a/docs/user/dashboard/aggregation-based.asciidoc b/docs/user/dashboard/aggregation-based.asciidoc
index f27d60928e6fe..e3f1f0bea6718 100644
--- a/docs/user/dashboard/aggregation-based.asciidoc
+++ b/docs/user/dashboard/aggregation-based.asciidoc
@@ -7,7 +7,7 @@ With aggregation-based visualizations, you can:
* Split charts up to three aggregation levels, which is more than *Lens* and *TSVB*
* Create visualization with non-time series data
-* Use a <> as an input
+* Use a <> as an input
* Sort data tables and use the summary row and percentage column features
* Assign colors to data series
* Extend features with plugins
@@ -112,7 +112,7 @@ Choose the type of visualization you want to create, then use the editor to conf
.. Select the data source you want to visualize.
+
-NOTE: There is no performance impact on the data source you select. For example, *Discover* saved searches perform the same as {data-sources}.
+NOTE: There is no performance impact on the data source you select. For example, saved Discover sessions perform the same as {data-sources}.
. Add the <> you want to visualize using the editor, then click *Update*.
+
diff --git a/docs/user/dashboard/create-visualizations.asciidoc b/docs/user/dashboard/create-visualizations.asciidoc
index 815f46d5711eb..f0cf95733a972 100644
--- a/docs/user/dashboard/create-visualizations.asciidoc
+++ b/docs/user/dashboard/create-visualizations.asciidoc
@@ -163,9 +163,9 @@ To enable series data interactions, configure <> data in *Discover*.
+* *Discover session interactions* — Opens <> data in *Discover*.
+
-To use saved search interactions, open the panel menu, then click *More > View saved search*.
+To use saved Discover session interactions, open the panel menu, then click *More > View Discover session*.
[[edit-panels]]
=== Edit panels
diff --git a/docs/user/dashboard/lens.asciidoc b/docs/user/dashboard/lens.asciidoc
index 3c2a120d167d9..525ff8d7bfb6a 100644
--- a/docs/user/dashboard/lens.asciidoc
+++ b/docs/user/dashboard/lens.asciidoc
@@ -668,10 +668,10 @@ For area, line, and bar charts, press Shift, then click the series in the legend
[discrete]
[[is-it-possible-to-use-saved-serches-in-lens]]
-.*How do I visualize saved searches?*
+.*How do I visualize saved Discover sessions?*
[%collapsible]
====
-Visualizing saved searches in unsupported.
+Visualizing saved Discover sessions in unsupported.
====
[discrete]
diff --git a/docs/user/dashboard/tsvb.asciidoc b/docs/user/dashboard/tsvb.asciidoc
index e8e7cec488007..15433b19b6fc9 100644
--- a/docs/user/dashboard/tsvb.asciidoc
+++ b/docs/user/dashboard/tsvb.asciidoc
@@ -233,7 +233,7 @@ For example `https://example.org/{{key}}`
This instructs TSVB to substitute the value from your visualization wherever it sees `{{key}}`.
-If your data contain reserved or invalid URL characters such as "#" or "&", you should apply a transform to URL-encode the key like this `{{encodeURIComponent key}}`. If you are dynamically constructing a drilldown to another location in Kibana (for example, clicking a table row takes to you a value-scoped saved search), you will likely want to Rison-encode your key as it may contain invalid Rison characters. (https://github.com/Nanonid/rison#rison---compact-data-in-uris[Rison] is the serialization format many parts of Kibana use to store information in their URL.)
+If your data contain reserved or invalid URL characters such as "#" or "&", you should apply a transform to URL-encode the key like this `{{encodeURIComponent key}}`. If you are dynamically constructing a drilldown to another location in Kibana (for example, clicking a table row takes to you a value-scoped Discover session), you will likely want to Rison-encode your key as it may contain invalid Rison characters. (https://github.com/Nanonid/rison#rison---compact-data-in-uris[Rison] is the serialization format many parts of Kibana use to store information in their URL.)
For example: `discover#/view/0ac50180-82d9-11ec-9f4a-55de56b00cc0?_a=(filters:!((query:(match_phrase:(foo.keyword:{{rison key}})))))`
diff --git a/docs/user/management.asciidoc b/docs/user/management.asciidoc
index c46786b98829d..b503dbdc2d0ea 100644
--- a/docs/user/management.asciidoc
+++ b/docs/user/management.asciidoc
@@ -85,7 +85,7 @@ You can add and remove remote clusters, and check their connectivity.
| <>
| Monitor the generation of reports—PDF, PNG, and CSV—and download reports that you previously generated.
-A report can contain a dashboard, visualization, saved search, or Canvas workpad.
+A report can contain a dashboard, visualization, table with Discover search results, or Canvas workpad.
| Machine Learning Jobs
| View, export, and import your <> and
diff --git a/docs/user/ml/index.asciidoc b/docs/user/ml/index.asciidoc
index 91227055fa8a7..92a28a1fdb0c8 100644
--- a/docs/user/ml/index.asciidoc
+++ b/docs/user/ml/index.asciidoc
@@ -168,7 +168,7 @@ It makes it easy to find and investigate causes of unusual spikes or drops by us
Examine the histogram chart of the log rates for a given {data-source}, and find the reason behind a particular change possibly in millions of log events across multiple fields and values.
You can find log rate analysis embedded in multiple applications.
-In {kib}, you can find it under **{ml-app}** > **AIOps Labs** or by using the <>. Here, you can select the {data-source} or saved search that you want to analyze.
+In {kib}, you can find it under **{ml-app}** > **AIOps Labs** or by using the <>. Here, you can select the {data-source} or saved Discover session that you want to analyze.
[role="screenshot"]
image::user/ml/images/ml-log-rate-analysis-before.png[Log event histogram chart]
@@ -203,7 +203,7 @@ and an example document that matches the category.
//end::log-pattern-analysis-intro[]
You can find log pattern analysis under **{ml-app}** > **AIOps Labs** or by using the <>.
-Here, you can select the {data-source} or saved search that you want to analyze, or in
+Here, you can select the {data-source} or saved Discover session that you want to analyze, or in
**Discover** as an available action for any text field.
[role="screenshot"]
@@ -228,7 +228,7 @@ to detect distribution changes, trend changes, and other statistically
significant change points in a metric of your time series data.
You can find change point detection under **{ml-app}** > **AIOps Labs** or by using the <>.
-Here, you can select the {data-source} or saved search that you want to analyze.
+Here, you can select the {data-source} or saved Discover session that you want to analyze.
[role="screenshot"]
image::user/ml/images/ml-change-point-detection.png[Change point detection UI]
diff --git a/docs/user/reporting/automating-report-generation.asciidoc b/docs/user/reporting/automating-report-generation.asciidoc
index b4334b7c7ea80..0b773decd60a7 100644
--- a/docs/user/reporting/automating-report-generation.asciidoc
+++ b/docs/user/reporting/automating-report-generation.asciidoc
@@ -24,7 +24,7 @@ To create the POST URL for CSV reports:
. Go to *Discover*.
-. Open the saved search you want to share.
+. Open the saved Discover session you want to share.
. In the toolbar, click *Share > Export > Copy POST URL*.
@@ -54,7 +54,7 @@ If you experience issues with the deprecated report URLs after you upgrade {kib}
* *Dashboard* reports: `/api/reporting/generate/dashboard/`
* *Visualize Library* reports: `/api/reporting/generate/visualization/`
-* *Discover* saved search reports: `/api/reporting/generate/search/`
+* *Discover* reports: `/api/reporting/generate/search/`
IMPORTANT:
In earlier {kib} versions, you could use the `&sync` parameter to append to report URLs that held the request open until the document was fully generated. The `&sync` parameter is now unsupported. If you use the `&sync` parameter in Watcher, you must update the parameter.
diff --git a/docs/user/reporting/index.asciidoc b/docs/user/reporting/index.asciidoc
index 4425cc45d9b4d..7a52f5d77b10d 100644
--- a/docs/user/reporting/index.asciidoc
+++ b/docs/user/reporting/index.asciidoc
@@ -4,16 +4,16 @@
[partintro]
--
-:frontmatter-description: {kib} provides you with several options to share *Discover* saved searches, dashboards, *Visualize Library* visualizations, and *Canvas* workpads with others, or on a website.
+:frontmatter-description: {kib} provides you with several options to share *Discover* sessions, dashboards, *Visualize Library* visualizations, and *Canvas* workpads with others, or on a website.
:frontmatter-tags-products: [kibana]
-{kib} provides you with several options to share *Discover* saved searches, dashboards, *Visualize Library* visualizations, and *Canvas* workpads. These sharing options are available from the *Share* menu in the toolbar.
+{kib} provides you with several options to share *Discover* sessions, dashboards, *Visualize Library* visualizations, and *Canvas* workpads. These sharing options are available from the *Share* menu in the toolbar.
[float]
[[share-a-direct-link]]
== Share with a direct link
-You can share direct links to saved searches, dashboards, and visualizations. When clicking **Share**, look for the **Links** tab to get the shareable link and copy it.
+You can share direct links to saved Discover sessions, dashboards, and visualizations. When clicking **Share**, look for the **Links** tab to get the shareable link and copy it.
TIP: When sharing an object with unsaved changes, you get a temporary link that might break in the future, for example in case of upgrade. Save the object to get a permanent link instead.
@@ -29,13 +29,13 @@ image::https://images.contentstack.io/v3/assets/bltefdd0b53724fa2ce/blt49f2b5a80
NOTE: For more information on how to configure reporting in {kib}, refer to <>
-Create and download PDF, PNG, or CSV reports of saved searches, dashboards, visualizations, and workpads.
+Create and download PDF, PNG, or CSV reports of saved Discover sessions, dashboards, visualizations, and workpads.
* *PDF* — Generate and download PDF files of dashboards, visualizations, and *Canvas* workpads. PDF reports are a link:https://www.elastic.co/subscriptions[subscription feature].
* *PNG* — Generate and download PNG files of dashboards and visualizations. PNG reports are a link:https://www.elastic.co/subscriptions[subscription feature].
-* *CSV Reports* — Generate CSV reports of saved searches. <>.
+* *CSV Reports* — Generate CSV reports of saved Discover sessions. <>.
* *CSV Download* — Generate and download CSV files of *Lens* visualizations.
@@ -44,7 +44,7 @@ Create and download PDF, PNG, or CSV reports of saved searches, dashboards, visu
[[reporting-layout-sizing]]
The layout and size of the report depends on what you are sharing.
-For saved searches, dashboards, and visualizations, the layout depends on the size of the panels.
+For saved Discover sessions, dashboards, and visualizations, the layout depends on the size of the panels.
For workpads, the layout depends on the size of the worksheet dimensions.
To change the output size, change the size of the browser, which resizes the shareable container before the report generates. It might take some trial and error before you're satisfied.
@@ -54,13 +54,13 @@ In the following dashboard, the shareable container is highlighted:
[role="screenshot"]
image::user/reporting/images/shareable-container.png["Shareable Container"]
-. Open the saved search, dashboard, visualization, or workpad you want to share.
+. Open the saved Discover session, dashboard, visualization, or workpad you want to share.
. From the toolbar, click *Share*, then select the report option.
* If you are creating dashboard PDFs, select *For printing* to create printer-friendly PDFs with multiple A4 portrait pages and two visualizations per page.
+
-NOTE: When you create a dashboard report that includes a data table or saved search, the PDF includes only the visible data.
+NOTE: When you create a dashboard report that includes a data table or Discover session, the PDF includes only the visible data.
* If you are creating workpad PDFs, select *Full page layout* to create PDFs without margins that surround the workpad.
diff --git a/examples/content_management_examples/public/examples/finder/finder_app.tsx b/examples/content_management_examples/public/examples/finder/finder_app.tsx
index b8aaa6fe5f34b..dda034e711180 100644
--- a/examples/content_management_examples/public/examples/finder/finder_app.tsx
+++ b/examples/content_management_examples/public/examples/finder/finder_app.tsx
@@ -37,7 +37,7 @@ export const FinderApp = (props: {
{
type: `search`,
getIconForSavedObject: () => 'discoverApp',
- name: 'Saved search',
+ name: 'Discover session',
},
{
type: 'index-pattern',
diff --git a/oas_docs/bundle.json b/oas_docs/bundle.json
index 5b0e7fd2c1667..ea89bcc578536 100644
--- a/oas_docs/bundle.json
+++ b/oas_docs/bundle.json
@@ -9755,7 +9755,7 @@
},
"/api/spaces/_copy_saved_objects": {
"post": {
- "description": "It also allows you to automatically copy related objects, so when you copy a dashboard, this can automatically copy over the associated visualizations, data views, and saved searches, as required. You can request to overwrite any objects that already exist in the target space if they share an identifier or you can use the resolve copy saved objects conflicts API to do this on a per-object basis.
[Required authorization] Route required privileges: ALL of [copySavedObjectsToSpaces].",
+ "description": "It also allows you to automatically copy related objects, so when you copy a dashboard, this can automatically copy over the associated visualizations, data views, and saved Discover sessions, as required. You can request to overwrite any objects that already exist in the target space if they share an identifier or you can use the resolve copy saved objects conflicts API to do this on a per-object basis.
[Required authorization] Route required privileges: ALL of [copySavedObjectsToSpaces].",
"operationId": "post-spaces-copy-saved-objects",
"parameters": [
{
diff --git a/oas_docs/output/kibana.yaml b/oas_docs/output/kibana.yaml
index 48f5bb0779c49..5027de8b8ce49 100644
--- a/oas_docs/output/kibana.yaml
+++ b/oas_docs/output/kibana.yaml
@@ -11201,6 +11201,7 @@ paths:
- Security Detections API
/api/detection_engine/rules/{id}/exceptions:
post:
+ description: Create exception items that apply to a single detection rule.
operationId: CreateRuleExceptionListItems
parameters:
- description: Detection rule's identifier
@@ -11258,7 +11259,7 @@ paths:
schema:
$ref: '#/components/schemas/Security_Exceptions_API_SiemErrorResponse'
description: Internal server error response
- summary: Creates rule exception list items
+ summary: Create rule exception list items
tags:
- Security Exceptions API
/api/detection_engine/rules/prepackaged:
@@ -13330,6 +13331,7 @@ paths:
- Security Entity Analytics API
/api/exception_lists:
delete:
+ description: Delete an exception list using the `id` or `list_id` field.
operationId: DeleteExceptionList
parameters:
- description: Either `id` or `list_id` must be specified
@@ -13389,10 +13391,11 @@ paths:
schema:
$ref: '#/components/schemas/Security_Exceptions_API_SiemErrorResponse'
description: Internal server error response
- summary: Deletes an exception list
+ summary: Delete an exception list
tags:
- Security Exceptions API
get:
+ description: Get the details of an exception list using the `id` or `list_id` field.
operationId: ReadExceptionList
parameters:
- description: Either `id` or `list_id` must be specified
@@ -13452,10 +13455,14 @@ paths:
schema:
$ref: '#/components/schemas/Security_Exceptions_API_SiemErrorResponse'
description: Internal server error response
- summary: Retrieves an exception list using its `id` or `list_id` field
+ summary: Get exception list details
tags:
- Security Exceptions API
post:
+ description: |
+ An exception list groups exception items and can be associated with detection rules. You can assign detection rules with multiple exception lists.
+ > info
+ > All exception items added to the same list are evaluated using `OR` logic. That is, if any of the items in a list evaluate to `true`, the exception prevents the rule from generating an alert. Likewise, `OR` logic is used for evaluating exceptions when more than one exception list is assigned to a rule. To use the `AND` operator, you can define multiple clauses (`entries`) in a single exception item.
operationId: CreateExceptionList
requestBody:
content:
@@ -13529,10 +13536,11 @@ paths:
schema:
$ref: '#/components/schemas/Security_Exceptions_API_SiemErrorResponse'
description: Internal server error response
- summary: Creates an exception list
+ summary: Create an exception list
tags:
- Security Exceptions API
put:
+ description: Update an exception list using the `id` or `list_id` field.
operationId: UpdateExceptionList
requestBody:
content:
@@ -13609,11 +13617,12 @@ paths:
schema:
$ref: '#/components/schemas/Security_Exceptions_API_SiemErrorResponse'
description: Internal server error response
- summary: Updates an exception list
+ summary: Update an exception list
tags:
- Security Exceptions API
/api/exception_lists/_duplicate:
post:
+ description: Duplicate an existing exception list.
operationId: DuplicateExceptionList
parameters:
- description: Exception list's human identifier
@@ -13676,12 +13685,12 @@ paths:
schema:
$ref: '#/components/schemas/Security_Exceptions_API_SiemErrorResponse'
description: Internal server error response
- summary: Duplicates an exception list
+ summary: Duplicate an exception list
tags:
- Security Exceptions API
/api/exception_lists/_export:
post:
- description: Exports an exception list and its associated items to an .ndjson file
+ description: Export an exception list and its associated items to an NDJSON file.
operationId: ExportExceptionList
parameters:
- description: Exception list's identifier
@@ -13752,11 +13761,12 @@ paths:
schema:
$ref: '#/components/schemas/Security_Exceptions_API_SiemErrorResponse'
description: Internal server error response
- summary: Exports an exception list
+ summary: Export an exception list
tags:
- Security Exceptions API
/api/exception_lists/_find:
get:
+ description: Get a list of all exception lists.
operationId: FindExceptionLists
parameters:
- description: |
@@ -13864,12 +13874,12 @@ paths:
schema:
$ref: '#/components/schemas/Security_Exceptions_API_SiemErrorResponse'
description: Internal server error response
- summary: Finds exception lists
+ summary: Get exception lists
tags:
- Security Exceptions API
/api/exception_lists/_import:
post:
- description: Imports an exception list and associated items
+ description: Import an exception list and its associated items from an NDJSON file.
operationId: ImportExceptionList
parameters:
- description: |
@@ -13973,11 +13983,12 @@ paths:
schema:
$ref: '#/components/schemas/Security_Exceptions_API_SiemErrorResponse'
description: Internal server error response
- summary: Imports an exception list
+ summary: Import an exception list
tags:
- Security Exceptions API
/api/exception_lists/items:
delete:
+ description: Delete an exception list item using the `id` or `item_id` field.
operationId: DeleteExceptionListItem
parameters:
- description: Either `id` or `item_id` must be specified
@@ -14037,10 +14048,11 @@ paths:
schema:
$ref: '#/components/schemas/Security_Exceptions_API_SiemErrorResponse'
description: Internal server error response
- summary: Deletes an exception list item
+ summary: Delete an exception list item
tags:
- Security Exceptions API
get:
+ description: Get the details of an exception list item using the `id` or `item_id` field.
operationId: ReadExceptionListItem
parameters:
- description: Either `id` or `item_id` must be specified
@@ -14100,10 +14112,14 @@ paths:
schema:
$ref: '#/components/schemas/Security_Exceptions_API_SiemErrorResponse'
description: Internal server error response
- summary: Gets an exception list item
+ summary: Get an exception list item
tags:
- Security Exceptions API
post:
+ description: |
+ Create an exception item and associate it with the specified exception list.
+ > info
+ > Before creating exception items, you must create an exception list.
operationId: CreateExceptionListItem
requestBody:
content:
@@ -14187,10 +14203,11 @@ paths:
schema:
$ref: '#/components/schemas/Security_Exceptions_API_SiemErrorResponse'
description: Internal server error response
- summary: Creates an exception list item
+ summary: Create an exception list item
tags:
- Security Exceptions API
put:
+ description: Update an exception list item using the `id` or `item_id` field.
operationId: UpdateExceptionListItem
requestBody:
content:
@@ -14278,11 +14295,12 @@ paths:
schema:
$ref: '#/components/schemas/Security_Exceptions_API_SiemErrorResponse'
description: Internal server error response
- summary: Updates an exception list item
+ summary: Update an exception list item
tags:
- Security Exceptions API
/api/exception_lists/items/_find:
get:
+ description: Get a list of all exception list items in the specified list.
operationId: FindExceptionListItems
parameters:
- description: List's id
@@ -14410,11 +14428,12 @@ paths:
schema:
$ref: '#/components/schemas/Security_Exceptions_API_SiemErrorResponse'
description: Internal server error response
- summary: Finds exception list items
+ summary: Get exception list items
tags:
- Security Exceptions API
/api/exception_lists/summary:
get:
+ description: Get a summary of the specified exception list.
operationId: ReadExceptionListSummary
parameters:
- description: Exception list's identifier generated upon creation
@@ -14493,11 +14512,15 @@ paths:
schema:
$ref: '#/components/schemas/Security_Exceptions_API_SiemErrorResponse'
description: Internal server error response
- summary: Retrieves an exception list summary
+ summary: Get an exception list summary
tags:
- Security Exceptions API
/api/exceptions/shared:
post:
+ description: |
+ An exception list groups exception items and can be associated with detection rules. A shared exception list can apply to multiple detection rules.
+ > info
+ > All exception items added to the same list are evaluated using `OR` logic. That is, if any of the items in a list evaluate to `true`, the exception prevents the rule from generating an alert. Likewise, `OR` logic is used for evaluating exceptions when more than one exception list is assigned to a rule. To use the `AND` operator, you can define multiple clauses (`entries`) in a single exception item.
operationId: CreateSharedExceptionList
requestBody:
content:
@@ -14552,7 +14575,7 @@ paths:
schema:
$ref: '#/components/schemas/Security_Exceptions_API_SiemErrorResponse'
description: Internal server error response
- summary: Creates a shared exception list
+ summary: Create a shared exception list
tags:
- Security Exceptions API
/api/fleet/agent_download_sources:
@@ -21797,7 +21820,7 @@ paths:
- roles
/api/spaces/_copy_saved_objects:
post:
- description: 'It also allows you to automatically copy related objects, so when you copy a dashboard, this can automatically copy over the associated visualizations, data views, and saved searches, as required. You can request to overwrite any objects that already exist in the target space if they share an identifier or you can use the resolve copy saved objects conflicts API to do this on a per-object basis.
[Required authorization] Route required privileges: ALL of [copySavedObjectsToSpaces].'
+ description: 'It also allows you to automatically copy related objects, so when you copy a dashboard, this can automatically copy over the associated visualizations, data views, and saved Discover sessions, as required. You can request to overwrite any objects that already exist in the target space if they share an identifier or you can use the resolve copy saved objects conflicts API to do this on a per-object basis.
[Required authorization] Route required privileges: ALL of [copySavedObjectsToSpaces].'
operationId: post-spaces-copy-saved-objects
parameters:
- description: A required header to protect against CSRF attacks
diff --git a/package.json b/package.json
index 7464cea2fb9d0..12e17e0d91001 100644
--- a/package.json
+++ b/package.json
@@ -711,7 +711,7 @@
"@kbn/observability-utils-server": "link:x-pack/packages/observability/observability_utils/observability_utils_server",
"@kbn/oidc-provider-plugin": "link:x-pack/test/security_api_integration/plugins/oidc_provider",
"@kbn/open-telemetry-instrumented-plugin": "link:test/common/plugins/otel_metrics",
- "@kbn/openapi-common": "link:packages/kbn-openapi-common",
+ "@kbn/openapi-common": "link:src/platform/packages/shared/kbn-openapi-common",
"@kbn/osquery-io-ts-types": "link:src/platform/packages/shared/kbn-osquery-io-ts-types",
"@kbn/osquery-plugin": "link:x-pack/platform/plugins/shared/osquery",
"@kbn/paertial-results-example-plugin": "link:examples/partial_results_example",
@@ -770,7 +770,7 @@
"@kbn/router-utils": "link:packages/kbn-router-utils",
"@kbn/routing-example-plugin": "link:examples/routing_example",
"@kbn/rrule": "link:packages/kbn-rrule",
- "@kbn/rule-data-utils": "link:packages/kbn-rule-data-utils",
+ "@kbn/rule-data-utils": "link:src/platform/packages/shared/kbn-rule-data-utils",
"@kbn/rule-registry-plugin": "link:x-pack/plugins/rule_registry",
"@kbn/runtime-fields-plugin": "link:x-pack/platform/plugins/private/runtime_fields",
"@kbn/safer-lodash-set": "link:packages/kbn-safer-lodash-set",
@@ -1024,7 +1024,7 @@
"@kbn/watcher-plugin": "link:x-pack/platform/plugins/private/watcher",
"@kbn/xstate-utils": "link:packages/kbn-xstate-utils",
"@kbn/zod": "link:packages/kbn-zod",
- "@kbn/zod-helpers": "link:packages/kbn-zod-helpers",
+ "@kbn/zod-helpers": "link:src/platform/packages/shared/kbn-zod-helpers",
"@langchain/aws": "^0.1.2",
"@langchain/community": "0.3.14",
"@langchain/core": "^0.3.16",
diff --git a/packages/kbn-saved-search-component/README.md b/packages/kbn-saved-search-component/README.md
index 296ddb9079bcf..61ec5a6cd8a90 100644
--- a/packages/kbn-saved-search-component/README.md
+++ b/packages/kbn-saved-search-component/README.md
@@ -1,6 +1,6 @@
# @kbn/saved-search-component
-A component wrapper around Discover's Saved Search embeddable. This can be used in solutions without being within a Dasboard context.
+A component wrapper around Discover session embeddable. This can be used in solutions without being within a Dasboard context.
This can be used to render a context-aware (logs etc) "document table".
diff --git a/packages/kbn-scout/README.md b/packages/kbn-scout/README.md
index 4449bdf966200..b5e64416d4ed2 100644
--- a/packages/kbn-scout/README.md
+++ b/packages/kbn-scout/README.md
@@ -1,9 +1,258 @@
# @kbn/scout
-The package is designed to streamline the setup and execution of Playwright tests for Kibana. It consolidates server management and testing capabilities by wrapping both the Kibana/Elasticsearch server launcher and the Playwright test runner. It includes:
+`kbn-scout` is a modern test framework for Kibana. It uses Playwright for UI integration tests. Its primary goal is to enhance the developer experience by offering a lightweight and flexible testing solution to create UI tests next to the plugin source code. This README explains the structure of the `kbn-scout` package and provides an overview of its key components.
- - core test and worker-scoped fixtures for reliable setup across test suites
- - page objects combined into the fixture for for core Kibana apps UI interactions
- - configurations for seamless test execution in both local and CI environments
+### Table of Contents
-This package aims to simplify test setup and enhance modularity, making it easier to create, run, and maintain deployment-agnostic tests, that are located in the plugin they actually test.
+1. Overview
+2. Folder Structure
+3. Key Components
+4. How to Use
+5. Contributing
+
+### Overview
+
+The `kbn-scout` framework provides:
+
+- **Ease of integration:** a simplified mechanism to write and run tests closer to plugins.
+- **Deployment-agnostic tests:** enables the testing of Kibana features across different environments (e.g., Stateful, Serverless).
+- **Fixture-based design:** built on Playwright's fixture model to modularize and standardize test setup.
+- **Focus on Developer Productivity:** faster test execution and minimal boilerplate for writing tests.
+
+### Folder Structure
+
+The `kbn-scout` structure includes the following key directories and files:
+
+```
+packages/kbn-scout/
+├── src/
+│ ├── cli/
+│ ├── common/
+│ │ ├── services/
+│ │ ├── utils/
+│ ├── config/
+│ │ ├── loader/
+│ │ ├── schema/
+│ │ └── serverless/
+│ │ └── stateful/
+│ │ └── config.ts
+│ ├── playwright/
+│ │ ├── config/
+│ │ └── fixtures
+│ │ │ └── test/
+│ │ │ └── worker/
+│ │ └── page_objects/
+│ │ └── runner
+│ │ │ └── config_validator.ts
+│ │ │ └── run_tests.ts
+│ ├── servers/
+│ │ ├── run_elasticsearch.ts
+│ │ └── run_kibana_server.ts
+│ │ └── start_servers.ts
+│ ├── types/
+│ └── index.ts
+├── package.json
+├── tsconfig.json
+```
+
+### Key Components
+
+1. **src/cli/**
+
+Contains the logic to start servers, with or without running tests. It is accessed through the `scripts/scout` script.
+
+2. **src/common/**
+
+`services` directory includes test helpers used across UI and API integration tests, such as Kibana and Elasticsearch `clients`, `esArchiver`, and `samlSessionManager`. These services are used to initialize instances and expose them to tests via Playwright worker fixtures.
+
+3. **src/config/**
+
+`config` directory holds configurations for running servers locally. `serverless` and `stateful` directories contain deployment-specific configurations. Configuration attributes are defined in `schema` directory.
+The `Config` class in config.ts serves as the main entry point. It is instantiated using the config loader in
+the `loader` directory. This instance is compatible with the `kbn-test` input format and is passed to functions
+for starting servers.
+
+4. **src/playwright/**
+
+#### Config
+
+`playwright` directory manages the default Playwright configuration. It exports the `createPlaywrightConfig` function, which is used by Kibana plugins to define Scout playwright configurations and serves as the entry point to run tests.
+
+```ts
+import { createPlaywrightConfig } from '@kbn/scout';
+
+// eslint-disable-next-line import/no-default-export
+export default createPlaywrightConfig({
+ testDir: './tests',
+ workers: 2,
+});
+```
+
+Scout relies on configuration to determine the test files and opt-in [parallel test execution](https://playwright.dev/docs/test-parallel) against the single Elastic cluster.
+
+The Playwright configuration should only be created this way to ensure compatibility with Scout functionality. For configuration
+verification, we use a marker `VALID_CONFIG_MARKER`, and Scout will throw an error if the configuration is invalid.
+
+#### Fixtures
+
+The `fixtures` directory contains core Scout capabilities required for testing the majority of Kibana plugins. [Fixtures](https://playwright.dev/docs/test-fixtures) can be
+scoped to either `test` or `worker`. Scope decides when to init a new fixture instance: once per worker or for every test function. It is important to choose the correct scope to keep test execution optimally fast: if **a new instance is not needed for every test**, the fixture should be scoped to **worker**. Otherwise, it should be scoped to **test**.
+
+**Core `worker` scoped fixtures:**
+- `log`
+- `config`
+- `esClient`
+- `kbnClient`
+- `esArchiver`
+- `samlAuth`
+
+```ts
+ test.beforeAll(async ({ kbnClient }) => {
+ await kbnClient.importExport.load(testData.KBN_ARCHIVES.ECOMMERCE);
+ });
+```
+
+**Core `test` scoped fixtures:**
+- `browserAuth`
+- `pageObjects`
+- `page`
+
+```ts
+ test.beforeEach(async ({ browserAuth }) => {
+ await browserAuth.loginAsViewer();
+ });
+```
+
+If a new fixture depends on a fixture with a `test` scope, it must also be `test` scoped.
+
+#### Page Objects
+
+The `page_objects` directory contains all the Page Objects that represent Platform core functionality such as Discover, Dashboard, Index Management, etc.
+
+If a Page Object is likely to be used in more than one plugin, it should be added here. This allows other teams to reuse it, improving collaboration across teams, reducing code duplication, and simplifying support and adoption.
+
+Page Objects must be registered with the `createLazyPageObject` function, which guarantees its instance is lazy-initialized. This way, we can have all the page objects available in the test context, but only the ones that are called will be actually initialized:
+
+```ts
+export function createCorePageObjects(page: ScoutPage): PageObjects {
+ return {
+ dashboard: createLazyPageObject(DashboardApp, page),
+ discover: createLazyPageObject(DiscoverApp, page),
+ // Add new page objects here
+ };
+}
+```
+
+All registered Page Objects are available via the `pageObjects` fixture:
+
+```ts
+test.beforeEach(async ({ pageObjects }) => {
+ await pageObjects.discover.goto();
+});
+```
+
+5. **src/servers/**
+
+Here we have logic to start Kibana and Elasticsearch servers using `kbn-test` functionality in Scout flavor.
+The instance of the `Config` class is passed to start servers for the specific deployment type. The `loadServersConfig` function not only returns a `kbn-test` compatible config instance, but also converts it to `ScoutServiceConfig` format and saves it on disk to `./scout/servers/local.json` in the Kibana root directory. Scout `config` fixture reads it and expose to UI tests.
+
+### How to Use
+
+#### Starting Servers Only
+
+To start the servers without running tests, use the following command:
+
+```bash
+node scripts/scout.js start-server [--stateful|--serverless=[es|oblt|security]]
+```
+
+This is useful for manual testing or running tests via an IDE.
+
+#### Running Servers and Tests
+
+To start the servers and run tests, use:
+
+```bash
+node scripts/scout.js run-tests [--stateful|--serverless=[es|oblt|security]] --config /ui_tests/playwright.config.ts
+```
+
+This command starts the required servers and then automatically executes the tests using Playwright.
+
+#### Running Tests Separately
+
+If the servers are already running, you can execute tests independently using either:
+
+- Playwright Plugin in IDE: Run tests directly within your IDE using Playwright's integration.
+- Command Line: Use the following command to run tests:
+
+```bash
+npx playwright test --config /ui_tests/playwright.config.ts
+```
+
+### Contributing
+
+We welcome contributions to improve and extend `kbn-scout`. This guide will help you get started, add new features, and align with existing project standards.
+
+#### Setting Up the Environment
+
+Ensure you have the latest local copy of the Kibana repository.
+
+Install dependencies by running the following commands:
+- `yarn kbn bootstrap` to install dependencies.
+- `node scripts/build_kibana_platform_plugins.js` to build plugins.
+
+Move to the `packages/kbn-scout` directory to begin development.
+
+#### Adding or Modifying Features
+
+Contributions to sharable fixtures and page objects are highly encouraged to promote reusability, stability, and ease of adoption. Follow these steps:
+
+Create a New Page Object: Add your Page Object to the `src/playwright/page_objects` directory. For instance:
+
+#### Adding Page Objects
+
+1. **Create a New Page Object:** Add your Page Object to the src/playwright/page_objects directory. For instance:
+
+```ts
+export class NewPage {
+ constructor(private readonly page: ScoutPage) {}
+
+ // implementation
+}
+```
+2. **Register the Page Object:** Update the index file to include the new Page Object:
+```ts
+export function createCorePageObjects(page: ScoutPage): PageObjects {
+ return {
+ ...
+ newPage: createLazyPageObject(NewPage, page),
+ };
+}
+```
+#### Adding Fixtures
+1. **Determine Fixture Scope:** Decide if your fixture should apply to the `test` (per-test) or `worker` (per-worker) scope.
+
+2. **Implement the Fixture:** Add the implementation to `src/playwright/fixtures/test` or `src/playwright/fixtures/worker`.
+
+```ts
+export const newTestFixture = base.extend({
+ newFixture: async ({}, use) => {
+ const myFn = // implementation
+ await use(myFn);
+ // optionally, cleanup on test completion
+ },
+});
+```
+3. **Register the Fixture:** Add the fixture to the appropriate scope:
+```ts
+export const scoutTestFixtures = mergeTests(
+ ...
+ newTestFixture,
+);
+```
+
+#### Best Practices
+- **Reusable Code:** When creating Page Objects or Fixtures that apply to more than one plugin, ensure they are added to the kbn-scout package.
+- **Adhere to Existing Structure:** Maintain consistency with the project's architecture.
+- **Add Unit Tests:** Include tests for new logic where applicable, ensuring it works as expected.
+- **Playwright documentation:** [Official best practices](https://playwright.dev/docs/best-practices)
diff --git a/packages/kbn-scout/index.ts b/packages/kbn-scout/index.ts
index 5cb95662f4228..733d0bae1ecd1 100644
--- a/packages/kbn-scout/index.ts
+++ b/packages/kbn-scout/index.ts
@@ -8,7 +8,7 @@
*/
export * as cli from './src/cli';
-export { expect, test, createPlaywrightConfig, createLazyPageObject } from './src/playwright';
+export { expect, test, tags, createPlaywrightConfig, createLazyPageObject } from './src/playwright';
export type {
ScoutPage,
ScoutPlaywrightOptions,
diff --git a/packages/kbn-scout/src/config/loader/config_load.ts b/packages/kbn-scout/src/config/loader/config_load.ts
index 5ef4b88b4cf1a..c7e6b197d6a28 100644
--- a/packages/kbn-scout/src/config/loader/config_load.ts
+++ b/packages/kbn-scout/src/config/loader/config_load.ts
@@ -8,10 +8,16 @@
*/
import path from 'path';
-import { ToolingLog } from '@kbn/tooling-log';
import { Config } from '../config';
-export const loadConfig = async (configPath: string, log: ToolingLog): Promise => {
+/**
+ * Dynamically loads server configuration file in the "kbn-scout" framework. It reads
+ * and validates the configuration file, ensuring the presence of essential servers
+ * information required to initialize the testing environment.
+ * @param configPath Path to the configuration file to be loaded.
+ * @returns Config instance that is used to start local servers
+ */
+export const loadConfig = async (configPath: string): Promise => {
try {
const absolutePath = path.resolve(configPath);
const configModule = await import(absolutePath);
diff --git a/packages/kbn-scout/src/config/serverless/es.serverless.config.ts b/packages/kbn-scout/src/config/serverless/es.serverless.config.ts
index 89e27b4e877e0..0ae2c7e6f0b3f 100644
--- a/packages/kbn-scout/src/config/serverless/es.serverless.config.ts
+++ b/packages/kbn-scout/src/config/serverless/es.serverless.config.ts
@@ -17,6 +17,7 @@ export const servers: ScoutLoaderConfig = {
serverArgs: [...defaultConfig.esTestCluster.serverArgs],
},
kbnTestServer: {
+ ...defaultConfig.kbnTestServer,
serverArgs: [
...defaultConfig.kbnTestServer.serverArgs,
'--serverless=es',
diff --git a/packages/kbn-scout/src/config/serverless/oblt.serverless.config.ts b/packages/kbn-scout/src/config/serverless/oblt.serverless.config.ts
index 3f283f140479e..08eb4d9d7cf55 100644
--- a/packages/kbn-scout/src/config/serverless/oblt.serverless.config.ts
+++ b/packages/kbn-scout/src/config/serverless/oblt.serverless.config.ts
@@ -22,6 +22,7 @@ export const servers: ScoutLoaderConfig = {
],
},
kbnTestServer: {
+ ...defaultConfig.kbnTestServer,
serverArgs: [
...defaultConfig.kbnTestServer.serverArgs,
'--serverless=oblt',
diff --git a/packages/kbn-scout/src/config/serverless/security.serverless.config.ts b/packages/kbn-scout/src/config/serverless/security.serverless.config.ts
index f1fa4f53f8988..289790a9ffeb1 100644
--- a/packages/kbn-scout/src/config/serverless/security.serverless.config.ts
+++ b/packages/kbn-scout/src/config/serverless/security.serverless.config.ts
@@ -20,6 +20,7 @@ export const servers: ScoutLoaderConfig = {
],
},
kbnTestServer: {
+ ...defaultConfig.kbnTestServer,
serverArgs: [
...defaultConfig.kbnTestServer.serverArgs,
'--serverless=security',
diff --git a/packages/kbn-scout/src/config/serverless/serverless.base.config.ts b/packages/kbn-scout/src/config/serverless/serverless.base.config.ts
index 8b4852f9c9e62..a20a0c3bbe7a7 100644
--- a/packages/kbn-scout/src/config/serverless/serverless.base.config.ts
+++ b/packages/kbn-scout/src/config/serverless/serverless.base.config.ts
@@ -80,6 +80,11 @@ export const defaultConfig: ScoutLoaderConfig = {
'xpack.security.authc.realms.jwt.jwt1.order=-98',
`xpack.security.authc.realms.jwt.jwt1.pkc_jwkset_path=${getDockerFileMountPath(JWKS_PATH)}`,
`xpack.security.authc.realms.jwt.jwt1.token_type=access_token`,
+ 'serverless.indices.validate_dot_prefixes=true',
+ // controller cluster-settings
+ `cluster.service.slow_task_logging_threshold=15s`,
+ `cluster.service.slow_task_thread_dump_timeout=5s`,
+ `serverless.search.enable_replicas_for_instant_failover=true`,
],
ssl: true, // SSL is required for SAML realm
},
@@ -136,7 +141,15 @@ export const defaultConfig: ScoutLoaderConfig = {
// This ensures that we register the Security SAML API endpoints.
// In the real world the SAML config is injected by control plane.
`--plugin-path=${SAML_IDP_PLUGIN_PATH}`,
+ '--xpack.cloud.base_url=https://fake-cloud.elastic.co',
+ '--xpack.cloud.billing_url=/billing/overview/',
+ '--xpack.cloud.deployments_url=/deployments',
'--xpack.cloud.id=ftr_fake_cloud_id',
+ '--xpack.cloud.organization_url=/account/',
+ '--xpack.cloud.profile_url=/user/settings/',
+ '--xpack.cloud.projects_url=/projects/',
+ '--xpack.cloud.serverless.project_id=fakeprojectid',
+ '--xpack.cloud.users_and_roles_url=/account/members/',
// Ensure that SAML is used as the default authentication method whenever a user navigates to Kibana. In other
// words, Kibana should attempt to authenticate the user using the provider with the lowest order if the Login
// Selector is disabled (which is how Serverless Kibana is configured). By declaring `cloud-basic` with a higher
diff --git a/packages/kbn-scout/src/config/utils.ts b/packages/kbn-scout/src/config/utils.ts
index d15e0e094b2db..38c65f1573b04 100644
--- a/packages/kbn-scout/src/config/utils.ts
+++ b/packages/kbn-scout/src/config/utils.ts
@@ -16,6 +16,7 @@ import { SCOUT_SERVERS_ROOT } from '@kbn/scout-info';
import { CliSupportedServerModes, ScoutServerConfig } from '../types';
import { getConfigFilePath } from './get_config_file';
import { loadConfig } from './loader/config_load';
+import type { Config } from './config';
export const formatCurrentDate = () => {
const now = new Date();
@@ -29,6 +30,11 @@ export const formatCurrentDate = () => {
);
};
+/**
+ * Saves Scout server configuration to the disk.
+ * @param testServersConfig configuration to be saved
+ * @param log Logger instance to report errors or debug information.
+ */
const saveTestServersConfigOnDisk = (testServersConfig: ScoutServerConfig, log: ToolingLog) => {
const configFilePath = path.join(SCOUT_SERVERS_ROOT, `local.json`);
@@ -48,16 +54,26 @@ const saveTestServersConfigOnDisk = (testServersConfig: ScoutServerConfig, log:
}
};
-export async function loadServersConfig(mode: CliSupportedServerModes, log: ToolingLog) {
+/**
+ * Loads server configuration based on the mode, creates "kbn-test" compatible Config
+ * instance, that can be used to start local servers and saves its "Scout"-format copy
+ * to the disk.
+ * @param mode server local run mode
+ * @param log Logger instance to report errors or debug information.
+ * @returns "kbn-test" compatible Config instance
+ */
+export async function loadServersConfig(
+ mode: CliSupportedServerModes,
+ log: ToolingLog
+): Promise {
// get path to one of the predefined config files
const configPath = getConfigFilePath(mode);
// load config that is compatible with kbn-test input format
- const config = await loadConfig(configPath, log);
+ const config = await loadConfig(configPath);
// construct config for Playwright Test
const scoutServerConfig = config.getTestServersConfig();
// save test config to the file
saveTestServersConfigOnDisk(scoutServerConfig, log);
-
return config;
}
diff --git a/packages/kbn-scout/src/playwright/fixtures/test/browser_auth.ts b/packages/kbn-scout/src/playwright/fixtures/test/browser_auth.ts
index 5faa1b5392d96..11c2d97b06673 100644
--- a/packages/kbn-scout/src/playwright/fixtures/test/browser_auth.ts
+++ b/packages/kbn-scout/src/playwright/fixtures/test/browser_auth.ts
@@ -14,6 +14,11 @@ import { serviceLoadedMsg } from '../../utils';
type LoginFunction = (role: string) => Promise;
+/**
+ * The "browserAuth" fixture simplifies the process of logging into Kibana with
+ * different roles during tests. It uses the "samlAuth" fixture to create an authentication session
+ * for the specified role and the "context" fixture to update the cookie with the role-scoped session.
+ */
export const browserAuthFixture = base.extend<{ browserAuth: LoginFixture }, ScoutWorkerFixtures>({
browserAuth: async ({ log, context, samlAuth, config }, use) => {
const setSessionCookie = async (cookieValue: string) => {
diff --git a/packages/kbn-scout/src/playwright/fixtures/test/index.ts b/packages/kbn-scout/src/playwright/fixtures/test/index.ts
index 41bfedcf39dc7..3e2ea85b90bc3 100644
--- a/packages/kbn-scout/src/playwright/fixtures/test/index.ts
+++ b/packages/kbn-scout/src/playwright/fixtures/test/index.ts
@@ -11,9 +11,11 @@ import { mergeTests } from '@playwright/test';
import { browserAuthFixture } from './browser_auth';
import { scoutPageFixture } from './page';
import { pageObjectsFixture } from './page_objects';
+import { validateTagsFixture } from './validate_tags';
export const scoutTestFixtures = mergeTests(
browserAuthFixture,
scoutPageFixture,
- pageObjectsFixture
+ pageObjectsFixture,
+ validateTagsFixture
);
diff --git a/packages/kbn-scout/src/playwright/fixtures/test/page_objects.ts b/packages/kbn-scout/src/playwright/fixtures/test/page_objects.ts
index ed142b48b3f9a..06be362294432 100644
--- a/packages/kbn-scout/src/playwright/fixtures/test/page_objects.ts
+++ b/packages/kbn-scout/src/playwright/fixtures/test/page_objects.ts
@@ -11,6 +11,14 @@ import { test as base } from '@playwright/test';
import { ScoutTestFixtures, ScoutWorkerFixtures } from '../types';
import { createCorePageObjects } from '../../page_objects';
+/**
+ * The "pageObjects" fixture provides a centralized and consistent way to access and
+ * interact with reusable Page Objects in tests. This fixture automatically
+ * initializes core Page Objects and makes them available to tests, promoting
+ * modularity and reducing redundant setup.
+ *
+ * Note: Page Objects are lazily instantiated on first access.
+ */
export const pageObjectsFixture = base.extend({
pageObjects: async ({ page }, use) => {
const corePageObjects = createCorePageObjects(page);
diff --git a/packages/kbn-scout/src/playwright/fixtures/test/validate_tags.ts b/packages/kbn-scout/src/playwright/fixtures/test/validate_tags.ts
new file mode 100644
index 0000000000000..1866935440e1a
--- /dev/null
+++ b/packages/kbn-scout/src/playwright/fixtures/test/validate_tags.ts
@@ -0,0 +1,35 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the "Elastic License
+ * 2.0", the "GNU Affero General Public License v3.0 only", 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", the "GNU Affero General Public
+ * License v3.0 only", or the "Server Side Public License, v 1".
+ */
+
+import { test as base } from '@playwright/test';
+import { tags } from '../../tags';
+
+const supportedTags = tags.DEPLOYMENT_AGNOSTIC;
+
+export const validateTagsFixture = base.extend<{ validateTags: void }>({
+ validateTags: [
+ async ({}, use, testInfo) => {
+ if (testInfo.tags.length === 0) {
+ throw new Error(`At least one tag is required: ${supportedTags.join(', ')}`);
+ }
+
+ const invalidTags = testInfo.tags.filter((tag: string) => !supportedTags.includes(tag));
+ if (invalidTags.length > 0) {
+ throw new Error(
+ `Unsupported tag(s) found in test suite "${testInfo.title}": ${invalidTags.join(
+ ', '
+ )}. ` + `Supported tags are: ${supportedTags.join(', ')}.`
+ );
+ }
+
+ await use();
+ },
+ { auto: true },
+ ],
+});
diff --git a/packages/kbn-scout/src/playwright/fixtures/types/test_scope.ts b/packages/kbn-scout/src/playwright/fixtures/types/test_scope.ts
index 4ff7fc18cd6f2..13a3c3ebaed83 100644
--- a/packages/kbn-scout/src/playwright/fixtures/types/test_scope.ts
+++ b/packages/kbn-scout/src/playwright/fixtures/types/test_scope.ts
@@ -17,8 +17,20 @@ export interface ScoutTestFixtures {
}
export interface LoginFixture {
+ /**
+ * Logs in as a user with viewer-only permissions.
+ * @returns A Promise that resolves once the cookie in browser is set.
+ */
loginAsViewer: () => Promise;
+ /**
+ * Logs in as a user with administrative privileges
+ * @returns A Promise that resolves once the cookie in browser is set.
+ */
loginAsAdmin: () => Promise;
+ /**
+ * Logs in as a user with elevated, but not admin, permissions.
+ * @returns A Promise that resolves once the cookie in browser is set.
+ */
loginAsPrivilegedUser: () => Promise;
}
diff --git a/packages/kbn-scout/src/playwright/fixtures/types/worker_scope.ts b/packages/kbn-scout/src/playwright/fixtures/types/worker_scope.ts
index 20908a566abb2..c42f7143d3191 100644
--- a/packages/kbn-scout/src/playwright/fixtures/types/worker_scope.ts
+++ b/packages/kbn-scout/src/playwright/fixtures/types/worker_scope.ts
@@ -18,6 +18,13 @@ import { ScoutServerConfig } from '../../../types';
import { KibanaUrl } from '../../../common/services/kibana_url';
export interface EsArchiverFixture {
+ /**
+ * Loads an Elasticsearch archive if the specified data index is not present.
+ * @param name The name of the archive to load.
+ * @param performance An object of type LoadActionPerfOptions to measure and
+ * report performance metrics during the load operation.
+ * @returns A Promise that resolves to an object containing index statistics.
+ */
loadIfNeeded: (
name: string,
performance?: LoadActionPerfOptions | undefined
@@ -25,11 +32,30 @@ export interface EsArchiverFixture {
}
export interface UiSettingsFixture {
+ /**
+ * Applies one or more UI settings
+ * @param values (UiSettingValues): An object containing key-value pairs of UI settings to apply.
+ * @returns A Promise that resolves once the settings are applied.
+ */
set: (values: UiSettingValues) => Promise;
+ /**
+ * Resets specific UI settings to their default values.
+ * @param values A list of UI setting keys to unset.
+ * @returns A Promise that resolves after the settings are unset.
+ */
unset: (...values: string[]) => Promise;
+ /**
+ * Sets the default time range for Kibana.
+ * @from The start time of the default time range.
+ * @to The end time of the default time range.
+ * @returns A Promise that resolves once the default time is set.
+ */
setDefaultTime: ({ from, to }: { from: string; to: string }) => Promise;
}
+/**
+ * The `ScoutWorkerFixtures` type defines the set of fixtures that are available
+ */
export interface ScoutWorkerFixtures {
log: ToolingLog;
config: ScoutServerConfig;
diff --git a/packages/kbn-scout/src/playwright/fixtures/worker/core.ts b/packages/kbn-scout/src/playwright/fixtures/worker/core.ts
index 359a779b05fc7..9f90f71d9c276 100644
--- a/packages/kbn-scout/src/playwright/fixtures/worker/core.ts
+++ b/packages/kbn-scout/src/playwright/fixtures/worker/core.ts
@@ -22,7 +22,16 @@ import {
import { ScoutWorkerFixtures } from '../types/worker_scope';
import { ScoutTestOptions } from '../../types';
+/**
+ * The coreWorkerFixtures setup defines foundational fixtures that are essential
+ * for running tests in the "kbn-scout" framework. These fixtures provide reusable,
+ * scoped resources for each Playwright worker, ensuring that tests have consistent
+ * and isolated access to critical services such as logging, configuration, and
+ * clients for interacting with Kibana and Elasticsearch.
+ */
export const coreWorkerFixtures = base.extend<{}, ScoutWorkerFixtures>({
+ // Provides a scoped logger instance for each worker. This logger is shared across
+ // all other fixtures within the worker scope.
log: [
({}, use) => {
use(createLogger());
@@ -30,6 +39,11 @@ export const coreWorkerFixtures = base.extend<{}, ScoutWorkerFixtures>({
{ scope: 'worker' },
],
+ /**
+ * Loads the test server configuration from the source file based on local or cloud
+ * target, located by default in '.scout/servers' directory. It supplies Playwright
+ * with all server-related information including hosts, credentials, type of deployment, etc.
+ */
config: [
({ log }, use, testInfo) => {
const configName = 'local';
@@ -42,6 +56,10 @@ export const coreWorkerFixtures = base.extend<{}, ScoutWorkerFixtures>({
{ scope: 'worker' },
],
+ /**
+ * Generates and exposes a Kibana URL object based on the configuration, allowing tests
+ * and fixtures to programmatically construct and validate URLs.
+ */
kbnUrl: [
({ config, log }, use) => {
use(createKbnUrl(config, log));
@@ -49,6 +67,9 @@ export const coreWorkerFixtures = base.extend<{}, ScoutWorkerFixtures>({
{ scope: 'worker' },
],
+ /**
+ * Instantiates an Elasticsearch client, enabling API-level interactions with ES.
+ */
esClient: [
({ config, log }, use) => {
use(createEsClient(config, log));
@@ -56,6 +77,9 @@ export const coreWorkerFixtures = base.extend<{}, ScoutWorkerFixtures>({
{ scope: 'worker' },
],
+ /**
+ * Creates a Kibana client, enabling API-level interactions with Kibana.
+ */
kbnClient: [
({ log, config }, use) => {
use(createKbnClient(config, log));
@@ -63,10 +87,17 @@ export const coreWorkerFixtures = base.extend<{}, ScoutWorkerFixtures>({
{ scope: 'worker' },
],
+ /**
+ * Provides utilities for managing test data in Elasticsearch. The "loadIfNeeded" method
+ * optimizes test execution by loading data archives only if required, avoiding redundant
+ * data ingestion.
+ *
+ * Note: In order to speedup test execution and avoid the overhead of deleting the data
+ * we only expose capability to ingest the data indexes.
+ */
esArchiver: [
({ log, esClient, kbnClient }, use) => {
const esArchiverInstance = createEsArchiver(esClient, kbnClient, log);
- // to speedup test execution we only allow to ingest the data indexes and only if index doesn't exist
const loadIfNeeded = async (name: string, performance?: LoadActionPerfOptions | undefined) =>
esArchiverInstance!.loadIfNeeded(name, performance);
@@ -75,6 +106,13 @@ export const coreWorkerFixtures = base.extend<{}, ScoutWorkerFixtures>({
{ scope: 'worker' },
],
+ /**
+ * Creates a SAML session manager, that handles authentication tasks for tests involving
+ * SAML-based authentication.
+ *
+ * Note: In order to speedup execution of tests, we cache the session cookies for each role
+ * after first call.
+ */
samlAuth: [
({ log, config }, use) => {
use(createSamlSessionManager(config, log));
diff --git a/packages/kbn-scout/src/playwright/fixtures/worker/ui_settings.ts b/packages/kbn-scout/src/playwright/fixtures/worker/ui_settings.ts
index 989f7ce436616..20fa59da9aba7 100644
--- a/packages/kbn-scout/src/playwright/fixtures/worker/ui_settings.ts
+++ b/packages/kbn-scout/src/playwright/fixtures/worker/ui_settings.ts
@@ -12,6 +12,9 @@ import { UiSettingValues } from '@kbn/test/src/kbn_client/kbn_client_ui_settings
import { ScoutWorkerFixtures } from '../types';
import { isValidUTCDate, formatTime } from '../../utils';
+/**
+ * This fixture provides a way to interact with Kibana UI settings.
+ */
export const uiSettingsFixture = base.extend<{}, ScoutWorkerFixtures>({
uiSettings: [
({ kbnClient }, use) => {
diff --git a/packages/kbn-scout/src/playwright/index.ts b/packages/kbn-scout/src/playwright/index.ts
index 5294274c41bc5..0a82bc0468fce 100644
--- a/packages/kbn-scout/src/playwright/index.ts
+++ b/packages/kbn-scout/src/playwright/index.ts
@@ -25,3 +25,6 @@ export type {
ScoutPage,
EsArchiverFixture,
} from './fixtures';
+
+// use to tag tests
+export { tags } from './tags';
diff --git a/packages/kbn-scout/src/playwright/runner/run_tests.ts b/packages/kbn-scout/src/playwright/runner/run_tests.ts
index a5d8aa137dbfd..766209f169963 100644
--- a/packages/kbn-scout/src/playwright/runner/run_tests.ts
+++ b/packages/kbn-scout/src/playwright/runner/run_tests.ts
@@ -18,12 +18,14 @@ import { loadServersConfig } from '../../config';
import { silence } from '../../common';
import { RunTestsOptions } from './flags';
import { getExtraKbnOpts } from '../../servers/run_kibana_server';
+import { getPlaywrightGrepTag } from '../utils';
export async function runTests(log: ToolingLog, options: RunTestsOptions) {
const runStartTime = Date.now();
- const reportTime = getTimeReporter(log, 'scripts/scout_test');
+ const reportTime = getTimeReporter(log, 'scripts/scout run-tests');
const config = await loadServersConfig(options.mode, log);
+ const playwrightGrepTag = getPlaywrightGrepTag(config);
const playwrightConfigPath = options.configPath;
await withProcRunner(log, async (procs) => {
@@ -59,7 +61,12 @@ export async function runTests(log: ToolingLog, options: RunTestsOptions) {
// Running 'npx playwright test --config=${playwrightConfigPath}'
await procs.run(`playwright`, {
cmd: resolve(REPO_ROOT, './node_modules/.bin/playwright'),
- args: ['test', `--config=${playwrightConfigPath}`, ...(options.headed ? ['--headed'] : [])],
+ args: [
+ 'test',
+ `--config=${playwrightConfigPath}`,
+ `--grep=${playwrightGrepTag}`,
+ ...(options.headed ? ['--headed'] : []),
+ ],
cwd: resolve(REPO_ROOT),
env: {
...process.env,
diff --git a/src/plugins/embeddable/public/lib/inspector.ts b/packages/kbn-scout/src/playwright/tags.ts
similarity index 54%
rename from src/plugins/embeddable/public/lib/inspector.ts
rename to packages/kbn-scout/src/playwright/tags.ts
index d90af7c751d81..a022b6afd3430 100644
--- a/src/plugins/embeddable/public/lib/inspector.ts
+++ b/packages/kbn-scout/src/playwright/tags.ts
@@ -7,4 +7,21 @@
* License v3.0 only", or the "Server Side Public License, v 1".
*/
-export * from '@kbn/inspector-plugin/public';
+const SERVERLESS_ONLY = ['@svlSecurity', '@svlOblt', '@svlSearch'];
+const ESS_ONLY = ['@ess'];
+const DEPLOYMENT_AGNOSTIC = SERVERLESS_ONLY.concat(ESS_ONLY);
+
+export const tags = {
+ ESS_ONLY,
+ SERVERLESS_ONLY,
+ DEPLOYMENT_AGNOSTIC,
+};
+
+export const tagsByMode = {
+ stateful: '@ess',
+ serverless: {
+ es: '@svlSearch',
+ oblt: '@svlOblt',
+ security: '@svlSecurity',
+ },
+};
diff --git a/packages/kbn-scout/src/playwright/utils/index.ts b/packages/kbn-scout/src/playwright/utils/index.ts
index 4b6fcafcbcfa8..8956c6d7cc18f 100644
--- a/packages/kbn-scout/src/playwright/utils/index.ts
+++ b/packages/kbn-scout/src/playwright/utils/index.ts
@@ -8,6 +8,8 @@
*/
import moment from 'moment';
+import { Config } from '../../config';
+import { tagsByMode } from '../tags';
export const serviceLoadedMsg = (name: string) => `scout service loaded: ${name}`;
@@ -18,3 +20,10 @@ export const isValidUTCDate = (date: string): boolean => {
export function formatTime(date: string, fmt: string = 'MMM D, YYYY @ HH:mm:ss.SSS') {
return moment.utc(date, fmt).format();
}
+
+export const getPlaywrightGrepTag = (config: Config): string => {
+ const serversConfig = config.getTestServersConfig();
+ return serversConfig.serverless
+ ? tagsByMode.serverless[serversConfig.projectType!]
+ : tagsByMode.stateful;
+};
diff --git a/packages/kbn-scout/src/types/config.d.ts b/packages/kbn-scout/src/types/config.d.ts
index 2f0c3a764d65f..08c4bc5f3f9b0 100644
--- a/packages/kbn-scout/src/types/config.d.ts
+++ b/packages/kbn-scout/src/types/config.d.ts
@@ -25,9 +25,9 @@ export interface ScoutLoaderConfig {
ssl: boolean;
};
kbnTestServer: {
- env?: any;
- buildArgs?: string[];
- sourceArgs?: string[];
+ env: any;
+ buildArgs: string[];
+ sourceArgs: string[];
serverArgs: string[];
useDedicatedTestRunner?: boolean;
};
diff --git a/packages/kbn-search-connectors/types/native_connectors.ts b/packages/kbn-search-connectors/types/native_connectors.ts
index c5ef7beab0ba5..96af7ea581e6c 100644
--- a/packages/kbn-search-connectors/types/native_connectors.ts
+++ b/packages/kbn-search-connectors/types/native_connectors.ts
@@ -107,6 +107,9 @@ const PERSONAL_ACCESS_TOKEN = 'personal_access_token';
const GITHUB_APP = 'github_app';
+const BOX_FREE = 'box_free';
+const BOX_ENTERPRISE = 'box_enterprise';
+
export const NATIVE_CONNECTOR_DEFINITIONS: Record = {
azure_blob_storage: {
configuration: {
@@ -246,31 +249,42 @@ export const NATIVE_CONNECTOR_DEFINITIONS: Record
) : (
)}
diff --git a/packages/react/kibana_context/render/render_provider.tsx b/packages/react/kibana_context/render/render_provider.tsx
index 233abb42834b9..345a0993bb9e4 100644
--- a/packages/react/kibana_context/render/render_provider.tsx
+++ b/packages/react/kibana_context/render/render_provider.tsx
@@ -25,11 +25,11 @@ export type KibanaRenderContextProviderProps = Omit
> = ({ children, ...props }) => {
- const { analytics, i18n, theme, userProfile, colorMode, modify } = props;
+ const { analytics, executionContext, i18n, theme, userProfile, colorMode, modify } = props;
return (
{children}
diff --git a/packages/react/kibana_context/root/root_provider.test.tsx b/packages/react/kibana_context/root/root_provider.test.tsx
index 8c8dbf38acfad..fc800708a8441 100644
--- a/packages/react/kibana_context/root/root_provider.test.tsx
+++ b/packages/react/kibana_context/root/root_provider.test.tsx
@@ -15,6 +15,8 @@ import { useEuiTheme } from '@elastic/eui';
import type { UseEuiTheme } from '@elastic/eui';
import { mountWithIntl } from '@kbn/test-jest-helpers';
import type { KibanaTheme } from '@kbn/react-kibana-context-common';
+import type { ExecutionContextStart } from '@kbn/core-execution-context-browser';
+import { executionContextServiceMock } from '@kbn/core-execution-context-browser-mocks';
import { i18nServiceMock } from '@kbn/core-i18n-browser-mocks';
import { I18nStart } from '@kbn/core-i18n-browser';
import type { UserProfileService } from '@kbn/core-user-profile-browser';
@@ -25,11 +27,13 @@ describe('KibanaRootContextProvider', () => {
let euiTheme: UseEuiTheme | undefined;
let i18nMock: I18nStart;
let userProfile: UserProfileService;
+ let executionContext: ExecutionContextStart;
beforeEach(() => {
euiTheme = undefined;
i18nMock = i18nServiceMock.createStartContract();
userProfile = userProfileServiceMock.createStart();
+ executionContext = executionContextServiceMock.createStartContract();
});
const flushPromises = async () => {
@@ -64,6 +68,7 @@ describe('KibanaRootContextProvider', () => {
@@ -82,6 +87,7 @@ describe('KibanaRootContextProvider', () => {
diff --git a/packages/react/kibana_context/root/root_provider.tsx b/packages/react/kibana_context/root/root_provider.tsx
index 386a67fb005e3..be8ddfa3f95ae 100644
--- a/packages/react/kibana_context/root/root_provider.tsx
+++ b/packages/react/kibana_context/root/root_provider.tsx
@@ -11,6 +11,8 @@ import React, { FC, PropsWithChildren } from 'react';
import type { AnalyticsServiceStart } from '@kbn/core-analytics-browser';
import type { I18nStart } from '@kbn/core-i18n-browser';
+import type { ExecutionContextStart } from '@kbn/core-execution-context-browser';
+import { SharedUXRouterContext } from '@kbn/shared-ux-router';
// @ts-expect-error EUI exports this component internally, but Kibana isn't picking it up its types
import { useIsNestedEuiProvider } from '@elastic/eui/lib/components/provider/nested';
@@ -25,6 +27,8 @@ export interface KibanaRootContextProviderProps extends KibanaEuiProviderProps {
i18n: I18nStart;
/** The `AnalyticsServiceStart` API from `CoreStart`. */
analytics?: Pick;
+ /** The `ExecutionContextStart` API from `CoreStart`. */
+ executionContext?: ExecutionContextStart;
}
/**
@@ -44,20 +48,26 @@ export interface KibanaRootContextProviderProps extends KibanaEuiProviderProps {
export const KibanaRootContextProvider: FC> = ({
children,
i18n,
+ executionContext,
...props
}) => {
const hasEuiProvider = useIsNestedEuiProvider();
+ const rootContextProvider = (
+
+ {children}
+
+ );
if (hasEuiProvider) {
emitEuiProviderWarning(
'KibanaRootContextProvider has likely been nested in this React tree, either by direct reference or by KibanaRenderContextProvider. The result of this nesting is a nesting of EuiProvider, which has negative effects. Check your React tree for nested Kibana context providers.'
);
- return {children};
+ return rootContextProvider;
} else {
const { theme, userProfile, globalStyles, colorMode, modify } = props;
return (
- {children}
+ {rootContextProvider}
);
}
diff --git a/packages/react/kibana_context/root/tsconfig.json b/packages/react/kibana_context/root/tsconfig.json
index a7606025552b8..8035f8379e390 100644
--- a/packages/react/kibana_context/root/tsconfig.json
+++ b/packages/react/kibana_context/root/tsconfig.json
@@ -24,5 +24,8 @@
"@kbn/core-analytics-browser",
"@kbn/core-user-profile-browser",
"@kbn/core-user-profile-browser-mocks",
+ "@kbn/core-execution-context-browser",
+ "@kbn/core-execution-context-browser-mocks",
+ "@kbn/shared-ux-router"
]
}
diff --git a/packages/shared-ux/router/impl/BUILD.bazel b/packages/shared-ux/router/impl/BUILD.bazel
new file mode 100644
index 0000000000000..224bebcf72e4a
--- /dev/null
+++ b/packages/shared-ux/router/impl/BUILD.bazel
@@ -0,0 +1,34 @@
+load("@build_bazel_rules_nodejs//:index.bzl", "js_library")
+
+SRCS = glob(
+ [
+ "**/*.ts",
+ "**/*.tsx",
+ ],
+ exclude = [
+ "**/test_helpers.ts",
+ "**/*.config.js",
+ "**/*.mock.*",
+ "**/*.test.*",
+ "**/*.stories.*",
+ "**/__snapshots__/**",
+ "**/integration_tests/**",
+ "**/mocks/**",
+ "**/scripts/**",
+ "**/storybook/**",
+ "**/test_fixtures/**",
+ "**/test_helpers/**",
+ ],
+)
+
+DEPS = [
+
+]
+
+js_library(
+ name = "shared-ux-router",
+ package_name = "@kbn/shared-ux-router",
+ srcs = ["package.json"] + SRCS,
+ deps = DEPS,
+ visibility = ["//visibility:public"],
+)
diff --git a/packages/shared-ux/router/impl/__snapshots__/route.test.tsx.snap b/packages/shared-ux/router/impl/__snapshots__/route.test.tsx.snap
index 418aa60b7c1f4..b7ef595289233 100644
--- a/packages/shared-ux/router/impl/__snapshots__/route.test.tsx.snap
+++ b/packages/shared-ux/router/impl/__snapshots__/route.test.tsx.snap
@@ -33,3 +33,5 @@ exports[`Route renders 1`] = `
`;
+
+exports[`Route renders with enableExecutionContextTracking as false 1`] = ``;
diff --git a/packages/shared-ux/router/impl/index.ts b/packages/shared-ux/router/impl/index.ts
index a8bef1b8499df..253d42beaa501 100644
--- a/packages/shared-ux/router/impl/index.ts
+++ b/packages/shared-ux/router/impl/index.ts
@@ -10,3 +10,5 @@
export { Route } from './route';
export { HashRouter, BrowserRouter, MemoryRouter, Router } from './router';
export { Routes } from './routes';
+
+export { SharedUXRouterContext } from './services';
diff --git a/packages/shared-ux/router/impl/route.test.tsx b/packages/shared-ux/router/impl/route.test.tsx
index 96bb6130387af..9d21690cdcf4f 100644
--- a/packages/shared-ux/router/impl/route.test.tsx
+++ b/packages/shared-ux/router/impl/route.test.tsx
@@ -9,15 +9,34 @@
import React, { Component, FC } from 'react';
import { shallow } from 'enzyme';
+import { useSharedUXRoutesContext } from './routes_context';
import { Route } from './route';
import { createMemoryHistory } from 'history';
+jest.mock('./routes_context', () => ({
+ useSharedUXRoutesContext: jest.fn().mockImplementation(() => ({
+ enableExecutionContextTracking: true,
+ })),
+}));
+
describe('Route', () => {
+ beforeEach(() => {
+ jest.restoreAllMocks();
+ });
+
test('renders', () => {
const example = shallow();
expect(example).toMatchSnapshot();
});
+ test('renders with enableExecutionContextTracking as false', () => {
+ (useSharedUXRoutesContext as jest.Mock).mockImplementationOnce(() => ({
+ enableExecutionContextTracking: false,
+ }));
+ const example = shallow();
+ expect(example).toMatchSnapshot();
+ });
+
test('location renders as expected', () => {
// create a history
const historyLocation = createMemoryHistory();
diff --git a/packages/shared-ux/router/impl/route.tsx b/packages/shared-ux/router/impl/route.tsx
index 3535ff7aecec8..5041f872b71b1 100644
--- a/packages/shared-ux/router/impl/route.tsx
+++ b/packages/shared-ux/router/impl/route.tsx
@@ -15,6 +15,7 @@ import {
RouteProps,
useRouteMatch,
} from 'react-router-dom';
+import { useSharedUXRoutesContext } from './routes_context';
import { useKibanaSharedUX } from './services';
import { useSharedUXExecutionContext } from './use_execution_context';
@@ -30,17 +31,18 @@ export const Route = ({
render,
...rest
}: RouteProps) => {
+ const { enableExecutionContextTracking } = useSharedUXRoutesContext();
const component = useMemo(() => {
if (!Component) {
return undefined;
}
return (props: RouteComponentProps) => (
<>
-
+ {enableExecutionContextTracking && }
>
);
- }, [Component]);
+ }, [Component, enableExecutionContextTracking]);
if (component) {
return ;
@@ -52,7 +54,7 @@ export const Route = ({
{...rest}
render={(props) => (
<>
-
+ {enableExecutionContextTracking && }
{/* @ts-ignore else condition exists if renderFunction is undefined*/}
{renderFunction(props)}
>
@@ -62,7 +64,7 @@ export const Route = ({
}
return (
-
+ {enableExecutionContextTracking && }
{children}
);
@@ -75,6 +77,12 @@ export const MatchPropagator = () => {
const { executionContext } = useKibanaSharedUX().services;
const match = useRouteMatch();
+ if (!executionContext && process.env.NODE_ENV !== 'production') {
+ throw new Error(
+ 'Default execution context tracking is enabled but the executionContext service is not available'
+ );
+ }
+
useSharedUXExecutionContext(executionContext, {
type: 'application',
page: match.path,
diff --git a/packages/shared-ux/router/impl/routes.tsx b/packages/shared-ux/router/impl/routes.tsx
index 9c1a97de65830..9377562246276 100644
--- a/packages/shared-ux/router/impl/routes.tsx
+++ b/packages/shared-ux/router/impl/routes.tsx
@@ -13,6 +13,7 @@ import React, { Children } from 'react';
import { Switch, useRouteMatch } from 'react-router-dom';
import { Routes as ReactRouterRoutes, Route } from 'react-router-dom-v5-compat';
import { Route as LegacyRoute, MatchPropagator } from './route';
+import { SharedUXRoutesContext } from './routes_context';
type RouterElementChildren = Array<
React.ReactElement<
@@ -28,42 +29,47 @@ type RouterElementChildren = Array<
export const Routes = ({
legacySwitch = true,
+ enableExecutionContextTracking = false,
children,
}: {
legacySwitch?: boolean;
+ enableExecutionContextTracking?: boolean;
children: React.ReactNode;
}) => {
const match = useRouteMatch();
return legacySwitch ? (
- {children}
+
+ {children}
+
) : (
-
- {Children.map(children as RouterElementChildren, (child) => {
- if (React.isValidElement(child) && child.type === LegacyRoute) {
- const path = replace(child?.props.path, match.url + '/', '');
- const renderFunction =
- typeof child?.props.children === 'function'
- ? child?.props.children
- : child?.props.render;
-
- return (
-
-
- {(child?.props?.component && ) ||
- (renderFunction && renderFunction()) ||
- children}
- >
- }
- />
- );
- } else {
- return child;
- }
- })}
-
+
+
+ {Children.map(children as RouterElementChildren, (child) => {
+ if (React.isValidElement(child) && child.type === LegacyRoute) {
+ const path = replace(child?.props.path, match.url + '/', '');
+ const renderFunction =
+ typeof child?.props.children === 'function'
+ ? child?.props.children
+ : child?.props.render;
+ return (
+
+ {enableExecutionContextTracking && }
+ {(child?.props?.component && ) ||
+ (renderFunction && renderFunction()) ||
+ children}
+ >
+ }
+ />
+ );
+ } else {
+ return child;
+ }
+ })}
+
+
);
};
diff --git a/packages/shared-ux/router/impl/routes_context.ts b/packages/shared-ux/router/impl/routes_context.ts
new file mode 100644
index 0000000000000..115a5df7780d5
--- /dev/null
+++ b/packages/shared-ux/router/impl/routes_context.ts
@@ -0,0 +1,18 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the "Elastic License
+ * 2.0", the "GNU Affero General Public License v3.0 only", 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", the "GNU Affero General Public
+ * License v3.0 only", or the "Server Side Public License, v 1".
+ */
+
+import { createContext, useContext } from 'react';
+import { SharedUXRoutesContextType } from './types';
+
+const defaultContextValue = {};
+
+export const SharedUXRoutesContext = createContext(defaultContextValue);
+
+export const useSharedUXRoutesContext = (): SharedUXRoutesContextType =>
+ useContext(SharedUXRoutesContext as unknown as React.Context);
diff --git a/packages/shared-ux/router/impl/services.ts b/packages/shared-ux/router/impl/services.ts
index c3ad2ab06e06d..7cea72f03bd82 100644
--- a/packages/shared-ux/router/impl/services.ts
+++ b/packages/shared-ux/router/impl/services.ts
@@ -50,7 +50,7 @@ export interface SharedUXExecutionContextSetup {
*/
export interface SharedUXExecutionContextSetup {
/** {@link SharedUXExecutionContextSetup} */
- executionContext: SharedUXExecutionContextStart;
+ executionContext?: SharedUXExecutionContextStart;
}
export type KibanaServices = Partial;
@@ -63,12 +63,14 @@ const defaultContextValue = {
services: {},
};
-export const sharedUXContext =
+export const SharedUXRouterContext =
createContext>(defaultContextValue);
export const useKibanaSharedUX = (): SharedUXRouterContextValue<
KibanaServices & Extra
> =>
useContext(
- sharedUXContext as unknown as React.Context>
+ SharedUXRouterContext as unknown as React.Context<
+ SharedUXRouterContextValue
+ >
);
diff --git a/packages/shared-ux/router/impl/types.ts b/packages/shared-ux/router/impl/types.ts
index 833c5bdd0c816..067677d152cae 100644
--- a/packages/shared-ux/router/impl/types.ts
+++ b/packages/shared-ux/router/impl/types.ts
@@ -33,3 +33,11 @@ export declare interface SharedUXExecutionContext {
/** an inner context spawned from the current context. */
child?: SharedUXExecutionContext;
}
+
+export declare interface SharedUXRoutesContextType {
+ /**
+ * This flag is used to enable the default execution context tracking for a specific router.
+ * Enable this flag in case you don't have a custom implementation for execution context tracking.
+ * */
+ readonly enableExecutionContextTracking?: boolean;
+}
diff --git a/packages/shared-ux/router/impl/use_execution_context.ts b/packages/shared-ux/router/impl/use_execution_context.ts
index d460d4df30805..5e088fc3eac77 100644
--- a/packages/shared-ux/router/impl/use_execution_context.ts
+++ b/packages/shared-ux/router/impl/use_execution_context.ts
@@ -8,7 +8,7 @@
*/
import useDeepCompareEffect from 'react-use/lib/useDeepCompareEffect';
-import { SharedUXExecutionContextSetup } from './services';
+import type { SharedUXExecutionContextSetup } from './services';
import { SharedUXExecutionContext } from './types';
/**
diff --git a/renovate.json b/renovate.json
index f7486c4d4e5b6..cb89313c13d9f 100644
--- a/renovate.json
+++ b/renovate.json
@@ -63,10 +63,22 @@
},
{
"groupName": "@elastic/elasticsearch",
- "matchDepNames": ["@elastic/elasticsearch"],
- "reviewers": ["team:kibana-operations", "team:kibana-core"],
- "matchBaseBranches": ["main"],
- "labels": ["release_note:skip", "backport:skip", "Team:Operations", "Team:Core"],
+ "matchDepNames": [
+ "@elastic/elasticsearch"
+ ],
+ "reviewers": [
+ "team:kibana-operations",
+ "team:kibana-core"
+ ],
+ "matchBaseBranches": [
+ "main"
+ ],
+ "labels": [
+ "release_note:skip",
+ "backport:prev-minor",
+ "Team:Operations",
+ "Team:Core"
+ ],
"enabled": true
},
{
@@ -103,43 +115,117 @@
},
{
"groupName": "APM",
- "matchDepNames": ["elastic-apm-node", "@elastic/apm-rum", "@elastic/apm-rum-react"],
- "reviewers": ["team:kibana-core"],
- "matchBaseBranches": ["main"],
- "labels": ["release_note:skip", "Team:Core", "backport:skip"],
+ "matchDepNames": [
+ "elastic-apm-node",
+ "@elastic/apm-rum",
+ "@elastic/apm-rum-react",
+ "@elastic/apm-rum-core"
+ ],
+ "reviewers": [
+ "team:kibana-core"
+ ],
+ "matchBaseBranches": [
+ "main"
+ ],
+ "labels": [
+ "release_note:skip",
+ "Team:Core",
+ "backport:prev-minor"
+ ],
"enabled": true
},
{
"groupName": "RxJS",
- "matchDepNames": ["rxjs"],
- "reviewers": ["team:kibana-core"],
- "matchBaseBranches": ["main"],
- "labels": ["release_note:skip", "Team:Core", "backport:skip"],
+ "matchDepNames": [
+ "rxjs"
+ ],
+ "reviewers": [
+ "team:kibana-core"
+ ],
+ "matchBaseBranches": [
+ "main"
+ ],
+ "labels": [
+ "release_note:skip",
+ "Team:Core",
+ "backport:prev-minor"
+ ],
+ "enabled": true
+ },
+ {
+ "groupName": "stack traces",
+ "matchDepNames": [
+ "trace",
+ "clarify"
+ ],
+ "reviewers": [
+ "team:kibana-core"
+ ],
+ "matchBaseBranches": [
+ "main"
+ ],
+ "labels": [
+ "release_note:skip",
+ "Team:Core",
+ "backport:skip"
+ ],
"enabled": true
},
{
"groupName": "@elastic/ebt",
- "matchDepNames": ["@elastic/ebt"],
- "reviewers": ["team:kibana-core"],
- "matchBaseBranches": ["main"],
- "labels": ["release_note:skip", "Team:Core", "backport:skip"],
+ "matchDepNames": [
+ "@elastic/ebt"
+ ],
+ "reviewers": [
+ "team:kibana-core"
+ ],
+ "matchBaseBranches": [
+ "main"
+ ],
+ "labels": [
+ "release_note:skip",
+ "Team:Core",
+ "backport:prev-minor"
+ ],
"enabled": true
},
{
- "groupName": "ansi-regex",
- "matchDepNames": ["ansi-regex"],
- "reviewers": ["team:kibana-core"],
- "matchBaseBranches": ["main"],
- "labels": ["release_note:skip", "Team:Core", "backport:skip"],
- "minimumReleaseAge": "7 days",
+ "groupName": "lodash",
+ "matchDepNames": [
+ "lodash",
+ "@types/lodash"
+ ],
+ "reviewers": [
+ "team:kibana-core"
+ ],
+ "matchBaseBranches": [
+ "main"
+ ],
+ "labels": [
+ "release_note:skip",
+ "Team:Core",
+ "backport:prev-minor"
+ ],
"enabled": true
},
{
"groupName": "OpenAPI Spec",
- "matchDepNames": ["@redocly/cli"],
- "reviewers": ["team:kibana-core"],
- "matchBaseBranches": ["main"],
- "labels": ["release_note:skip", "Team:Core", "backport:skip"],
+ "matchDepNames": [
+ "@apidevtools/swagger-parser",
+ "@redocly/cli",
+ "openapi-types"
+ ],
+ "reviewers": [
+ "team:kibana-core"
+ ],
+ "matchBaseBranches": [
+ "main"
+ ],
+ "labels": [
+ "release_note:skip",
+ "Team:Core",
+ "backport:prev-minor"
+ ],
"minimumReleaseAge": "7 days",
"enabled": true
},
diff --git a/src/platform/packages/private/kbn-esql-editor/src/esql_editor.tsx b/src/platform/packages/private/kbn-esql-editor/src/esql_editor.tsx
index 628bab839bdb9..dcb958311a85d 100644
--- a/src/platform/packages/private/kbn-esql-editor/src/esql_editor.tsx
+++ b/src/platform/packages/private/kbn-esql-editor/src/esql_editor.tsx
@@ -84,6 +84,7 @@ export const ESQLEditor = memo(function ESQLEditor({
hideQueryHistory,
hasOutline,
displayDocumentationAsFlyout,
+ disableAutoFocus,
}: ESQLEditorProps) {
const popoverRef = useRef(null);
const datePickerOpenStatusRef = useRef(false);
@@ -727,8 +728,10 @@ export const ESQLEditor = memo(function ESQLEditor({
editor.onDidChangeModelContent(showSuggestionsIfEmptyQuery);
// Auto-focus the editor and move the cursor to the end.
- editor.focus();
- editor.setPosition({ column: Infinity, lineNumber: Infinity });
+ if (!disableAutoFocus) {
+ editor.focus();
+ editor.setPosition({ column: Infinity, lineNumber: Infinity });
+ }
}}
/>
diff --git a/src/platform/packages/private/kbn-esql-editor/src/types.ts b/src/platform/packages/private/kbn-esql-editor/src/types.ts
index a5fcaba885b0a..d1cd894ebfd37 100644
--- a/src/platform/packages/private/kbn-esql-editor/src/types.ts
+++ b/src/platform/packages/private/kbn-esql-editor/src/types.ts
@@ -66,6 +66,9 @@ export interface ESQLEditorProps {
/** adds a documentation icon in the footer which opens the inline docs as a flyout **/
displayDocumentationAsFlyout?: boolean;
+
+ /** The component by default focuses on the editor when it is mounted, this flag disables it**/
+ disableAutoFocus?: boolean;
}
export interface ESQLEditorDeps {
diff --git a/packages/kbn-openapi-common/README.md b/src/platform/packages/shared/kbn-openapi-common/README.md
similarity index 100%
rename from packages/kbn-openapi-common/README.md
rename to src/platform/packages/shared/kbn-openapi-common/README.md
diff --git a/packages/kbn-openapi-common/jest.config.js b/src/platform/packages/shared/kbn-openapi-common/jest.config.js
similarity index 83%
rename from packages/kbn-openapi-common/jest.config.js
rename to src/platform/packages/shared/kbn-openapi-common/jest.config.js
index c8e533f9d7ed8..12c38e4154655 100644
--- a/packages/kbn-openapi-common/jest.config.js
+++ b/src/platform/packages/shared/kbn-openapi-common/jest.config.js
@@ -9,6 +9,6 @@
module.exports = {
preset: '@kbn/test/jest_node',
- rootDir: '../..',
- roots: ['/packages/kbn-openapi-common'],
+ rootDir: '../../../../..',
+ roots: ['/src/platform/packages/shared/kbn-openapi-common'],
};
diff --git a/packages/kbn-openapi-common/kibana.jsonc b/src/platform/packages/shared/kbn-openapi-common/kibana.jsonc
similarity index 100%
rename from packages/kbn-openapi-common/kibana.jsonc
rename to src/platform/packages/shared/kbn-openapi-common/kibana.jsonc
diff --git a/packages/kbn-openapi-common/package.json b/src/platform/packages/shared/kbn-openapi-common/package.json
similarity index 100%
rename from packages/kbn-openapi-common/package.json
rename to src/platform/packages/shared/kbn-openapi-common/package.json
diff --git a/packages/kbn-openapi-common/schemas/error_responses.gen.ts b/src/platform/packages/shared/kbn-openapi-common/schemas/error_responses.gen.ts
similarity index 100%
rename from packages/kbn-openapi-common/schemas/error_responses.gen.ts
rename to src/platform/packages/shared/kbn-openapi-common/schemas/error_responses.gen.ts
diff --git a/packages/kbn-openapi-common/schemas/error_responses.schema.yaml b/src/platform/packages/shared/kbn-openapi-common/schemas/error_responses.schema.yaml
similarity index 100%
rename from packages/kbn-openapi-common/schemas/error_responses.schema.yaml
rename to src/platform/packages/shared/kbn-openapi-common/schemas/error_responses.schema.yaml
diff --git a/packages/kbn-openapi-common/schemas/primitives.gen.ts b/src/platform/packages/shared/kbn-openapi-common/schemas/primitives.gen.ts
similarity index 100%
rename from packages/kbn-openapi-common/schemas/primitives.gen.ts
rename to src/platform/packages/shared/kbn-openapi-common/schemas/primitives.gen.ts
diff --git a/packages/kbn-openapi-common/schemas/primitives.schema.yaml b/src/platform/packages/shared/kbn-openapi-common/schemas/primitives.schema.yaml
similarity index 100%
rename from packages/kbn-openapi-common/schemas/primitives.schema.yaml
rename to src/platform/packages/shared/kbn-openapi-common/schemas/primitives.schema.yaml
diff --git a/packages/kbn-openapi-common/schemas/primitives.test.ts b/src/platform/packages/shared/kbn-openapi-common/schemas/primitives.test.ts
similarity index 100%
rename from packages/kbn-openapi-common/schemas/primitives.test.ts
rename to src/platform/packages/shared/kbn-openapi-common/schemas/primitives.test.ts
diff --git a/packages/kbn-openapi-common/scripts/openapi_generate.js b/src/platform/packages/shared/kbn-openapi-common/scripts/openapi_generate.js
similarity index 95%
rename from packages/kbn-openapi-common/scripts/openapi_generate.js
rename to src/platform/packages/shared/kbn-openapi-common/scripts/openapi_generate.js
index 07b7c4c0e4a0b..54fa109cfb2cd 100644
--- a/packages/kbn-openapi-common/scripts/openapi_generate.js
+++ b/src/platform/packages/shared/kbn-openapi-common/scripts/openapi_generate.js
@@ -7,7 +7,7 @@
* License v3.0 only", or the "Server Side Public License, v 1".
*/
-require('../../../src/setup_node_env');
+require('../../../../../setup_node_env');
const { resolve } = require('path');
const { generate } = require('@kbn/openapi-generator');
diff --git a/packages/kbn-openapi-common/shared/index.ts b/src/platform/packages/shared/kbn-openapi-common/shared/index.ts
similarity index 100%
rename from packages/kbn-openapi-common/shared/index.ts
rename to src/platform/packages/shared/kbn-openapi-common/shared/index.ts
diff --git a/packages/kbn-openapi-common/shared/path_params_replacer.ts b/src/platform/packages/shared/kbn-openapi-common/shared/path_params_replacer.ts
similarity index 100%
rename from packages/kbn-openapi-common/shared/path_params_replacer.ts
rename to src/platform/packages/shared/kbn-openapi-common/shared/path_params_replacer.ts
diff --git a/packages/kbn-openapi-common/tsconfig.json b/src/platform/packages/shared/kbn-openapi-common/tsconfig.json
similarity index 81%
rename from packages/kbn-openapi-common/tsconfig.json
rename to src/platform/packages/shared/kbn-openapi-common/tsconfig.json
index 29a271ba4840d..cf3d0ba7804aa 100644
--- a/packages/kbn-openapi-common/tsconfig.json
+++ b/src/platform/packages/shared/kbn-openapi-common/tsconfig.json
@@ -4,7 +4,7 @@
"types": ["jest", "node"]
},
"exclude": ["target/**/*"],
- "extends": "../../tsconfig.base.json",
+ "extends": "../../../../../tsconfig.base.json",
"include": ["**/*.ts"],
"kbn_references": [
"@kbn/zod",
diff --git a/packages/kbn-rule-data-utils/index.ts b/src/platform/packages/shared/kbn-rule-data-utils/index.ts
similarity index 100%
rename from packages/kbn-rule-data-utils/index.ts
rename to src/platform/packages/shared/kbn-rule-data-utils/index.ts
diff --git a/packages/kbn-rule-data-utils/jest.config.js b/src/platform/packages/shared/kbn-rule-data-utils/jest.config.js
similarity index 83%
rename from packages/kbn-rule-data-utils/jest.config.js
rename to src/platform/packages/shared/kbn-rule-data-utils/jest.config.js
index fd0feabd9f0ad..c8cb6a4bbec63 100644
--- a/packages/kbn-rule-data-utils/jest.config.js
+++ b/src/platform/packages/shared/kbn-rule-data-utils/jest.config.js
@@ -9,6 +9,6 @@
module.exports = {
preset: '@kbn/test',
- rootDir: '../..',
- roots: ['/packages/kbn-rule-data-utils'],
+ rootDir: '../../../../..',
+ roots: ['/src/platform/packages/shared/kbn-rule-data-utils'],
};
diff --git a/packages/kbn-rule-data-utils/kibana.jsonc b/src/platform/packages/shared/kbn-rule-data-utils/kibana.jsonc
similarity index 100%
rename from packages/kbn-rule-data-utils/kibana.jsonc
rename to src/platform/packages/shared/kbn-rule-data-utils/kibana.jsonc
diff --git a/packages/kbn-rule-data-utils/package.json b/src/platform/packages/shared/kbn-rule-data-utils/package.json
similarity index 100%
rename from packages/kbn-rule-data-utils/package.json
rename to src/platform/packages/shared/kbn-rule-data-utils/package.json
diff --git a/packages/kbn-rule-data-utils/src/alerts_as_data_cases.ts b/src/platform/packages/shared/kbn-rule-data-utils/src/alerts_as_data_cases.ts
similarity index 100%
rename from packages/kbn-rule-data-utils/src/alerts_as_data_cases.ts
rename to src/platform/packages/shared/kbn-rule-data-utils/src/alerts_as_data_cases.ts
diff --git a/packages/kbn-rule-data-utils/src/alerts_as_data_rbac.test.ts b/src/platform/packages/shared/kbn-rule-data-utils/src/alerts_as_data_rbac.test.ts
similarity index 100%
rename from packages/kbn-rule-data-utils/src/alerts_as_data_rbac.test.ts
rename to src/platform/packages/shared/kbn-rule-data-utils/src/alerts_as_data_rbac.test.ts
diff --git a/packages/kbn-rule-data-utils/src/alerts_as_data_rbac.ts b/src/platform/packages/shared/kbn-rule-data-utils/src/alerts_as_data_rbac.ts
similarity index 100%
rename from packages/kbn-rule-data-utils/src/alerts_as_data_rbac.ts
rename to src/platform/packages/shared/kbn-rule-data-utils/src/alerts_as_data_rbac.ts
diff --git a/packages/kbn-rule-data-utils/src/alerts_as_data_severity.ts b/src/platform/packages/shared/kbn-rule-data-utils/src/alerts_as_data_severity.ts
similarity index 100%
rename from packages/kbn-rule-data-utils/src/alerts_as_data_severity.ts
rename to src/platform/packages/shared/kbn-rule-data-utils/src/alerts_as_data_severity.ts
diff --git a/packages/kbn-rule-data-utils/src/alerts_as_data_status.ts b/src/platform/packages/shared/kbn-rule-data-utils/src/alerts_as_data_status.ts
similarity index 100%
rename from packages/kbn-rule-data-utils/src/alerts_as_data_status.ts
rename to src/platform/packages/shared/kbn-rule-data-utils/src/alerts_as_data_status.ts
diff --git a/packages/kbn-rule-data-utils/src/default_alerts_as_data.ts b/src/platform/packages/shared/kbn-rule-data-utils/src/default_alerts_as_data.ts
similarity index 100%
rename from packages/kbn-rule-data-utils/src/default_alerts_as_data.ts
rename to src/platform/packages/shared/kbn-rule-data-utils/src/default_alerts_as_data.ts
diff --git a/packages/kbn-rule-data-utils/src/legacy_alerts_as_data.ts b/src/platform/packages/shared/kbn-rule-data-utils/src/legacy_alerts_as_data.ts
similarity index 100%
rename from packages/kbn-rule-data-utils/src/legacy_alerts_as_data.ts
rename to src/platform/packages/shared/kbn-rule-data-utils/src/legacy_alerts_as_data.ts
diff --git a/packages/kbn-rule-data-utils/src/routes/stack_rule_paths.ts b/src/platform/packages/shared/kbn-rule-data-utils/src/routes/stack_rule_paths.ts
similarity index 100%
rename from packages/kbn-rule-data-utils/src/routes/stack_rule_paths.ts
rename to src/platform/packages/shared/kbn-rule-data-utils/src/routes/stack_rule_paths.ts
diff --git a/packages/kbn-rule-data-utils/src/rule_types/index.ts b/src/platform/packages/shared/kbn-rule-data-utils/src/rule_types/index.ts
similarity index 100%
rename from packages/kbn-rule-data-utils/src/rule_types/index.ts
rename to src/platform/packages/shared/kbn-rule-data-utils/src/rule_types/index.ts
diff --git a/packages/kbn-rule-data-utils/src/rule_types/o11y_rules.ts b/src/platform/packages/shared/kbn-rule-data-utils/src/rule_types/o11y_rules.ts
similarity index 100%
rename from packages/kbn-rule-data-utils/src/rule_types/o11y_rules.ts
rename to src/platform/packages/shared/kbn-rule-data-utils/src/rule_types/o11y_rules.ts
diff --git a/packages/kbn-rule-data-utils/src/rule_types/stack_rules.ts b/src/platform/packages/shared/kbn-rule-data-utils/src/rule_types/stack_rules.ts
similarity index 100%
rename from packages/kbn-rule-data-utils/src/rule_types/stack_rules.ts
rename to src/platform/packages/shared/kbn-rule-data-utils/src/rule_types/stack_rules.ts
diff --git a/packages/kbn-rule-data-utils/src/technical_field_names.ts b/src/platform/packages/shared/kbn-rule-data-utils/src/technical_field_names.ts
similarity index 100%
rename from packages/kbn-rule-data-utils/src/technical_field_names.ts
rename to src/platform/packages/shared/kbn-rule-data-utils/src/technical_field_names.ts
diff --git a/packages/kbn-rule-data-utils/tsconfig.json b/src/platform/packages/shared/kbn-rule-data-utils/tsconfig.json
similarity index 82%
rename from packages/kbn-rule-data-utils/tsconfig.json
rename to src/platform/packages/shared/kbn-rule-data-utils/tsconfig.json
index 77352c4f44209..536c1110ab3e3 100644
--- a/packages/kbn-rule-data-utils/tsconfig.json
+++ b/src/platform/packages/shared/kbn-rule-data-utils/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../tsconfig.base.json",
+ "extends": "../../../../../tsconfig.base.json",
"compilerOptions": {
"outDir": "target/types",
"types": [
diff --git a/packages/kbn-zod-helpers/README.md b/src/platform/packages/shared/kbn-zod-helpers/README.md
similarity index 100%
rename from packages/kbn-zod-helpers/README.md
rename to src/platform/packages/shared/kbn-zod-helpers/README.md
diff --git a/packages/kbn-zod-helpers/index.ts b/src/platform/packages/shared/kbn-zod-helpers/index.ts
similarity index 100%
rename from packages/kbn-zod-helpers/index.ts
rename to src/platform/packages/shared/kbn-zod-helpers/index.ts
diff --git a/packages/kbn-zod-helpers/jest.config.js b/src/platform/packages/shared/kbn-zod-helpers/jest.config.js
similarity index 83%
rename from packages/kbn-zod-helpers/jest.config.js
rename to src/platform/packages/shared/kbn-zod-helpers/jest.config.js
index 4f66c7eed2eee..a24e940983817 100644
--- a/packages/kbn-zod-helpers/jest.config.js
+++ b/src/platform/packages/shared/kbn-zod-helpers/jest.config.js
@@ -9,6 +9,6 @@
module.exports = {
preset: '@kbn/test',
- rootDir: '../..',
- roots: ['/packages/kbn-zod-helpers'],
+ rootDir: '../../../../..',
+ roots: ['/src/platform/packages/shared/kbn-zod-helpers'],
};
diff --git a/packages/kbn-zod-helpers/kibana.jsonc b/src/platform/packages/shared/kbn-zod-helpers/kibana.jsonc
similarity index 100%
rename from packages/kbn-zod-helpers/kibana.jsonc
rename to src/platform/packages/shared/kbn-zod-helpers/kibana.jsonc
diff --git a/packages/kbn-zod-helpers/package.json b/src/platform/packages/shared/kbn-zod-helpers/package.json
similarity index 100%
rename from packages/kbn-zod-helpers/package.json
rename to src/platform/packages/shared/kbn-zod-helpers/package.json
diff --git a/packages/kbn-zod-helpers/src/array_from_string.test.ts b/src/platform/packages/shared/kbn-zod-helpers/src/array_from_string.test.ts
similarity index 100%
rename from packages/kbn-zod-helpers/src/array_from_string.test.ts
rename to src/platform/packages/shared/kbn-zod-helpers/src/array_from_string.test.ts
diff --git a/packages/kbn-zod-helpers/src/array_from_string.ts b/src/platform/packages/shared/kbn-zod-helpers/src/array_from_string.ts
similarity index 100%
rename from packages/kbn-zod-helpers/src/array_from_string.ts
rename to src/platform/packages/shared/kbn-zod-helpers/src/array_from_string.ts
diff --git a/packages/kbn-zod-helpers/src/boolean_from_string.test.ts b/src/platform/packages/shared/kbn-zod-helpers/src/boolean_from_string.test.ts
similarity index 100%
rename from packages/kbn-zod-helpers/src/boolean_from_string.test.ts
rename to src/platform/packages/shared/kbn-zod-helpers/src/boolean_from_string.test.ts
diff --git a/packages/kbn-zod-helpers/src/boolean_from_string.ts b/src/platform/packages/shared/kbn-zod-helpers/src/boolean_from_string.ts
similarity index 100%
rename from packages/kbn-zod-helpers/src/boolean_from_string.ts
rename to src/platform/packages/shared/kbn-zod-helpers/src/boolean_from_string.ts
diff --git a/packages/kbn-zod-helpers/src/build_route_validation_with_zod.ts b/src/platform/packages/shared/kbn-zod-helpers/src/build_route_validation_with_zod.ts
similarity index 100%
rename from packages/kbn-zod-helpers/src/build_route_validation_with_zod.ts
rename to src/platform/packages/shared/kbn-zod-helpers/src/build_route_validation_with_zod.ts
diff --git a/packages/kbn-zod-helpers/src/expect_parse_error.ts b/src/platform/packages/shared/kbn-zod-helpers/src/expect_parse_error.ts
similarity index 100%
rename from packages/kbn-zod-helpers/src/expect_parse_error.ts
rename to src/platform/packages/shared/kbn-zod-helpers/src/expect_parse_error.ts
diff --git a/packages/kbn-zod-helpers/src/expect_parse_success.ts b/src/platform/packages/shared/kbn-zod-helpers/src/expect_parse_success.ts
similarity index 100%
rename from packages/kbn-zod-helpers/src/expect_parse_success.ts
rename to src/platform/packages/shared/kbn-zod-helpers/src/expect_parse_success.ts
diff --git a/packages/kbn-zod-helpers/src/is_valid_date_math.ts b/src/platform/packages/shared/kbn-zod-helpers/src/is_valid_date_math.ts
similarity index 100%
rename from packages/kbn-zod-helpers/src/is_valid_date_math.ts
rename to src/platform/packages/shared/kbn-zod-helpers/src/is_valid_date_math.ts
diff --git a/packages/kbn-zod-helpers/src/non_empty_string.ts b/src/platform/packages/shared/kbn-zod-helpers/src/non_empty_string.ts
similarity index 100%
rename from packages/kbn-zod-helpers/src/non_empty_string.ts
rename to src/platform/packages/shared/kbn-zod-helpers/src/non_empty_string.ts
diff --git a/packages/kbn-zod-helpers/src/required_optional.ts b/src/platform/packages/shared/kbn-zod-helpers/src/required_optional.ts
similarity index 100%
rename from packages/kbn-zod-helpers/src/required_optional.ts
rename to src/platform/packages/shared/kbn-zod-helpers/src/required_optional.ts
diff --git a/packages/kbn-zod-helpers/src/safe_parse_result.ts b/src/platform/packages/shared/kbn-zod-helpers/src/safe_parse_result.ts
similarity index 100%
rename from packages/kbn-zod-helpers/src/safe_parse_result.ts
rename to src/platform/packages/shared/kbn-zod-helpers/src/safe_parse_result.ts
diff --git a/packages/kbn-zod-helpers/src/stringify_zod_error.ts b/src/platform/packages/shared/kbn-zod-helpers/src/stringify_zod_error.ts
similarity index 100%
rename from packages/kbn-zod-helpers/src/stringify_zod_error.ts
rename to src/platform/packages/shared/kbn-zod-helpers/src/stringify_zod_error.ts
diff --git a/packages/kbn-zod-helpers/tsconfig.json b/src/platform/packages/shared/kbn-zod-helpers/tsconfig.json
similarity index 82%
rename from packages/kbn-zod-helpers/tsconfig.json
rename to src/platform/packages/shared/kbn-zod-helpers/tsconfig.json
index 9eab856c8c4d2..d3b33b22966b8 100644
--- a/packages/kbn-zod-helpers/tsconfig.json
+++ b/src/platform/packages/shared/kbn-zod-helpers/tsconfig.json
@@ -4,7 +4,7 @@
"types": ["jest", "node"]
},
"exclude": ["target/**/*"],
- "extends": "../../tsconfig.base.json",
+ "extends": "../../../../../tsconfig.base.json",
"include": ["**/*.ts"],
"kbn_references": [
"@kbn/datemath",
diff --git a/src/platform/plugins/shared/esql/server/ui_settings.ts b/src/platform/plugins/shared/esql/server/ui_settings.ts
index 1ddae41c9b241..c3520f7adc2a2 100644
--- a/src/platform/plugins/shared/esql/server/ui_settings.ts
+++ b/src/platform/plugins/shared/esql/server/ui_settings.ts
@@ -21,7 +21,7 @@ export const getUiSettings: () => Record = () => ({
value: true,
description: i18n.translate('esql.advancedSettings.enableESQLDescription', {
defaultMessage:
- 'This setting enables ES|QL in Kibana. By switching it off you will hide the ES|QL user interface from various applications. However, users will be able to access existing ES|QL saved searches, visualizations, etc.',
+ 'This setting enables ES|QL in Kibana. By switching it off you will hide the ES|QL user interface from various applications. However, users will be able to access existing ES|QL based Discover sessions, visualizations, etc.',
}),
requiresPageReload: true,
schema: schema.boolean(),
diff --git a/src/plugins/custom_integrations/server/routes/define_routes.ts b/src/plugins/custom_integrations/server/routes/define_routes.ts
index d59d9f98ff4c1..35231c7064345 100644
--- a/src/plugins/custom_integrations/server/routes/define_routes.ts
+++ b/src/plugins/custom_integrations/server/routes/define_routes.ts
@@ -22,6 +22,11 @@ export function defineRoutes(
{
path: ROUTES_APPEND_CUSTOM_INTEGRATIONS,
validate: false,
+ security: {
+ authz: {
+ requiredPrivileges: ['integrations-read'],
+ },
+ },
},
async (context, request, response) => {
const integrations = customIntegrationsRegistry.getAppendCustomIntegrations();
@@ -35,6 +40,11 @@ export function defineRoutes(
{
path: ROUTES_REPLACEMENT_CUSTOM_INTEGRATIONS,
validate: false,
+ security: {
+ authz: {
+ requiredPrivileges: ['integrations-read'],
+ },
+ },
},
async (context, request, response) => {
const integrations = customIntegrationsRegistry.getReplacementCustomIntegrations();
diff --git a/src/plugins/dashboard/common/dashboard_container/types.ts b/src/plugins/dashboard/common/dashboard_container/types.ts
index dd3f7302038c0..528eff1f96cb8 100644
--- a/src/plugins/dashboard/common/dashboard_container/types.ts
+++ b/src/plugins/dashboard/common/dashboard_container/types.ts
@@ -8,7 +8,6 @@
*/
import {
- ViewMode,
PanelState,
EmbeddableInput,
SavedObjectEmbeddableInput,
@@ -17,6 +16,7 @@ import { Filter, Query, TimeRange } from '@kbn/es-query';
import type { Reference } from '@kbn/content-management-utils';
import { RefreshInterval } from '@kbn/data-plugin/common';
import { KibanaExecutionContext } from '@kbn/core-execution-context-common';
+import type { ViewMode } from '@kbn/presentation-publishing';
import type { DashboardOptions, GridData } from '../../server/content_management';
@@ -44,7 +44,7 @@ export interface DashboardPanelState<
export type DashboardContainerByReferenceInput = SavedObjectEmbeddableInput;
-export interface DashboardContainerInput extends EmbeddableInput {
+export interface DashboardContainerInput extends Omit {
// filter context to be passed to children
query: Query;
filters: Filter[];
diff --git a/src/plugins/dashboard/public/dashboard_app/dashboard_app.tsx b/src/plugins/dashboard/public/dashboard_app/dashboard_app.tsx
index 06f56669630eb..39616653eea25 100644
--- a/src/plugins/dashboard/public/dashboard_app/dashboard_app.tsx
+++ b/src/plugins/dashboard/public/dashboard_app/dashboard_app.tsx
@@ -14,10 +14,10 @@ import { debounceTime } from 'rxjs';
import { v4 as uuidv4 } from 'uuid';
import { DASHBOARD_APP_LOCATOR } from '@kbn/deeplinks-analytics';
-import { ViewMode } from '@kbn/embeddable-plugin/public';
import { useExecutionContext } from '@kbn/kibana-react-plugin/public';
import { createKbnUrlStateStorage, withNotifyOnErrors } from '@kbn/kibana-utils-plugin/public';
+import { ViewMode } from '@kbn/presentation-publishing';
import { DashboardApi, DashboardCreationOptions, DashboardRenderer } from '..';
import { SharedDashboardState } from '../../common';
import {
@@ -154,7 +154,7 @@ export function DashboardApp({
// if print mode is active, force viewMode.PRINT
...(screenshotModeService.isScreenshotMode() &&
screenshotModeService.getScreenshotContext('layout') === 'print'
- ? { viewMode: ViewMode.PRINT }
+ ? { viewMode: 'print' as ViewMode }
: {}),
};
};
diff --git a/src/plugins/dashboard/public/dashboard_app/dashboard_router.tsx b/src/plugins/dashboard/public/dashboard_app/dashboard_router.tsx
index f994d9aa20c8e..6b59bf03a4bcd 100644
--- a/src/plugins/dashboard/public/dashboard_app/dashboard_router.tsx
+++ b/src/plugins/dashboard/public/dashboard_app/dashboard_router.tsx
@@ -10,7 +10,6 @@
import './_dashboard_app.scss';
import { AppMountParameters, CoreStart } from '@kbn/core/public';
-import { ViewMode } from '@kbn/embeddable-plugin/public';
import { createKbnUrlStateStorage, withNotifyOnErrors } from '@kbn/kibana-utils-plugin/public';
import { KibanaRenderContextProvider } from '@kbn/react-kibana-context-render';
import { Route, Routes } from '@kbn/shared-ux-router';
@@ -72,7 +71,7 @@ export async function mountApp({
if (redirectTo.destination === 'dashboard') {
path = redirectTo.id ? createDashboardEditUrl(redirectTo.id) : CREATE_NEW_DASHBOARD_URL;
if (redirectTo.editMode) {
- state = { viewMode: ViewMode.EDIT };
+ state = { viewMode: 'edit' };
}
} else {
path = createDashboardListingFilterUrl(redirectTo.filter);
diff --git a/src/plugins/dashboard/public/dashboard_app/listing_page/dashboard_listing_page.tsx b/src/plugins/dashboard/public/dashboard_app/listing_page/dashboard_listing_page.tsx
index 59b3b3926060a..55f8bcabdfea6 100644
--- a/src/plugins/dashboard/public/dashboard_app/listing_page/dashboard_listing_page.tsx
+++ b/src/plugins/dashboard/public/dashboard_app/listing_page/dashboard_listing_page.tsx
@@ -10,7 +10,6 @@
import React, { useEffect, useState } from 'react';
import { syncGlobalQueryStateWithUrl } from '@kbn/data-plugin/public';
-import { ViewMode } from '@kbn/embeddable-plugin/public';
import type { IKbnUrlStateStorage } from '@kbn/kibana-utils-plugin/public';
import { DashboardRedirect } from '../../dashboard_container/types';
@@ -108,7 +107,7 @@ export const DashboardListingPage = ({
useSessionStorageIntegration={true}
initialFilter={initialFilter ?? titleFilter}
goToDashboard={(id, viewMode) => {
- redirectTo({ destination: 'dashboard', id, editMode: viewMode === ViewMode.EDIT });
+ redirectTo({ destination: 'dashboard', id, editMode: viewMode === 'edit' });
}}
getDashboardUrl={(id, timeRestore) => {
return getDashboardListItemLink(kbnUrlStateStorage, id, timeRestore);
diff --git a/src/plugins/dashboard/public/dashboard_app/top_nav/share/show_share_modal.tsx b/src/plugins/dashboard/public/dashboard_app/top_nav/share/show_share_modal.tsx
index 41a290844328a..d8b4c341cf678 100644
--- a/src/plugins/dashboard/public/dashboard_app/top_nav/share/show_share_modal.tsx
+++ b/src/plugins/dashboard/public/dashboard_app/top_nav/share/show_share_modal.tsx
@@ -15,7 +15,6 @@ import { EuiCallOut, EuiCheckboxGroup } from '@elastic/eui';
import type { Capabilities } from '@kbn/core/public';
import { QueryState } from '@kbn/data-plugin/common';
import { DASHBOARD_APP_LOCATOR } from '@kbn/deeplinks-analytics';
-import { ViewMode } from '@kbn/embeddable-plugin/public';
import { i18n } from '@kbn/i18n';
import { getStateFromKbnUrl, setStateToKbnUrl, unhashUrl } from '@kbn/kibana-utils-plugin/public';
@@ -177,7 +176,7 @@ export function ShowShareModal({
dashboardId: savedObjectId,
preserveSavedFilters: true,
refreshInterval: undefined, // We don't share refresh interval externally
- viewMode: ViewMode.VIEW, // For share locators we always load the dashboard in view mode
+ viewMode: 'view', // For share locators we always load the dashboard in view mode
useHash: false,
timeRange: dataService.query.timefilter.timefilter.getTime(),
...unsavedStateForLocator,
diff --git a/src/plugins/dashboard/public/dashboard_app/top_nav/use_dashboard_menu_items.tsx b/src/plugins/dashboard/public/dashboard_app/top_nav/use_dashboard_menu_items.tsx
index 07e29db545e7f..6f3d9c1cf5654 100644
--- a/src/plugins/dashboard/public/dashboard_app/top_nav/use_dashboard_menu_items.tsx
+++ b/src/plugins/dashboard/public/dashboard_app/top_nav/use_dashboard_menu_items.tsx
@@ -9,7 +9,6 @@
import { Dispatch, SetStateAction, useCallback, useMemo, useState } from 'react';
-import { ViewMode } from '@kbn/embeddable-plugin/public';
import type { TopNavMenuData } from '@kbn/navigation-plugin/public';
import useMountedState from 'react-use/lib/useMountedState';
@@ -97,8 +96,8 @@ export const useDashboardMenuItems = ({
dashboardApi.clearOverlays();
const switchModes = switchToViewMode
? () => {
- dashboardApi.setViewMode(ViewMode.VIEW);
- getDashboardBackupService().storeViewMode(ViewMode.VIEW);
+ dashboardApi.setViewMode('view');
+ getDashboardBackupService().storeViewMode('view');
}
: undefined;
if (!hasUnsavedChanges) {
@@ -112,7 +111,7 @@ export const useDashboardMenuItems = ({
setIsResetting(false);
switchModes?.();
}
- }, viewMode as ViewMode);
+ }, viewMode);
},
[dashboardApi, hasUnsavedChanges, viewMode, isMounted]
);
@@ -146,8 +145,8 @@ export const useDashboardMenuItems = ({
testId: 'dashboardEditMode',
className: 'eui-hideFor--s eui-hideFor--xs', // hide for small screens - editing doesn't work in mobile mode.
run: () => {
- getDashboardBackupService().storeViewMode(ViewMode.EDIT);
- dashboardApi.setViewMode(ViewMode.EDIT);
+ getDashboardBackupService().storeViewMode('edit');
+ dashboardApi.setViewMode('edit');
dashboardApi.clearOverlays();
},
disableButton: disableTopNav,
@@ -171,13 +170,13 @@ export const useDashboardMenuItems = ({
testId: 'dashboardInteractiveSaveMenuItem',
run: dashboardInteractiveSave,
label:
- viewMode === ViewMode.VIEW
+ viewMode === 'view'
? topNavStrings.viewModeInteractiveSave.label
: Boolean(lastSavedId)
? topNavStrings.editModeInteractiveSave.label
: topNavStrings.quickSave.label,
description:
- viewMode === ViewMode.VIEW
+ viewMode === 'view'
? topNavStrings.viewModeInteractiveSave.description
: topNavStrings.editModeInteractiveSave.description,
} as TopNavMenuData,
@@ -232,7 +231,7 @@ export const useDashboardMenuItems = ({
isResetting ||
!hasUnsavedChanges ||
hasOverlays ||
- (viewMode === ViewMode.EDIT && (isSaveInProgress || !lastSavedId)),
+ (viewMode === 'edit' && (isSaveInProgress || !lastSavedId)),
isLoading: isResetting,
run: () => resetChanges(),
};
diff --git a/src/plugins/dashboard/public/dashboard_app/url/search_sessions_integration.ts b/src/plugins/dashboard/public/dashboard_app/url/search_sessions_integration.ts
index 37c9af6944f7a..9992ac661614e 100644
--- a/src/plugins/dashboard/public/dashboard_app/url/search_sessions_integration.ts
+++ b/src/plugins/dashboard/public/dashboard_app/url/search_sessions_integration.ts
@@ -18,7 +18,6 @@ import {
import { replaceUrlHashQuery } from '@kbn/kibana-utils-plugin/common';
import type { Query } from '@kbn/es-query';
import { SearchSessionInfoProvider } from '@kbn/data-plugin/public';
-import type { ViewMode } from '@kbn/embeddable-plugin/common';
import { DASHBOARD_APP_LOCATOR } from '@kbn/deeplinks-analytics';
import { SEARCH_SESSION_ID } from '../../dashboard_constants';
import { DashboardLocatorParams } from '../../dashboard_container';
@@ -73,7 +72,7 @@ function getLocatorParams({
}): DashboardLocatorParams {
const savedObjectId = dashboardApi.savedObjectId.value;
return {
- viewMode: (dashboardApi.viewMode.value as ViewMode) ?? 'view',
+ viewMode: dashboardApi.viewMode.value ?? 'view',
useHash: false,
preserveSavedFilters: false,
filters: dataService.query.filterManager.getFilters(),
diff --git a/src/plugins/dashboard/public/dashboard_constants.ts b/src/plugins/dashboard/public/dashboard_constants.ts
index da8c56bd70ee8..190b6653341a1 100644
--- a/src/plugins/dashboard/public/dashboard_constants.ts
+++ b/src/plugins/dashboard/public/dashboard_constants.ts
@@ -7,7 +7,6 @@
* License v3.0 only", or the "Server Side Public License, v 1".
*/
-import { ViewMode } from '@kbn/embeddable-plugin/common';
import type { DashboardContainerInput } from '../common';
// ------------------------------------------------------------------
@@ -85,7 +84,7 @@ export const DASHBOARD_CACHE_TTL = 1000 * 60 * 5; // time to live = 5 minutes
// Default State
// ------------------------------------------------------------------
export const DEFAULT_DASHBOARD_INPUT: Omit = {
- viewMode: ViewMode.VIEW,
+ viewMode: 'view',
timeRestore: false,
query: { query: '', language: 'kuery' },
description: '',
diff --git a/src/plugins/dashboard/public/dashboard_container/component/empty_screen/dashboard_empty_screen.tsx b/src/plugins/dashboard/public/dashboard_container/component/empty_screen/dashboard_empty_screen.tsx
index b7a4facde1c1e..73d225dca3b40 100644
--- a/src/plugins/dashboard/public/dashboard_container/component/empty_screen/dashboard_empty_screen.tsx
+++ b/src/plugins/dashboard/public/dashboard_container/component/empty_screen/dashboard_empty_screen.tsx
@@ -20,7 +20,6 @@ import {
EuiText,
} from '@elastic/eui';
import { METRIC_TYPE } from '@kbn/analytics';
-import { ViewMode } from '@kbn/embeddable-plugin/public';
import { useStateFromPublishingSubject } from '@kbn/presentation-publishing';
import { useDashboardApi } from '../../../dashboard_api/use_dashboard_api';
@@ -131,7 +130,7 @@ export function DashboardEmptyScreen() {
}
if (showWriteControls) {
return (
- dashboardApi.setViewMode(ViewMode.EDIT)}>
+ dashboardApi.setViewMode('edit')}>
{emptyScreenStrings.getEditLinkTitle()}
);
diff --git a/src/plugins/dashboard/public/dashboard_container/component/grid/dashboard_grid.tsx b/src/plugins/dashboard/public/dashboard_container/component/grid/dashboard_grid.tsx
index 1f5e48dd7a5df..e521a1bbd276c 100644
--- a/src/plugins/dashboard/public/dashboard_container/component/grid/dashboard_grid.tsx
+++ b/src/plugins/dashboard/public/dashboard_container/component/grid/dashboard_grid.tsx
@@ -15,8 +15,6 @@ import classNames from 'classnames';
import React, { useState, useMemo, useCallback, useEffect } from 'react';
import { Layout, Responsive as ResponsiveReactGridLayout } from 'react-grid-layout';
-import { ViewMode } from '@kbn/embeddable-plugin/public';
-
import { useBatchedPublishingSubjects } from '@kbn/presentation-publishing';
import { useAppFixedViewport } from '@kbn/core-rendering-browser';
import { DashboardPanelState } from '../../../../common';
@@ -106,7 +104,7 @@ export const DashboardGrid = ({
const onLayoutChange = useCallback(
(newLayout: Array) => {
- if (viewMode !== ViewMode.EDIT) return;
+ if (viewMode !== 'edit') return;
const updatedPanels: { [key: string]: DashboardPanelState } = newLayout.reduce(
(updatedPanelsAcc, panelLayout) => {
@@ -127,8 +125,8 @@ export const DashboardGrid = ({
const classes = classNames({
'dshLayout-withoutMargins': !useMargins,
- 'dshLayout--viewing': viewMode === ViewMode.VIEW,
- 'dshLayout--editing': viewMode !== ViewMode.VIEW,
+ 'dshLayout--viewing': viewMode === 'view',
+ 'dshLayout--editing': viewMode !== 'view',
'dshLayout--noAnimation': !animatePanelTransforms || delayedIsPanelExpanded,
'dshLayout-isMaximizedPanel': expandedPanelId !== undefined,
});
@@ -136,7 +134,7 @@ export const DashboardGrid = ({
const { layouts, breakpoints, columns } = useDashboardGridSettings(panelsInOrder, panels);
// in print mode, dashboard layout is not controlled by React Grid Layout
- if (viewMode === ViewMode.PRINT) {
+ if (viewMode === 'print') {
return <>{panelComponents}>;
}
diff --git a/src/plugins/dashboard/public/dashboard_container/component/grid/use_dashboard_grid_settings.tsx b/src/plugins/dashboard/public/dashboard_container/component/grid/use_dashboard_grid_settings.tsx
index 155d7022141db..50481d1a82f72 100644
--- a/src/plugins/dashboard/public/dashboard_container/component/grid/use_dashboard_grid_settings.tsx
+++ b/src/plugins/dashboard/public/dashboard_container/component/grid/use_dashboard_grid_settings.tsx
@@ -10,7 +10,6 @@
import { useMemo } from 'react';
import { useEuiTheme } from '@elastic/eui';
-import { ViewMode } from '@kbn/embeddable-plugin/public';
import { useStateFromPublishingSubject } from '@kbn/presentation-publishing';
import { DashboardPanelMap } from '../../../../common';
@@ -30,14 +29,14 @@ export const useDashboardGridSettings = (panelsInOrder: string[], panels: Dashbo
}, [panels, panelsInOrder]);
const breakpoints = useMemo(
- () => ({ lg: euiTheme.breakpoint.m, ...(viewMode === ViewMode.VIEW ? { sm: 0 } : {}) }),
+ () => ({ lg: euiTheme.breakpoint.m, ...(viewMode === 'view' ? { sm: 0 } : {}) }),
[viewMode, euiTheme.breakpoint.m]
);
const columns = useMemo(
() => ({
lg: DASHBOARD_GRID_COLUMN_COUNT,
- ...(viewMode === ViewMode.VIEW ? { sm: 1 } : {}),
+ ...(viewMode === 'view' ? { sm: 1 } : {}),
}),
[viewMode]
);
diff --git a/src/plugins/dashboard/public/dashboard_container/component/viewport/dashboard_viewport.tsx b/src/plugins/dashboard/public/dashboard_container/component/viewport/dashboard_viewport.tsx
index 32f1f830ba938..0252341b5f4b9 100644
--- a/src/plugins/dashboard/public/dashboard_container/component/viewport/dashboard_viewport.tsx
+++ b/src/plugins/dashboard/public/dashboard_container/component/viewport/dashboard_viewport.tsx
@@ -13,7 +13,7 @@ import useResizeObserver from 'use-resize-observer/polyfilled';
import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { EuiPortal } from '@elastic/eui';
-import { ReactEmbeddableRenderer, ViewMode } from '@kbn/embeddable-plugin/public';
+import { ReactEmbeddableRenderer } from '@kbn/embeddable-plugin/public';
import { ExitFullScreenButton } from '@kbn/shared-ux-button-exit-full-screen';
import {
@@ -119,7 +119,7 @@ export const DashboardViewport = ({ dashboardContainer }: { dashboardContainer?:
'dshDashboardViewportWrapper--isFullscreen': fullScreenMode,
})}
>
- {viewMode !== ViewMode.PRINT ? (
+ {viewMode !== 'print' ? (
@@ -116,7 +116,7 @@ export const resetConfirmStrings = {
defaultMessage: 'Reset dashboard?',
}),
getResetSubtitle: (viewMode: ViewMode) =>
- viewMode === ViewMode.EDIT
+ viewMode === 'edit'
? i18n.translate('dashboard.discardChangesConfirmModal.discardChangesDescription', {
defaultMessage: `All unsaved changes will be lost.`,
})
diff --git a/src/plugins/dashboard/public/dashboard_listing/confirm_overlays.tsx b/src/plugins/dashboard/public/dashboard_listing/confirm_overlays.tsx
index a2adea2470abb..d6e3728df023d 100644
--- a/src/plugins/dashboard/public/dashboard_listing/confirm_overlays.tsx
+++ b/src/plugins/dashboard/public/dashboard_listing/confirm_overlays.tsx
@@ -21,9 +21,9 @@ import {
EuiOutsideClickDetector,
EuiText,
} from '@elastic/eui';
-import { ViewMode } from '@kbn/embeddable-plugin/public';
import { toMountPoint } from '@kbn/react-kibana-mount';
+import { ViewMode } from '@kbn/presentation-publishing';
import { coreServices } from '../services/kibana_services';
import { createConfirmStrings, resetConfirmStrings } from './_dashboard_listing_strings';
@@ -31,12 +31,12 @@ export type DiscardOrKeepSelection = 'cancel' | 'discard' | 'keep';
export const confirmDiscardUnsavedChanges = (
discardCallback: () => void,
- viewMode: ViewMode = ViewMode.EDIT // we want to show the danger modal on the listing page
+ viewMode: ViewMode = 'edit' // we want to show the danger modal on the listing page
) => {
coreServices.overlays
.openConfirm(resetConfirmStrings.getResetSubtitle(viewMode), {
confirmButtonText: resetConfirmStrings.getResetConfirmButtonText(),
- buttonColor: viewMode === ViewMode.EDIT ? 'danger' : 'primary',
+ buttonColor: viewMode === 'edit' ? 'danger' : 'primary',
maxWidth: 500,
defaultFocusedButton: EUI_MODAL_CANCEL_BUTTON,
title: resetConfirmStrings.getResetTitle(),
diff --git a/src/plugins/dashboard/public/dashboard_listing/dashboard_unsaved_listing.test.tsx b/src/plugins/dashboard/public/dashboard_listing/dashboard_unsaved_listing.test.tsx
index 74b538d87c207..5cadd610ea2af 100644
--- a/src/plugins/dashboard/public/dashboard_listing/dashboard_unsaved_listing.test.tsx
+++ b/src/plugins/dashboard/public/dashboard_listing/dashboard_unsaved_listing.test.tsx
@@ -11,7 +11,6 @@ import { ComponentType, mount } from 'enzyme';
import React from 'react';
import { findTestSubject } from '@elastic/eui/lib/test';
-import { ViewMode } from '@kbn/embeddable-plugin/public';
import { I18nProvider } from '@kbn/i18n-react';
import { waitFor } from '@testing-library/react';
@@ -72,7 +71,7 @@ describe('Unsaved listing', () => {
expect(getEditButton().length).toEqual(1);
});
getEditButton().simulate('click');
- expect(props.goToDashboard).toHaveBeenCalledWith('dashboardUnsavedOne', ViewMode.EDIT);
+ expect(props.goToDashboard).toHaveBeenCalledWith('dashboardUnsavedOne', 'edit');
});
it('Redirects to new dashboard when continue editing clicked', async () => {
@@ -85,7 +84,7 @@ describe('Unsaved listing', () => {
expect(getEditButton().length).toBe(1);
});
getEditButton().simulate('click');
- expect(props.goToDashboard).toHaveBeenCalledWith(undefined, ViewMode.EDIT);
+ expect(props.goToDashboard).toHaveBeenCalledWith(undefined, 'edit');
});
it('Shows a warning then clears changes when delete unsaved changes is pressed', async () => {
diff --git a/src/plugins/dashboard/public/dashboard_listing/dashboard_unsaved_listing.tsx b/src/plugins/dashboard/public/dashboard_listing/dashboard_unsaved_listing.tsx
index 04f40a199e83b..1ab1aecfce916 100644
--- a/src/plugins/dashboard/public/dashboard_listing/dashboard_unsaved_listing.tsx
+++ b/src/plugins/dashboard/public/dashboard_listing/dashboard_unsaved_listing.tsx
@@ -18,8 +18,7 @@ import {
} from '@elastic/eui';
import React, { useCallback, useEffect, useMemo, useState } from 'react';
-import { ViewMode } from '@kbn/embeddable-plugin/public';
-
+import { ViewMode } from '@kbn/presentation-publishing';
import type { DashboardAttributes } from '../../server/content_management';
import {
DASHBOARD_PANELS_UNSAVED_ID,
@@ -124,7 +123,7 @@ export const DashboardUnsavedListing = ({
const onOpen = useCallback(
(id?: string) => {
- goToDashboard(id, ViewMode.EDIT);
+ goToDashboard(id, 'edit');
},
[goToDashboard]
);
diff --git a/src/plugins/dashboard/public/dashboard_listing/hooks/use_dashboard_listing_table.tsx b/src/plugins/dashboard/public/dashboard_listing/hooks/use_dashboard_listing_table.tsx
index e29f93f97c17e..23d29898e49c2 100644
--- a/src/plugins/dashboard/public/dashboard_listing/hooks/use_dashboard_listing_table.tsx
+++ b/src/plugins/dashboard/public/dashboard_listing/hooks/use_dashboard_listing_table.tsx
@@ -14,7 +14,7 @@ import { ContentInsightsClient } from '@kbn/content-management-content-insights-
import { TableListViewTableProps } from '@kbn/content-management-table-list-view-table';
import type { SavedObjectsFindOptionsReference } from '@kbn/core/public';
import { reportPerformanceMetricEvent } from '@kbn/ebt-tools';
-import { ViewMode } from '@kbn/embeddable-plugin/public';
+import { ViewMode } from '@kbn/presentation-publishing';
import type { DashboardSearchOut } from '../../../server/content_management';
import {
@@ -270,7 +270,7 @@ export const useDashboardListingTable = ({
);
const editItem = useCallback(
- ({ id }: { id: string | undefined }) => goToDashboard(id, ViewMode.EDIT),
+ ({ id }: { id: string | undefined }) => goToDashboard(id, 'edit'),
[goToDashboard]
);
diff --git a/src/plugins/dashboard/public/dashboard_listing/types.ts b/src/plugins/dashboard/public/dashboard_listing/types.ts
index 0f5e245366242..84a47012b04ce 100644
--- a/src/plugins/dashboard/public/dashboard_listing/types.ts
+++ b/src/plugins/dashboard/public/dashboard_listing/types.ts
@@ -9,7 +9,7 @@
import type { PropsWithChildren } from 'react';
import type { UserContentCommonSchema } from '@kbn/content-management-table-list-view-common';
-import type { ViewMode } from '@kbn/embeddable-plugin/public';
+import { ViewMode } from '@kbn/presentation-publishing';
export type DashboardListingProps = PropsWithChildren<{
disableCreateDashboardButton?: boolean;
diff --git a/src/plugins/dashboard/public/mocks.tsx b/src/plugins/dashboard/public/mocks.tsx
index 1a275d805e5ed..334bf9ee05208 100644
--- a/src/plugins/dashboard/public/mocks.tsx
+++ b/src/plugins/dashboard/public/mocks.tsx
@@ -9,7 +9,6 @@
import { ControlGroupApi } from '@kbn/controls-plugin/public';
import { BehaviorSubject } from 'rxjs';
-import { ViewMode } from '@kbn/embeddable-plugin/public';
import { DashboardStart } from './plugin';
import { DashboardState } from './dashboard_api/types';
import { getDashboardApi } from './dashboard_api/get_dashboard_api';
@@ -97,7 +96,6 @@ export function buildMockDashboardApi({
dashboardInput: {
...initialState,
executionContext: { type: 'dashboard' },
- viewMode: initialState.viewMode as ViewMode,
id: savedObjectId ?? '123',
} as SavedDashboardInput,
references: [],
diff --git a/src/plugins/dashboard/public/plugin.tsx b/src/plugins/dashboard/public/plugin.tsx
index a8e7cd96f38db..c8b2244d6865b 100644
--- a/src/plugins/dashboard/public/plugin.tsx
+++ b/src/plugins/dashboard/public/plugin.tsx
@@ -298,7 +298,7 @@ export class DashboardPlugin
defaultMessage: 'Analyze data in dashboards.',
}),
description: i18n.translate('dashboard.featureCatalogue.dashboardDescription', {
- defaultMessage: 'Display and share a collection of visualizations and saved searches.',
+ defaultMessage: 'Display and share a collection of visualizations and search results.',
}),
icon: 'dashboardApp',
path: `/app/${DASHBOARD_APP_ID}#${LANDING_PAGE_PATH}`,
diff --git a/src/plugins/dashboard/public/services/dashboard_content_management_service/lib/load_dashboard_state.ts b/src/plugins/dashboard/public/services/dashboard_content_management_service/lib/load_dashboard_state.ts
index 9773291b2ca5c..f0fe47b54ba90 100644
--- a/src/plugins/dashboard/public/services/dashboard_content_management_service/lib/load_dashboard_state.ts
+++ b/src/plugins/dashboard/public/services/dashboard_content_management_service/lib/load_dashboard_state.ts
@@ -11,7 +11,6 @@ import { has } from 'lodash';
import { v4 as uuidv4 } from 'uuid';
import { injectSearchSourceReferences } from '@kbn/data-plugin/public';
-import { ViewMode } from '@kbn/embeddable-plugin/public';
import { Filter, Query } from '@kbn/es-query';
import { SavedObjectNotFound } from '@kbn/kibana-utils-plugin/public';
@@ -188,7 +187,7 @@ export const loadDashboardState = async ({
query,
title,
- viewMode: ViewMode.VIEW, // dashboards loaded from saved object default to view mode. If it was edited recently, the view mode from session storage will override this.
+ viewMode: 'view', // dashboards loaded from saved object default to view mode. If it was edited recently, the view mode from session storage will override this.
tags:
savedObjectsTaggingService?.getTaggingApi()?.ui.getTagIdsFromReferences(references) ?? [],
diff --git a/src/plugins/data/server/ui_settings.ts b/src/plugins/data/server/ui_settings.ts
index 8dc58c3ffd637..857de03d4dbd0 100644
--- a/src/plugins/data/server/ui_settings.ts
+++ b/src/plugins/data/server/ui_settings.ts
@@ -55,7 +55,7 @@ export function getUiSettings(
value: true,
description: i18n.translate('data.advancedSettings.docTableHighlightText', {
defaultMessage:
- 'Highlight results in Discover and Saved Searches Dashboard. ' +
+ 'Highlights search results in Discover and Discover session panels on dashboards. ' +
'Highlighting makes requests slow when working on big documents.',
}),
category: ['discover'],
diff --git a/src/plugins/data_view_management/public/components/edit_index_pattern/source_filters_table/components/header/__snapshots__/header.test.tsx.snap b/src/plugins/data_view_management/public/components/edit_index_pattern/source_filters_table/components/header/__snapshots__/header.test.tsx.snap
index 83a272d88d15b..97486302553f5 100644
--- a/src/plugins/data_view_management/public/components/edit_index_pattern/source_filters_table/components/header/__snapshots__/header.test.tsx.snap
+++ b/src/plugins/data_view_management/public/components/edit_index_pattern/source_filters_table/components/header/__snapshots__/header.test.tsx.snap
@@ -7,7 +7,7 @@ exports[`Header should render normally 1`] = `
>
diff --git a/src/plugins/data_view_management/public/components/edit_index_pattern/source_filters_table/components/header/header.tsx b/src/plugins/data_view_management/public/components/edit_index_pattern/source_filters_table/components/header/header.tsx
index 3530493a7490a..86a77e6512af4 100644
--- a/src/plugins/data_view_management/public/components/edit_index_pattern/source_filters_table/components/header/header.tsx
+++ b/src/plugins/data_view_management/public/components/edit_index_pattern/source_filters_table/components/header/header.tsx
@@ -19,7 +19,7 @@ export const Header = () => (
diff --git a/src/plugins/discover/README.md b/src/plugins/discover/README.md
index 6240cd63f3ea3..6f3f17c97e7a0 100644
--- a/src/plugins/discover/README.md
+++ b/src/plugins/discover/README.md
@@ -16,7 +16,7 @@ One folder for every "route", each folder contains files and folders related onl
* **[/not_found](./public/application/not_found)** (Rendered when a route can't be found)
* **[/view_alert](./public/application/view_alert)** (Forwarding links in alert notifications)
* **[/components](./public/components)** (All React components used in more than just one app)
-* **[/embeddable](./public/embeddable)** (Code related to the saved search embeddable, rendered on dashboards)
+* **[/embeddable](./public/embeddable)** (Code related to the Discover session embeddable, rendered on dashboards)
* **[/hooks](./public/hooks)** (Code containing React hooks)
* **[/services](./public/services)** (Services either for external or internal use)
* **[/utils](./public/utils)** (All utility functions used across more than one application)
diff --git a/src/plugins/discover/public/application/index.tsx b/src/plugins/discover/public/application/index.tsx
index 426e388811723..99fc03170a9bb 100644
--- a/src/plugins/discover/public/application/index.tsx
+++ b/src/plugins/discover/public/application/index.tsx
@@ -37,7 +37,7 @@ export const renderApp = ({
defaultMessage: 'Read only',
}),
tooltip: i18n.translate('discover.badge.readOnly.tooltip', {
- defaultMessage: 'Unable to save searches',
+ defaultMessage: 'Unable to save Discover sessions',
}),
iconType: 'glasses',
});
diff --git a/src/plugins/discover/public/application/main/components/top_nav/__snapshots__/open_search_panel.test.tsx.snap b/src/plugins/discover/public/application/main/components/top_nav/__snapshots__/open_search_panel.test.tsx.snap
index b1b399d1bd736..934e7068e78db 100644
--- a/src/plugins/discover/public/application/main/components/top_nav/__snapshots__/open_search_panel.test.tsx.snap
+++ b/src/plugins/discover/public/application/main/components/top_nav/__snapshots__/open_search_panel.test.tsx.snap
@@ -14,7 +14,7 @@ exports[`OpenSearchPanel render 1`] = `
>
@@ -25,7 +25,7 @@ exports[`OpenSearchPanel render 1`] = `
id="discoverOpenSearch"
noItemsMessage={
}
@@ -34,7 +34,7 @@ exports[`OpenSearchPanel render 1`] = `
Array [
Object {
"getIconForSavedObject": [Function],
- "name": "Saved search",
+ "name": "Discover session",
"type": "search",
},
]
@@ -59,11 +59,11 @@ exports[`OpenSearchPanel render 1`] = `
diff --git a/src/plugins/discover/public/application/main/components/top_nav/app_menu_actions/get_new_search.tsx b/src/plugins/discover/public/application/main/components/top_nav/app_menu_actions/get_new_search.tsx
index b67f14f31c56a..a27b1f5753e20 100644
--- a/src/plugins/discover/public/application/main/components/top_nav/app_menu_actions/get_new_search.tsx
+++ b/src/plugins/discover/public/application/main/components/top_nav/app_menu_actions/get_new_search.tsx
@@ -19,11 +19,8 @@ export const getNewSearchAppMenuItem = ({
id: AppMenuActionId.new,
type: AppMenuActionType.primary,
controlProps: {
- label: i18n.translate('discover.localMenu.localMenu.newSearchTitle', {
- defaultMessage: 'New',
- }),
- description: i18n.translate('discover.localMenu.newSearchDescription', {
- defaultMessage: 'New Search',
+ label: i18n.translate('discover.localMenu.localMenu.newDiscoverSessionTitle', {
+ defaultMessage: 'New session',
}),
iconType: 'plus',
testId: 'discoverNewButton',
diff --git a/src/plugins/discover/public/application/main/components/top_nav/app_menu_actions/get_open_search.tsx b/src/plugins/discover/public/application/main/components/top_nav/app_menu_actions/get_open_search.tsx
index e8f6c5448d602..0a3d75af893cc 100644
--- a/src/plugins/discover/public/application/main/components/top_nav/app_menu_actions/get_open_search.tsx
+++ b/src/plugins/discover/public/application/main/components/top_nav/app_menu_actions/get_open_search.tsx
@@ -21,11 +21,8 @@ export const getOpenSearchAppMenuItem = ({
id: AppMenuActionId.open,
type: AppMenuActionType.primary,
controlProps: {
- label: i18n.translate('discover.localMenu.openTitle', {
- defaultMessage: 'Open',
- }),
- description: i18n.translate('discover.localMenu.openSavedSearchDescription', {
- defaultMessage: 'Open Saved Search',
+ label: i18n.translate('discover.localMenu.openDiscoverSessionTitle', {
+ defaultMessage: 'Open session',
}),
iconType: 'folderOpen',
testId: 'discoverOpenButton',
diff --git a/src/plugins/discover/public/application/main/components/top_nav/app_menu_actions/get_share.tsx b/src/plugins/discover/public/application/main/components/top_nav/app_menu_actions/get_share.tsx
index f1a030a40ea0a..87514e81a063e 100644
--- a/src/plugins/discover/public/application/main/components/top_nav/app_menu_actions/get_share.tsx
+++ b/src/plugins/discover/public/application/main/components/top_nav/app_menu_actions/get_share.tsx
@@ -34,7 +34,7 @@ export const getShareAppMenuItem = ({
defaultMessage: 'Share',
}),
description: i18n.translate('discover.localMenu.shareSearchDescription', {
- defaultMessage: 'Share Search',
+ defaultMessage: 'Share Discover session',
}),
iconType: 'share',
testId: 'shareTopNavButton',
@@ -108,7 +108,7 @@ export const getShareAppMenuItem = ({
objectType: 'search',
objectTypeMeta: {
title: i18n.translate('discover.share.shareModal.title', {
- defaultMessage: 'Share this search',
+ defaultMessage: 'Share this Discover session',
}),
},
sharingData: {
@@ -119,7 +119,7 @@ export const getShareAppMenuItem = ({
title:
savedSearch.title ||
i18n.translate('discover.localMenu.fallbackReportTitle', {
- defaultMessage: 'Untitled discover search',
+ defaultMessage: 'Untitled Discover session',
}),
},
isDirty: !savedSearch.id || stateContainer.appState.hasChanged(),
diff --git a/src/plugins/discover/public/application/main/components/top_nav/esql_dataview_transition/esql_dataview_transition_modal.tsx b/src/plugins/discover/public/application/main/components/top_nav/esql_dataview_transition/esql_dataview_transition_modal.tsx
index 342d8c4f1684b..d52d25064d306 100644
--- a/src/plugins/discover/public/application/main/components/top_nav/esql_dataview_transition/esql_dataview_transition_modal.tsx
+++ b/src/plugins/discover/public/application/main/components/top_nav/esql_dataview_transition/esql_dataview_transition_modal.tsx
@@ -57,7 +57,7 @@ export default function ESQLToDataViewTransitionModal({
{i18n.translate('discover.esqlToDataviewTransitionModalBody', {
defaultMessage:
- 'Switching data views removes the current ES|QL query. Save this search to avoid losing work.',
+ 'Switching data views removes the current ES|QL query. Save this session to avoid losing work.',
})}
diff --git a/src/plugins/discover/public/application/main/components/top_nav/get_top_nav_badges.tsx b/src/plugins/discover/public/application/main/components/top_nav/get_top_nav_badges.tsx
index 13544f7f28dea..9d6a3c8a9912a 100644
--- a/src/plugins/discover/public/application/main/components/top_nav/get_top_nav_badges.tsx
+++ b/src/plugins/discover/public/application/main/components/top_nav/get_top_nav_badges.tsx
@@ -71,7 +71,7 @@ export const getTopNavBadges = ({
getManagedContentBadge(
i18n.translate('discover.topNav.managedContentLabel', {
defaultMessage:
- 'This saved search is managed by Elastic. Changes here must be saved to a new saved search.',
+ 'This Discover session is managed by Elastic. Changes here must be saved to a new Discover session.',
})
)
);
diff --git a/src/plugins/discover/public/application/main/components/top_nav/on_save_search.tsx b/src/plugins/discover/public/application/main/components/top_nav/on_save_search.tsx
index bd8073c01f27f..6b9913b2a0221 100644
--- a/src/plugins/discover/public/application/main/components/top_nav/on_save_search.tsx
+++ b/src/plugins/discover/public/application/main/components/top_nav/on_save_search.tsx
@@ -37,7 +37,7 @@ async function saveDataSource({
if (id) {
services.toastNotifications.addSuccess({
title: i18n.translate('discover.notifications.savedSearchTitle', {
- defaultMessage: `Search ''{savedSearchTitle}'' was saved`,
+ defaultMessage: `Discover session ''{savedSearchTitle}'' was saved`,
values: {
savedSearchTitle: savedSearch.title,
},
@@ -58,7 +58,7 @@ async function saveDataSource({
function onError(error: Error) {
services.toastNotifications.addDanger({
title: i18n.translate('discover.notifications.notSavedSearchTitle', {
- defaultMessage: `Search ''{savedSearchTitle}'' was not saved.`,
+ defaultMessage: `Discover session ''{savedSearchTitle}'' was not saved.`,
values: {
savedSearchTitle: savedSearch.title,
},
@@ -273,7 +273,7 @@ const SaveSearchObjectModal: React.FC<{
label={
}
/>
@@ -296,7 +296,7 @@ const SaveSearchObjectModal: React.FC<{
initialCopyOnSave={initialCopyOnSave}
description={description}
objectType={i18n.translate('discover.localMenu.saveSaveSearchObjectType', {
- defaultMessage: 'search',
+ defaultMessage: 'Discover session',
})}
showDescription={true}
options={options}
@@ -306,7 +306,7 @@ const SaveSearchObjectModal: React.FC<{
managed
? i18n.translate('discover.localMenu.mustCopyOnSave', {
defaultMessage:
- 'Elastic manages this saved search. Save any changes to a new saved search.',
+ 'Elastic manages this Discover session. Save any changes to a new Discover session.',
})
: undefined
}
diff --git a/src/plugins/discover/public/application/main/components/top_nav/open_search_panel.tsx b/src/plugins/discover/public/application/main/components/top_nav/open_search_panel.tsx
index 7633bea3612b0..bd4163a20d4d7 100644
--- a/src/plugins/discover/public/application/main/components/top_nav/open_search_panel.tsx
+++ b/src/plugins/discover/public/application/main/components/top_nav/open_search_panel.tsx
@@ -20,11 +20,10 @@ import {
EuiFlyoutBody,
EuiTitle,
} from '@elastic/eui';
+import { SavedSearchType, SavedSearchTypeDisplayName } from '@kbn/saved-search-plugin/common';
import { SavedObjectFinder } from '@kbn/saved-objects-finder-plugin/public';
import { useDiscoverServices } from '../../../../hooks/use_discover_services';
-const SEARCH_OBJECT_TYPE = 'search';
-
interface OpenSearchPanelProps {
onClose: () => void;
onOpenSavedSearch: (id: string) => void;
@@ -43,7 +42,7 @@ export function OpenSearchPanel(props: OpenSearchPanelProps) {
@@ -59,15 +58,15 @@ export function OpenSearchPanel(props: OpenSearchPanelProps) {
noItemsMessage={
}
savedObjectMetaData={[
{
- type: SEARCH_OBJECT_TYPE,
+ type: SavedSearchType,
getIconForSavedObject: () => 'discoverApp',
name: i18n.translate('discover.savedSearch.savedObjectName', {
- defaultMessage: 'Saved search',
+ defaultMessage: 'Discover session',
}),
},
]}
@@ -88,12 +87,12 @@ export function OpenSearchPanel(props: OpenSearchPanelProps) {
onClick={props.onClose}
data-test-subj="manageSearchesBtn"
href={addBasePath(
- `/app/management/kibana/objects?initialQuery=type:(${SEARCH_OBJECT_TYPE})`
+ `/app/management/kibana/objects?initialQuery=type:("${SavedSearchTypeDisplayName}")`
)}
>
diff --git a/src/plugins/discover/public/application/main/components/top_nav/use_top_nav_links.test.tsx b/src/plugins/discover/public/application/main/components/top_nav/use_top_nav_links.test.tsx
index a70b200a74346..3db9fb74f0eac 100644
--- a/src/plugins/discover/public/application/main/components/top_nav/use_top_nav_links.test.tsx
+++ b/src/plugins/discover/public/application/main/components/top_nav/use_top_nav_links.test.tsx
@@ -73,25 +73,25 @@ describe('useTopNavLinks', () => {
"testId": "openInspectorButton",
},
Object {
- "description": "New Search",
+ "description": "New session",
"iconOnly": true,
"iconType": "plus",
"id": "new",
- "label": "New",
+ "label": "New session",
"run": [Function],
"testId": "discoverNewButton",
},
Object {
- "description": "Open Saved Search",
+ "description": "Open session",
"iconOnly": true,
"iconType": "folderOpen",
"id": "open",
- "label": "Open",
+ "label": "Open session",
"run": [Function],
"testId": "discoverOpenButton",
},
Object {
- "description": "Share Search",
+ "description": "Share Discover session",
"iconOnly": true,
"iconType": "share",
"id": "share",
@@ -100,7 +100,7 @@ describe('useTopNavLinks', () => {
"testId": "shareTopNavButton",
},
Object {
- "description": "Save Search",
+ "description": "Save session",
"emphasize": true,
"iconType": "save",
"id": "save",
@@ -149,25 +149,25 @@ describe('useTopNavLinks', () => {
"testId": "openInspectorButton",
},
Object {
- "description": "New Search",
+ "description": "New session",
"iconOnly": true,
"iconType": "plus",
"id": "new",
- "label": "New",
+ "label": "New session",
"run": [Function],
"testId": "discoverNewButton",
},
Object {
- "description": "Open Saved Search",
+ "description": "Open session",
"iconOnly": true,
"iconType": "folderOpen",
"id": "open",
- "label": "Open",
+ "label": "Open session",
"run": [Function],
"testId": "discoverOpenButton",
},
Object {
- "description": "Share Search",
+ "description": "Share Discover session",
"iconOnly": true,
"iconType": "share",
"id": "share",
@@ -176,7 +176,7 @@ describe('useTopNavLinks', () => {
"testId": "shareTopNavButton",
},
Object {
- "description": "Save Search",
+ "description": "Save session",
"emphasize": true,
"iconType": "save",
"id": "save",
diff --git a/src/plugins/discover/public/application/main/components/top_nav/use_top_nav_links.tsx b/src/plugins/discover/public/application/main/components/top_nav/use_top_nav_links.tsx
index de9686711d104..608442da14088 100644
--- a/src/plugins/discover/public/application/main/components/top_nav/use_top_nav_links.tsx
+++ b/src/plugins/discover/public/application/main/components/top_nav/use_top_nav_links.tsx
@@ -192,7 +192,7 @@ export const useTopNavLinks = ({
defaultMessage: 'Save',
}),
description: i18n.translate('discover.localMenu.saveSearchDescription', {
- defaultMessage: 'Save Search',
+ defaultMessage: 'Save session',
}),
testId: 'discoverSaveButton',
iconType: 'save',
diff --git a/src/plugins/discover/public/components/saved_search_url_conflict_callout/saved_search_url_conflict_callout.ts b/src/plugins/discover/public/components/saved_search_url_conflict_callout/saved_search_url_conflict_callout.ts
index 3c42d0301e6dc..4a49a6cb2e073 100644
--- a/src/plugins/discover/public/components/saved_search_url_conflict_callout/saved_search_url_conflict_callout.ts
+++ b/src/plugins/discover/public/components/saved_search_url_conflict_callout/saved_search_url_conflict_callout.ts
@@ -29,7 +29,7 @@ export const SavedSearchURLConflictCallout = ({
if (otherObjectId) {
return spaces.ui.components.getLegacyUrlConflict({
objectNoun: i18n.translate('discover.savedSearchURLConflictCallout.objectNoun', {
- defaultMessage: '{savedSearch} search',
+ defaultMessage: `''{savedSearch}'' Discover session`,
values: {
savedSearch: savedSearch.title,
},
diff --git a/src/plugins/discover/public/context_awareness/README.md b/src/plugins/discover/public/context_awareness/README.md
index 31fa5ff9bfcda..ae42038b77aa3 100644
--- a/src/plugins/discover/public/context_awareness/README.md
+++ b/src/plugins/discover/public/context_awareness/README.md
@@ -54,7 +54,7 @@ The context awareness framework is driven by two main supporting services called
Each context level has a dedicated profile service, e.g. `RootProfileService`, which is responsible for accepting profile provider registrations and looping over each provider in order during context resolution to identify a matching profile. Each resolution call can result in only one matching profile, which is the first to return a match based on execution order.
-A single `ProfilesManager` is instantiated on Discover load, or one per saved search panel in a dashboard. The profiles manager is responsible for the following:
+A single `ProfilesManager` is instantiated on Discover load, or one per Discover session panel in a dashboard. The profiles manager is responsible for the following:
- Managing state associated with the current Discover context.
- Coordinating profile services and exposing resolution methods for each context level.
diff --git a/src/plugins/discover/public/embeddable/constants.ts b/src/plugins/discover/public/embeddable/constants.ts
index 313f2bbb99ed1..938caa233b435 100644
--- a/src/plugins/discover/public/embeddable/constants.ts
+++ b/src/plugins/discover/public/embeddable/constants.ts
@@ -17,9 +17,9 @@ export const SEARCH_EMBEDDABLE_CELL_ACTIONS_TRIGGER_ID =
export const SEARCH_EMBEDDABLE_CELL_ACTIONS_TRIGGER: Trigger = {
id: SEARCH_EMBEDDABLE_CELL_ACTIONS_TRIGGER_ID,
- title: 'Discover saved searches embeddable cell actions',
+ title: 'Discover session embeddable cell actions',
description:
- 'This trigger is used to replace the cell actions for Discover saved search embeddable grid.',
+ 'This trigger is used to replace the cell actions for Discover session embeddable grid.',
} as const;
export const DEFAULT_HEADER_ROW_HEIGHT_LINES = 3;
diff --git a/src/plugins/discover/public/embeddable/get_search_embeddable_factory.tsx b/src/plugins/discover/public/embeddable/get_search_embeddable_factory.tsx
index 1f97e2de66390..7c08cdc95e585 100644
--- a/src/plugins/discover/public/embeddable/get_search_embeddable_factory.tsx
+++ b/src/plugins/discover/public/embeddable/get_search_embeddable_factory.tsx
@@ -152,7 +152,7 @@ export const getSearchEmbeddableFactory = ({
},
getTypeDisplayName: () =>
i18n.translate('discover.embeddable.search.displayName', {
- defaultMessage: 'search',
+ defaultMessage: 'Discover session',
}),
canLinkToLibrary: async () => {
return (
diff --git a/src/plugins/discover/public/embeddable/initialize_edit_api.ts b/src/plugins/discover/public/embeddable/initialize_edit_api.ts
index a99cea0519626..acb489735d053 100644
--- a/src/plugins/discover/public/embeddable/initialize_edit_api.ts
+++ b/src/plugins/discover/public/embeddable/initialize_edit_api.ts
@@ -75,7 +75,7 @@ export function initializeEditApi<
return {
getTypeDisplayName: () =>
i18n.translate('discover.embeddable.search.displayName', {
- defaultMessage: 'search',
+ defaultMessage: 'Discover session',
}),
onEdit: async () => {
const appTarget = await getAppTarget(partialApi, discoverServices);
diff --git a/src/plugins/discover/public/hooks/saved_search_alias_match_redirect.test.ts b/src/plugins/discover/public/hooks/saved_search_alias_match_redirect.test.ts
index 4e4469188d0b8..81f0ce8e15372 100644
--- a/src/plugins/discover/public/hooks/saved_search_alias_match_redirect.test.ts
+++ b/src/plugins/discover/public/hooks/saved_search_alias_match_redirect.test.ts
@@ -44,7 +44,7 @@ describe('useSavedSearchAliasMatchRedirect', () => {
expect(spaces.ui.redirectLegacyUrl).toHaveBeenCalledWith({
path: '#/view/aliasTargetId?_g=foo',
aliasPurpose: 'savedObjectConversion',
- objectNoun: 'my-title search',
+ objectNoun: `'my-title' Discover session`,
});
});
diff --git a/src/plugins/discover/public/hooks/saved_search_alias_match_redirect.ts b/src/plugins/discover/public/hooks/saved_search_alias_match_redirect.ts
index c4234e40612b8..9bbfebe613c0b 100644
--- a/src/plugins/discover/public/hooks/saved_search_alias_match_redirect.ts
+++ b/src/plugins/discover/public/hooks/saved_search_alias_match_redirect.ts
@@ -35,7 +35,7 @@ export const useSavedSearchAliasMatchRedirect = ({
path: `${getSavedSearchUrl(aliasTargetId)}${history.location.search}`,
aliasPurpose,
objectNoun: i18n.translate('discover.savedSearchAliasMatchRedirect.objectNoun', {
- defaultMessage: '{savedSearch} search',
+ defaultMessage: `''{savedSearch}'' Discover session`,
values: {
savedSearch: savedSearch.title,
},
diff --git a/src/plugins/discover/public/plugin.tsx b/src/plugins/discover/public/plugin.tsx
index fb58e1def5083..3142a5784afb2 100644
--- a/src/plugins/discover/public/plugin.tsx
+++ b/src/plugins/discover/public/plugin.tsx
@@ -431,7 +431,7 @@ export class DiscoverPlugin
},
savedObjectType: SavedSearchType,
savedObjectName: i18n.translate('discover.savedSearch.savedObjectName', {
- defaultMessage: 'Saved search',
+ defaultMessage: 'Discover session',
}),
getIconForSavedObject: () => 'discoverApp',
});
diff --git a/src/plugins/discover/server/ui_settings.ts b/src/plugins/discover/server/ui_settings.ts
index 9d0905b27bfad..716478d8d0c1e 100644
--- a/src/plugins/discover/server/ui_settings.ts
+++ b/src/plugins/discover/server/ui_settings.ts
@@ -122,7 +122,7 @@ export const getUiSettings: (
description: i18n.translate('discover.advancedSettings.searchOnPageLoadText', {
defaultMessage:
'Controls whether a search is executed when Discover first loads. This setting does not ' +
- 'have an effect when loading a saved search.',
+ 'have an effect when loading a Discover session.',
}),
category: ['discover'],
schema: schema.boolean(),
@@ -133,7 +133,8 @@ export const getUiSettings: (
}),
value: false,
description: i18n.translate('discover.advancedSettings.docTableHideTimeColumnText', {
- defaultMessage: "Hide the 'Time' column in Discover and in all Saved Searches on Dashboards.",
+ defaultMessage:
+ "Hide the 'Time' column in Discover and in all Discover session panels on Dashboards.",
}),
category: ['discover'],
schema: schema.boolean(),
diff --git a/src/plugins/embeddable/public/index.ts b/src/plugins/embeddable/public/index.ts
index c3bb2a796b286..ad5857ac871a6 100644
--- a/src/plugins/embeddable/public/index.ts
+++ b/src/plugins/embeddable/public/index.ts
@@ -53,7 +53,6 @@ export {
withEmbeddableSubscription,
} from './lib';
export type {
- Adapters,
CellValueContext,
ChartActionContext,
EmbeddableContext,
@@ -93,9 +92,4 @@ export function plugin(initializerContext: PluginInitializerContext) {
return new EmbeddablePublicPlugin(initializerContext);
}
-export {
- embeddableInputToSubject,
- embeddableOutputToSubject,
-} from './lib/embeddables/compatibility/embeddable_compatibility_utils';
-
export { COMMON_EMBEDDABLE_GROUPING } from './lib/embeddables/common/constants';
diff --git a/src/plugins/embeddable/public/lib/embeddables/compatibility/embeddable_compatibility_utils.ts b/src/plugins/embeddable/public/lib/embeddables/compatibility/embeddable_compatibility_utils.ts
deleted file mode 100644
index 6512d28d6bcfd..0000000000000
--- a/src/plugins/embeddable/public/lib/embeddables/compatibility/embeddable_compatibility_utils.ts
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the "Elastic License
- * 2.0", the "GNU Affero General Public License v3.0 only", 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", the "GNU Affero General Public
- * License v3.0 only", or the "Server Side Public License, v 1".
- */
-
-import { ViewMode } from '@kbn/presentation-publishing';
-import deepEqual from 'fast-deep-equal';
-import { BehaviorSubject, distinctUntilKeyChanged, map, Subscription } from 'rxjs';
-import { EmbeddableInput, EmbeddableOutput, IEmbeddable } from '../..';
-import { ViewMode as LegacyViewMode } from '../../types';
-import { CommonLegacyEmbeddable } from './legacy_embeddable_to_api';
-
-export const embeddableInputToSubject = <
- ValueType extends unknown = unknown,
- LegacyInput extends EmbeddableInput = EmbeddableInput
->(
- subscription: Subscription,
- embeddable: IEmbeddable,
- key: keyof LegacyInput,
- useExplicitInput = false
-) => {
- const subject = new BehaviorSubject(
- embeddable.getExplicitInput()?.[key] as ValueType
- );
- subscription.add(
- embeddable
- .getInput$()
- .pipe(
- distinctUntilKeyChanged(key, (prev, current) => {
- return deepEqual(prev, current);
- })
- )
- .subscribe(() => subject.next(embeddable.getInput()?.[key] as ValueType))
- );
- return subject;
-};
-
-export const embeddableOutputToSubject = <
- ValueType extends unknown = unknown,
- LegacyOutput extends EmbeddableOutput = EmbeddableOutput
->(
- subscription: Subscription,
- embeddable: IEmbeddable,
- key: keyof LegacyOutput
-) => {
- const subject = new BehaviorSubject(
- embeddable.getOutput()[key] as ValueType
- );
- subscription.add(
- embeddable
- .getOutput$()
- .pipe(distinctUntilKeyChanged(key))
- .subscribe(() => subject.next(embeddable.getOutput()[key] as ValueType))
- );
- return subject;
-};
-
-export const mapLegacyViewModeToViewMode = (legacyViewMode?: LegacyViewMode): ViewMode => {
- if (!legacyViewMode) return 'view';
- switch (legacyViewMode) {
- case LegacyViewMode.VIEW: {
- return 'view';
- }
- case LegacyViewMode.EDIT: {
- return 'edit';
- }
- case LegacyViewMode.PREVIEW: {
- return 'preview';
- }
- case LegacyViewMode.PRINT: {
- return 'print';
- }
- default: {
- return 'view';
- }
- }
-};
-
-export const viewModeToSubject = (
- subscription: Subscription,
- embeddable: CommonLegacyEmbeddable
-) => {
- const subject = new BehaviorSubject(
- mapLegacyViewModeToViewMode(embeddable.getInput().viewMode)
- );
- subscription.add(
- embeddable
- .getInput$()
- .pipe(
- distinctUntilKeyChanged('viewMode'),
- map(({ viewMode }) => mapLegacyViewModeToViewMode(viewMode))
- )
- .subscribe((viewMode: ViewMode) => subject.next(viewMode))
- );
- return subject;
-};
diff --git a/src/plugins/embeddable/public/lib/embeddables/compatibility/legacy_embeddable_to_api.ts b/src/plugins/embeddable/public/lib/embeddables/compatibility/legacy_embeddable_to_api.ts
deleted file mode 100644
index 56fe9b82d1b2d..0000000000000
--- a/src/plugins/embeddable/public/lib/embeddables/compatibility/legacy_embeddable_to_api.ts
+++ /dev/null
@@ -1,302 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the "Elastic License
- * 2.0", the "GNU Affero General Public License v3.0 only", 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", the "GNU Affero General Public
- * License v3.0 only", or the "Server Side Public License, v 1".
- */
-
-import { DataView } from '@kbn/data-views-plugin/common';
-import {
- AggregateQuery,
- compareFilters,
- COMPARE_ALL_OPTIONS,
- Filter,
- Query,
- TimeRange,
-} from '@kbn/es-query';
-import type { ErrorLike } from '@kbn/expressions-plugin/common';
-import { i18n } from '@kbn/i18n';
-import { PhaseEvent, PhaseEventType } from '@kbn/presentation-publishing';
-import deepEqual from 'fast-deep-equal';
-import { isNil } from 'lodash';
-import {
- BehaviorSubject,
- map,
- Subscription,
- distinct,
- combineLatest,
- distinctUntilChanged,
-} from 'rxjs';
-import { embeddableStart } from '../../../kibana_services';
-import { isFilterableEmbeddable } from '../../filterable_embeddable';
-import {
- EmbeddableInput,
- EmbeddableOutput,
- IEmbeddable,
- LegacyEmbeddableAPI,
-} from '../i_embeddable';
-import {
- embeddableInputToSubject,
- embeddableOutputToSubject,
- viewModeToSubject,
-} from './embeddable_compatibility_utils';
-
-export type CommonLegacyInput = EmbeddableInput & { savedObjectId?: string; timeRange: TimeRange };
-export type CommonLegacyOutput = EmbeddableOutput & { indexPatterns: DataView[] };
-export type CommonLegacyEmbeddable = IEmbeddable;
-
-type VisualizeEmbeddable = IEmbeddable<{ id: string }, EmbeddableOutput & { visTypeName: string }>;
-function isVisualizeEmbeddable(
- embeddable: IEmbeddable | VisualizeEmbeddable
-): embeddable is VisualizeEmbeddable {
- return embeddable.type === 'visualization';
-}
-
-const getEventStatus = (output: EmbeddableOutput): PhaseEventType => {
- if (!isNil(output.error)) {
- return 'error';
- } else if (output.rendered === true) {
- return 'rendered';
- } else if (output.loading === false) {
- return 'loaded';
- } else {
- return 'loading';
- }
-};
-
-export const legacyEmbeddableToApi = (
- embeddable: CommonLegacyEmbeddable
-): { api: Omit; destroyAPI: () => void } => {
- const subscriptions = new Subscription();
-
- /**
- * Shortcuts for creating publishing subjects from the input and output subjects
- */
- const inputKeyToSubject = (
- key: keyof CommonLegacyInput,
- useExplicitInput?: boolean
- ) =>
- embeddableInputToSubject(
- subscriptions,
- embeddable,
- key,
- useExplicitInput
- );
- const outputKeyToSubject = (key: keyof CommonLegacyOutput) =>
- embeddableOutputToSubject(subscriptions, embeddable, key);
-
- /**
- * Support editing of legacy embeddables
- */
- const onEdit = () => {
- throw new Error('Edit legacy embeddable not supported');
- };
- const getTypeDisplayName = () =>
- embeddableStart.getEmbeddableFactory(embeddable.type)?.getDisplayName() ??
- i18n.translate('embeddableApi.compatibility.defaultTypeDisplayName', {
- defaultMessage: 'chart',
- });
- const isEditingEnabled = () => false;
-
- /**
- * Performance tracking
- */
- const phase$ = new BehaviorSubject(undefined);
-
- let loadingStartTime = 0;
- subscriptions.add(
- embeddable
- .getOutput$()
- .pipe(
- // Map loaded event properties
- map((output) => {
- if (output.loading === true) {
- loadingStartTime = performance.now();
- }
- return {
- id: embeddable.id,
- status: getEventStatus(output),
- error: output.error,
- };
- }),
- // Dedupe
- distinct((output) => loadingStartTime + output.id + output.status + !!output.error),
- // Map loaded event properties
- map((output): PhaseEvent => {
- return {
- ...output,
- timeToEvent: performance.now() - loadingStartTime,
- };
- })
- )
- .subscribe((statusOutput) => {
- phase$.next(statusOutput);
- })
- );
-
- /**
- * Publish state for Presentation panel
- */
- const viewMode = viewModeToSubject(subscriptions, embeddable);
- const dataLoading = outputKeyToSubject('loading');
-
- const setHidePanelTitle = (hidePanelTitle?: boolean) =>
- embeddable.updateInput({ hidePanelTitles: hidePanelTitle });
- const hidePanelTitle = inputKeyToSubject('hidePanelTitles');
-
- const setPanelTitle = (title?: string) => embeddable.updateInput({ title });
- const panelTitle = inputKeyToSubject('title');
-
- const setPanelDescription = (description?: string) => embeddable.updateInput({ description });
- const panelDescription = inputKeyToSubject('description');
-
- const defaultPanelTitle = outputKeyToSubject('defaultTitle');
- const defaultPanelDescription = outputKeyToSubject('defaultDescription');
- const disabledActionIds = inputKeyToSubject('disabledActions');
-
- function getSavedObjectId(input: { savedObjectId?: string }, output: { savedObjectId?: string }) {
- return output.savedObjectId ?? input.savedObjectId;
- }
- const savedObjectId = new BehaviorSubject(
- getSavedObjectId(embeddable.getInput(), embeddable.getOutput())
- );
- subscriptions.add(
- combineLatest([embeddable.getInput$(), embeddable.getOutput$()])
- .pipe(
- map(([input, output]) => {
- return getSavedObjectId(input, output);
- }),
- distinctUntilChanged()
- )
- .subscribe((nextSavedObjectId) => {
- savedObjectId.next(nextSavedObjectId);
- })
- );
-
- const blockingError = new BehaviorSubject(undefined);
- subscriptions.add(
- embeddable.getOutput$().subscribe({
- next: (output) => blockingError.next(output.error),
- error: (error) => blockingError.next(error),
- })
- );
-
- const uuid = embeddable.id;
- const disableTriggers = embeddable.getInput().disableTriggers;
-
- /**
- * We treat all legacy embeddable types as if they can support local unified search state, because there is no programmatic way
- * to tell when given a legacy embeddable what it's input could contain. All existing actions treat these as optional
- * so if the Embeddable is incapable of publishing unified search state (i.e. markdown) then it will just be ignored.
- */
- const timeRange$ = inputKeyToSubject('timeRange', true);
- const setTimeRange = (nextTimeRange?: TimeRange) =>
- embeddable.updateInput({ timeRange: nextTimeRange });
-
- const filters$: BehaviorSubject = new BehaviorSubject(
- undefined
- );
-
- const query$: BehaviorSubject = new BehaviorSubject<
- Query | AggregateQuery | undefined
- >(undefined);
- // if this embeddable is a legacy filterable embeddable, publish changes to those filters to the panelFilters subject.
- if (isFilterableEmbeddable(embeddable)) {
- embeddable.untilInitializationFinished().then(() => {
- filters$.next(embeddable.getFilters());
- query$.next(embeddable.getQuery());
-
- subscriptions.add(
- embeddable.getInput$().subscribe(() => {
- if (
- !compareFilters(
- embeddable.filters$.getValue() ?? [],
- embeddable.getFilters(),
- COMPARE_ALL_OPTIONS
- )
- ) {
- filters$.next(embeddable.getFilters());
- }
- if (!deepEqual(embeddable.query$.getValue() ?? [], embeddable.getQuery())) {
- query$.next(embeddable.getQuery());
- }
- })
- );
- });
- }
-
- const dataViews = outputKeyToSubject('indexPatterns');
- const isCompatibleWithUnifiedSearch = () => {
- const isInputControl =
- isVisualizeEmbeddable(embeddable) &&
- (embeddable as unknown as VisualizeEmbeddable).getOutput().visTypeName ===
- 'input_control_vis';
-
- const isMarkdown =
- isVisualizeEmbeddable(embeddable) &&
- (embeddable as VisualizeEmbeddable).getOutput().visTypeName === 'markdown';
-
- const isImage = embeddable.type === 'image';
- const isLinks = embeddable.type === 'links';
- return !isInputControl && !isMarkdown && !isImage && !isLinks;
- };
-
- const hasLockedHoverActions$ = new BehaviorSubject(false);
-
- return {
- api: {
- uuid,
- disableTriggers: disableTriggers ?? false,
- viewMode,
- dataLoading,
- blockingError,
-
- phase$,
-
- onEdit,
- isEditingEnabled,
- getTypeDisplayName,
-
- timeRange$,
- setTimeRange,
- filters$,
- query$,
- isCompatibleWithUnifiedSearch,
-
- dataViews,
- disabledActionIds,
- setDisabledActionIds: (ids) => disabledActionIds.next(ids),
-
- hasLockedHoverActions$,
- lockHoverActions: (lock: boolean) => hasLockedHoverActions$.next(lock),
-
- panelTitle,
- setPanelTitle,
- defaultPanelTitle,
-
- hidePanelTitle,
- setHidePanelTitle,
-
- setPanelDescription,
- panelDescription,
- defaultPanelDescription,
-
- canLinkToLibrary: async () => false,
- linkToLibrary: () => {
- throw new Error('Link to library not supported for legacy embeddable');
- },
-
- canUnlinkFromLibrary: async () => false,
- unlinkFromLibrary: () => {
- throw new Error('Unlink from library not supported for legacy embeddable');
- },
-
- savedObjectId,
- },
- destroyAPI: () => {
- subscriptions.unsubscribe();
- },
- };
-};
diff --git a/src/plugins/embeddable/public/lib/embeddables/embeddable.tsx b/src/plugins/embeddable/public/lib/embeddables/embeddable.tsx
index 40fb391400a18..3af13b3d998a3 100644
--- a/src/plugins/embeddable/public/lib/embeddables/embeddable.tsx
+++ b/src/plugins/embeddable/public/lib/embeddables/embeddable.tsx
@@ -13,19 +13,10 @@ import * as Rx from 'rxjs';
import { merge } from 'rxjs';
import { debounceTime, distinctUntilChanged, map, skip } from 'rxjs';
import { RenderCompleteDispatcher } from '@kbn/kibana-utils-plugin/public';
-import { Adapters } from '../types';
-import {
- EmbeddableError,
- EmbeddableOutput,
- IEmbeddable,
- LegacyEmbeddableAPI,
-} from './i_embeddable';
+import { Adapters } from '@kbn/inspector-plugin/public';
+import { EmbeddableError, EmbeddableOutput, IEmbeddable } from './i_embeddable';
import { EmbeddableInput, ViewMode } from '../../../common/types';
import { genericEmbeddableInputIsEqual, omitGenericEmbeddableInput } from './diff_embeddable_input';
-import {
- CommonLegacyEmbeddable,
- legacyEmbeddableToApi,
-} from './compatibility/legacy_embeddable_to_api';
function getPanelTitle(input: EmbeddableInput, output: EmbeddableOutput) {
if (input.hidePanelTitles) return '';
@@ -96,86 +87,12 @@ export abstract class Embeddable<
)
.subscribe((title) => this.renderComplete.setTitle(title));
- const { api, destroyAPI } = legacyEmbeddableToApi(this as unknown as CommonLegacyEmbeddable);
- this.destroyAPI = destroyAPI;
- ({
- uuid: this.uuid,
- disableTriggers: this.disableTriggers,
- onEdit: this.onEdit,
- viewMode: this.viewMode,
- dataViews: this.dataViews,
- panelTitle: this.panelTitle,
- query$: this.query$,
- dataLoading: this.dataLoading,
- filters$: this.filters$,
- blockingError: this.blockingError,
- phase$: this.phase$,
- setPanelTitle: this.setPanelTitle,
- linkToLibrary: this.linkToLibrary,
- hidePanelTitle: this.hidePanelTitle,
- timeRange$: this.timeRange$,
- isEditingEnabled: this.isEditingEnabled,
- panelDescription: this.panelDescription,
- defaultPanelDescription: this.defaultPanelDescription,
- canLinkToLibrary: this.canLinkToLibrary,
- disabledActionIds: this.disabledActionIds,
- setDisabledActionIds: this.setDisabledActionIds,
- unlinkFromLibrary: this.unlinkFromLibrary,
- setHidePanelTitle: this.setHidePanelTitle,
- defaultPanelTitle: this.defaultPanelTitle,
- setTimeRange: this.setTimeRange,
- getTypeDisplayName: this.getTypeDisplayName,
- setPanelDescription: this.setPanelDescription,
- canUnlinkFromLibrary: this.canUnlinkFromLibrary,
- isCompatibleWithUnifiedSearch: this.isCompatibleWithUnifiedSearch,
- savedObjectId: this.savedObjectId,
- hasLockedHoverActions$: this.hasLockedHoverActions$,
- lockHoverActions: this.lockHoverActions,
- } = api);
-
setTimeout(() => {
// after the constructor has finished, we initialize this embeddable if it isn't delayed
if (!this.deferEmbeddableLoad) this.initializationFinished.complete();
}, 0);
}
- /**
- * Assign compatibility API directly to the Embeddable instance.
- */
- private destroyAPI;
- public uuid: LegacyEmbeddableAPI['uuid'];
- public disableTriggers: LegacyEmbeddableAPI['disableTriggers'];
- public onEdit: LegacyEmbeddableAPI['onEdit'];
- public viewMode: LegacyEmbeddableAPI['viewMode'];
- public dataViews: LegacyEmbeddableAPI['dataViews'];
- public query$: LegacyEmbeddableAPI['query$'];
- public panelTitle: LegacyEmbeddableAPI['panelTitle'];
- public dataLoading: LegacyEmbeddableAPI['dataLoading'];
- public filters$: LegacyEmbeddableAPI['filters$'];
- public phase$: LegacyEmbeddableAPI['phase$'];
- public linkToLibrary: LegacyEmbeddableAPI['linkToLibrary'];
- public blockingError: LegacyEmbeddableAPI['blockingError'];
- public setPanelTitle: LegacyEmbeddableAPI['setPanelTitle'];
- public timeRange$: LegacyEmbeddableAPI['timeRange$'];
- public hidePanelTitle: LegacyEmbeddableAPI['hidePanelTitle'];
- public isEditingEnabled: LegacyEmbeddableAPI['isEditingEnabled'];
- public canLinkToLibrary: LegacyEmbeddableAPI['canLinkToLibrary'];
- public panelDescription: LegacyEmbeddableAPI['panelDescription'];
- public defaultPanelDescription: LegacyEmbeddableAPI['defaultPanelDescription'];
- public disabledActionIds: LegacyEmbeddableAPI['disabledActionIds'];
- public setDisabledActionIds: LegacyEmbeddableAPI['setDisabledActionIds'];
- public unlinkFromLibrary: LegacyEmbeddableAPI['unlinkFromLibrary'];
- public setTimeRange: LegacyEmbeddableAPI['setTimeRange'];
- public defaultPanelTitle: LegacyEmbeddableAPI['defaultPanelTitle'];
- public setHidePanelTitle: LegacyEmbeddableAPI['setHidePanelTitle'];
- public getTypeDisplayName: LegacyEmbeddableAPI['getTypeDisplayName'];
- public setPanelDescription: LegacyEmbeddableAPI['setPanelDescription'];
- public canUnlinkFromLibrary: LegacyEmbeddableAPI['canUnlinkFromLibrary'];
- public isCompatibleWithUnifiedSearch: LegacyEmbeddableAPI['isCompatibleWithUnifiedSearch'];
- public savedObjectId: LegacyEmbeddableAPI['savedObjectId'];
- public hasLockedHoverActions$: LegacyEmbeddableAPI['hasLockedHoverActions$'];
- public lockHoverActions: LegacyEmbeddableAPI['lockHoverActions'];
-
public async getEditHref(): Promise {
return this.getOutput().editUrl ?? undefined;
}
@@ -290,7 +207,6 @@ export abstract class Embeddable<
this.inputSubject.complete();
this.outputSubject.complete();
- this.destroyAPI();
return;
}
diff --git a/src/plugins/embeddable/public/lib/embeddables/error_embeddable.tsx b/src/plugins/embeddable/public/lib/embeddables/error_embeddable.tsx
index ffb5c197a4bcc..b508d5aeb2142 100644
--- a/src/plugins/embeddable/public/lib/embeddables/error_embeddable.tsx
+++ b/src/plugins/embeddable/public/lib/embeddables/error_embeddable.tsx
@@ -32,6 +32,14 @@ export class ErrorEmbeddable extends Embeddable;
+ return (
+
+ );
}
}
diff --git a/src/plugins/embeddable/public/lib/embeddables/i_embeddable.ts b/src/plugins/embeddable/public/lib/embeddables/i_embeddable.ts
index e1dbc3db22368..51a24527dd4aa 100644
--- a/src/plugins/embeddable/public/lib/embeddables/i_embeddable.ts
+++ b/src/plugins/embeddable/public/lib/embeddables/i_embeddable.ts
@@ -8,55 +8,13 @@
*/
import { ErrorLike } from '@kbn/expressions-plugin/common';
-import {
- HasEditCapabilities,
- HasType,
- HasDisableTriggers,
- PublishesBlockingError,
- PublishesDataLoading,
- PublishesDataViews,
- PublishesDisabledActionIds,
- PublishesUnifiedSearch,
- HasUniqueId,
- PublishesViewMode,
- PublishesWritablePanelDescription,
- PublishesWritablePanelTitle,
- PublishesPhaseEvents,
- PublishesSavedObjectId,
- HasLegacyLibraryTransforms,
- CanLockHoverActions,
-} from '@kbn/presentation-publishing';
+import { Adapters } from '@kbn/inspector-plugin/public';
import { Observable } from 'rxjs';
import { EmbeddableInput } from '../../../common/types';
-import { EmbeddableHasTimeRange } from '../filterable_embeddable/types';
-import { HasInspectorAdapters } from '../inspector';
-import { Adapters } from '../types';
export type EmbeddableError = ErrorLike;
export type { EmbeddableInput };
-/**
- * Types for compatibility between the legacy Embeddable system and the new system
- */
-export type LegacyEmbeddableAPI = HasType &
- HasUniqueId &
- HasDisableTriggers &
- PublishesPhaseEvents &
- PublishesViewMode &
- PublishesDataViews &
- HasEditCapabilities &
- PublishesDataLoading &
- HasInspectorAdapters &
- PublishesBlockingError &
- PublishesUnifiedSearch &
- PublishesDisabledActionIds &
- PublishesWritablePanelTitle &
- PublishesWritablePanelDescription &
- Partial &
- EmbeddableHasTimeRange &
- PublishesSavedObjectId &
- CanLockHoverActions;
-
export interface EmbeddableOutput {
// Whether the embeddable is actively loading.
loading?: boolean;
@@ -83,7 +41,7 @@ export interface IEmbeddable<
I extends EmbeddableInput = EmbeddableInput,
O extends EmbeddableOutput = EmbeddableOutput,
N = any
-> extends LegacyEmbeddableAPI {
+> {
/**
* The type of embeddable, this is what will be used to take a serialized
* embeddable and find the correct factory for which to create an instance of it.
diff --git a/src/plugins/embeddable/public/lib/types.ts b/src/plugins/embeddable/public/lib/types.ts
index 936867be43712..9a3f98891235d 100644
--- a/src/plugins/embeddable/public/lib/types.ts
+++ b/src/plugins/embeddable/public/lib/types.ts
@@ -7,8 +7,6 @@
* License v3.0 only", or the "Server Side Public License, v 1".
*/
-import { Adapters } from './inspector';
-
export interface Trigger {
id: string;
title?: string;
@@ -23,7 +21,6 @@ export interface PropertySpec {
value?: string;
}
export { ViewMode } from '../../common/types';
-export type { Adapters };
export interface CommonlyUsedRange {
from: string;
diff --git a/src/plugins/embeddable/tsconfig.json b/src/plugins/embeddable/tsconfig.json
index bf97096d1484b..249612d6d0e49 100644
--- a/src/plugins/embeddable/tsconfig.json
+++ b/src/plugins/embeddable/tsconfig.json
@@ -19,7 +19,6 @@
"@kbn/saved-objects-finder-plugin",
"@kbn/usage-collection-plugin",
"@kbn/content-management-plugin",
- "@kbn/data-views-plugin",
"@kbn/presentation-panel-plugin",
"@kbn/presentation-publishing",
"@kbn/presentation-containers",
diff --git a/src/plugins/home/public/services/feature_catalogue/feature_catalogue_registry.test.ts b/src/plugins/home/public/services/feature_catalogue/feature_catalogue_registry.test.ts
index ab264d6ff1d15..a9463ca5083fc 100644
--- a/src/plugins/home/public/services/feature_catalogue/feature_catalogue_registry.test.ts
+++ b/src/plugins/home/public/services/feature_catalogue/feature_catalogue_registry.test.ts
@@ -17,7 +17,7 @@ import {
const DASHBOARD_FEATURE: FeatureCatalogueEntry = {
id: 'dashboard',
title: 'Dashboard',
- description: 'Display and share a collection of visualizations and saved searches.',
+ description: 'Display and share a collection of visualizations and search results.',
icon: 'dashboardApp',
path: `/app/kibana#dashboard`,
showOnHomePage: true,
diff --git a/src/plugins/inspector/README.md b/src/plugins/inspector/README.md
index 99984b53065ad..f9eace25a25c3 100644
--- a/src/plugins/inspector/README.md
+++ b/src/plugins/inspector/README.md
@@ -14,7 +14,7 @@ a specific view is available depends on the used adapters.
## Inspector Adapters
Since the Inspector panel itself is not tied to a specific type of elements (visualizations,
-saved searches, etc.), everything you need to open the inspector is a collection
+Discover sessions, etc.), everything you need to open the inspector is a collection
of so called inspector adapters. A single adapter can be any type of JavaScript class.
Most likely an adapter offers some kind of logging capabilities for the element, that
diff --git a/src/plugins/saved_objects_management/public/management_section/object_view/components/__snapshots__/not_found_errors.test.tsx.snap b/src/plugins/saved_objects_management/public/management_section/object_view/components/__snapshots__/not_found_errors.test.tsx.snap
index 0c5045a1c8662..6e96c51be7be3 100644
--- a/src/plugins/saved_objects_management/public/management_section/object_view/components/__snapshots__/not_found_errors.test.tsx.snap
+++ b/src/plugins/saved_objects_management/public/management_section/object_view/components/__snapshots__/not_found_errors.test.tsx.snap
@@ -124,7 +124,7 @@ exports[`NotFoundErrors component renders correctly for search type 1`] = `
class="euiText emotion-euiText-s-euiTextColor-default"
>
- The saved search associated with this object no longer exists.
+ The Discover session associated with this object no longer exists.
If you know what this error means, you can use the
diff --git a/src/plugins/saved_objects_management/public/management_section/object_view/components/not_found_errors.test.tsx b/src/plugins/saved_objects_management/public/management_section/object_view/components/not_found_errors.test.tsx
index 41919c9172e56..d1d53c0807ba8 100644
--- a/src/plugins/saved_objects_management/public/management_section/object_view/components/not_found_errors.test.tsx
+++ b/src/plugins/saved_objects_management/public/management_section/object_view/components/not_found_errors.test.tsx
@@ -26,7 +26,7 @@ describe('NotFoundErrors component', () => {
const callOut = mounted.find('EuiCallOut');
expect(callOut.render()).toMatchSnapshot();
expect(mounted.text()).toMatchInlineSnapshot(
- `"There is a problem with this saved objectThe saved search associated with this object no longer exists.If you know what this error means, you can use the Saved objects APIs(external, opens in a new tab or window) to fix it — otherwise click the delete button above."`
+ `"There is a problem with this saved objectThe Discover session associated with this object no longer exists.If you know what this error means, you can use the Saved objects APIs(external, opens in a new tab or window) to fix it — otherwise click the delete button above."`
);
});
diff --git a/src/plugins/saved_objects_management/public/management_section/object_view/components/not_found_errors.tsx b/src/plugins/saved_objects_management/public/management_section/object_view/components/not_found_errors.tsx
index e89762bd2105f..ddee0bb9ee38a 100644
--- a/src/plugins/saved_objects_management/public/management_section/object_view/components/not_found_errors.tsx
+++ b/src/plugins/saved_objects_management/public/management_section/object_view/components/not_found_errors.tsx
@@ -32,7 +32,7 @@ export const NotFoundErrors = ({ type, docLinks }: NotFoundErrors) => {
return (
);
case 'index-pattern':
diff --git a/src/plugins/saved_search/README.md b/src/plugins/saved_search/README.md
index d2234f04494a1..cf2762c23d23c 100644
--- a/src/plugins/saved_search/README.md
+++ b/src/plugins/saved_search/README.md
@@ -1,3 +1,4 @@
# Saved search
Contains the saved search saved object definition and helpers.
+This object is created when a user saves their current session in the Discover app.
diff --git a/src/plugins/saved_search/common/constants.ts b/src/plugins/saved_search/common/constants.ts
index f30466d220967..cc5fdcebc6dae 100644
--- a/src/plugins/saved_search/common/constants.ts
+++ b/src/plugins/saved_search/common/constants.ts
@@ -8,6 +8,8 @@
*/
export const SavedSearchType = 'search';
+// While the legacy SO name has to stay "search" the display name can be customized.
+export const SavedSearchTypeDisplayName = 'discover session'; // visible on Saved Objects page
export const LATEST_VERSION = 1;
diff --git a/src/plugins/saved_search/common/index.ts b/src/plugins/saved_search/common/index.ts
index 1900a7e90d168..c29caaf9bcde7 100644
--- a/src/plugins/saved_search/common/index.ts
+++ b/src/plugins/saved_search/common/index.ts
@@ -25,6 +25,7 @@ export enum VIEW_MODE {
export {
SavedSearchType,
+ SavedSearchTypeDisplayName,
LATEST_VERSION,
MIN_SAVED_SEARCH_SAMPLE_SIZE,
MAX_SAVED_SEARCH_SAMPLE_SIZE,
diff --git a/src/plugins/saved_search/public/plugin.ts b/src/plugins/saved_search/public/plugin.ts
index 5570e0fc8d5ab..17132a1a7a415 100644
--- a/src/plugins/saved_search/public/plugin.ts
+++ b/src/plugins/saved_search/public/plugin.ts
@@ -102,7 +102,7 @@ export class SavedSearchPublicPlugin
latest: LATEST_VERSION,
},
name: i18n.translate('savedSearch.contentManagementType', {
- defaultMessage: 'Saved search',
+ defaultMessage: 'Discover session',
}),
});
diff --git a/src/plugins/saved_search/public/services/saved_searches/check_for_duplicate_title.ts b/src/plugins/saved_search/public/services/saved_searches/check_for_duplicate_title.ts
index 0efc945a867e1..6eb364afec12f 100644
--- a/src/plugins/saved_search/public/services/saved_searches/check_for_duplicate_title.ts
+++ b/src/plugins/saved_search/public/services/saved_searches/check_for_duplicate_title.ts
@@ -54,7 +54,7 @@ export const checkForDuplicateTitle = async ({
(await hasDuplicatedTitle(title, contentManagement))
) {
onTitleDuplicate();
- return Promise.reject(new Error(`Saved search title already exists: ${title}`));
+ return Promise.reject(new Error(`Saved Discover session title already exists: ${title}`));
}
return;
diff --git a/src/plugins/saved_search/server/saved_objects/search.ts b/src/plugins/saved_search/server/saved_objects/search.ts
index 153d95c6d7cb5..90dbd6fbe6206 100644
--- a/src/plugins/saved_search/server/saved_objects/search.ts
+++ b/src/plugins/saved_search/server/saved_objects/search.ts
@@ -11,6 +11,7 @@ import { ANALYTICS_SAVED_OBJECT_INDEX } from '@kbn/core-saved-objects-server';
import { SavedObjectsType } from '@kbn/core/server';
import { MigrateFunctionsObject } from '@kbn/kibana-utils-plugin/common';
import { getAllMigrations } from './search_migrations';
+import { SavedSearchTypeDisplayName } from '../../common/constants';
import {
SCHEMA_SEARCH_V8_8_0,
SCHEMA_SEARCH_MODEL_VERSION_1,
@@ -32,6 +33,7 @@ export function getSavedSearchObjectType(
management: {
icon: 'discoverApp',
defaultSearchField: 'title',
+ displayName: SavedSearchTypeDisplayName,
importableAndExportable: true,
getTitle(obj) {
return obj.attributes.title;
diff --git a/src/plugins/vis_default_editor/public/components/sidebar/sidebar_title.tsx b/src/plugins/vis_default_editor/public/components/sidebar/sidebar_title.tsx
index b83a3330cce2f..41199116837cb 100644
--- a/src/plugins/vis_default_editor/public/components/sidebar/sidebar_title.tsx
+++ b/src/plugins/vis_default_editor/public/components/sidebar/sidebar_title.tsx
@@ -63,7 +63,7 @@ export function LinkedSearch({ savedSearch, eventEmitter }: LinkedSearchProps) {
const linkButtonAriaLabel = i18n.translate(
'visDefaultEditor.sidebar.savedSearch.linkButtonAriaLabel',
{
- defaultMessage: 'Link to saved search. Click to learn more or break link.',
+ defaultMessage: 'Link to Discover session. Click to learn more or break link.',
}
);
@@ -82,7 +82,7 @@ export function LinkedSearch({ savedSearch, eventEmitter }: LinkedSearchProps) {